diff --git a/_maps/map_files/MetaStation/MetaStation.v41A.II.dmm b/_maps/map_files/MetaStation/MetaStation.v41A.II.dmm index 145248966bc..bd1fb3145b3 100644 --- a/_maps/map_files/MetaStation/MetaStation.v41A.II.dmm +++ b/_maps/map_files/MetaStation/MetaStation.v41A.II.dmm @@ -1242,7 +1242,7 @@ "axT" = (/obj/effect/spawner/window/reinforced,/obj/structure/cable/yellow,/obj/structure/cable/yellow{d2 = 4; icon_state = "0-4"},/turf/simulated/floor/plating,/area/maintenance/fore) "axU" = (/obj/effect/spawner/window/reinforced,/obj/structure/cable/yellow,/obj/structure/cable/yellow{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area/maintenance/fore) "axV" = (/obj/structure/cable/yellow{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 2; initialize_directions = 11},/turf/simulated/floor/plasteel,/area/crew_quarters/fitness{name = "\improper Recreation Area"}) -"axW" = (/obj/structure/grille,/obj/structure/window/reinforced/tinted{dir = 5; health = 120; icon_state = "twindow"; reinf = 0},/turf/simulated/floor/plating,/area/security/main) +"axW" = (/obj/structure/grille,/obj/structure/window/reinforced/tinted{dir = 5; max_integrity = 120; reinf = 0},/turf/simulated/floor/plating,/area/security/main) "axX" = (/obj/machinery/conveyor{dir = 4; id = "QMLoad"},/obj/machinery/door/poddoor{id_tag = "QMLoaddoor"; name = "supply dock loading door"},/turf/simulated/floor/plating,/area/quartermaster/storage) "axY" = (/obj/machinery/cryopod/right,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/crew_quarters/fitness{name = "\improper Recreation Area"}) "axZ" = (/obj/machinery/door/poddoor/shutters{dir = 2; id_tag = "supplybridge"},/turf/simulated/floor/plating{tag = "icon-warnplate (SOUTHEAST)"; icon_state = "warnplate"; dir = 6},/area/maintenance/fpmaint2{name = "Port Maintenance"}) @@ -1277,7 +1277,7 @@ "ayC" = (/obj/structure/stool/bed/chair{dir = 4},/turf/simulated/floor/plating,/area/hallway/secondary/entry{name = "Arrivals"}) "ayD" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/disposalpipe/segment,/turf/simulated/floor/plating,/area/maintenance/fpmaint2{name = "Port Maintenance"}) "ayE" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/turf/simulated/floor/plating,/area/maintenance/fpmaint2{name = "Port Maintenance"}) -"ayF" = (/obj/structure/grille,/obj/structure/window/reinforced/tinted{dir = 5; health = 120; icon_state = "twindow"; reinf = 0},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plating,/area/maintenance/fore) +"ayF" = (/obj/structure/grille,/obj/structure/window/reinforced/tinted{dir = 5; max_integrity = 120; reinf = 0},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plating,/area/maintenance/fore) "ayG" = (/obj/structure/disposalpipe/segment,/turf/simulated/floor/plating,/area/maintenance/fore) "ayH" = (/obj/structure/disposalpipe/junction{tag = "icon-pipe-j2 (NORTH)"; icon_state = "pipe-j2"; dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/maintenance/fore) "ayI" = (/obj/structure/rack{dir = 8; layer = 2.9},/obj/item/clothing/shoes/magboots,/obj/item/clothing/suit/space/hardsuit/engineering,/obj/item/clothing/mask/breath,/obj/item/clothing/head/helmet/space/hardsuit/engineering,/turf/simulated/floor/plasteel{dir = 8; icon_state = "warning"},/area/engine/engineering) @@ -1495,9 +1495,9 @@ "aCM" = (/obj/effect/spawner/window/reinforced,/obj/structure/cable/yellow{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area/engine/engineering) "aCN" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/quartermaster/sorting{name = "\improper Warehouse"}) "aCO" = (/turf/simulated/wall/r_wall,/area/security/detectives_office) -"aCP" = (/obj/structure/grille,/obj/structure/cable/yellow{d2 = 2; icon_state = "0-2"},/obj/structure/window/reinforced/tinted{dir = 5; health = 120; icon_state = "twindow"; reinf = 0},/turf/simulated/floor/plating,/area/security/detectives_office) +"aCP" = (/obj/structure/grille,/obj/structure/cable/yellow{d2 = 2; icon_state = "0-2"},/obj/structure/window/reinforced/tinted{dir = 5; max_integrity = 120; reinf = 0},/turf/simulated/floor/plating,/area/security/detectives_office) "aCQ" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/security{name = "Detective's Office"; req_access = null; req_access_txt = "4"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{req_access_txt = 1},/turf/simulated/floor/plasteel,/area/security/detectives_office) -"aCR" = (/obj/structure/grille,/obj/structure/cable/yellow{d2 = 2; icon_state = "0-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/window/reinforced/tinted{dir = 5; health = 120; icon_state = "twindow"; reinf = 0},/turf/simulated/floor/plating,/area/security/detectives_office) +"aCR" = (/obj/structure/grille,/obj/structure/cable/yellow{d2 = 2; icon_state = "0-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/window/reinforced/tinted{dir = 5; max_integrity = 120; reinf = 0},/turf/simulated/floor/plating,/area/security/detectives_office) "aCS" = (/turf/simulated/wall,/area/security/detectives_office) "aCT" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/light/small,/turf/simulated/floor/plasteel{icon_state = "whitered"},/area/security/brig) "aCU" = (/obj/machinery/light/small{dir = 1},/obj/machinery/atmospherics/unary/vent_scrubber{dir = 8; on = 1; scrub_N2O = 0; scrub_Toxins = 0},/obj/machinery/alarm{pixel_y = 26},/turf/simulated/floor/plasteel{icon_state = "freezerfloor"},/area/crew_quarters/locker/locker_toilet{name = "\improper Restrooms"}) @@ -2285,7 +2285,7 @@ "aRW" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/obj/structure/disposalpipe/junction{icon_state = "pipe-j1"; dir = 4},/turf/simulated/floor/plasteel{dir = 1; icon_state = "neutralcorner"},/area/crew_quarters/locker) "aRX" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 2; on = 1; scrub_N2O = 0; scrub_Toxins = 0},/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/turf/simulated/floor/plasteel,/area/crew_quarters/locker) "aRY" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/navbeacon{codes_txt = "patrol;next_patrol=14.5-Recreation"; location = "14.3-Lockers-Dorms"},/turf/simulated/floor/plasteel{dir = 4; icon_state = "neutralcorner"},/area/crew_quarters/locker) -"aRZ" = (/obj/structure/grille,/obj/structure/window/reinforced/tinted{dir = 5; health = 120; icon_state = "twindow"; reinf = 0},/turf/simulated/floor/plating,/area/hallway/secondary/construction{name = "\improper Garden"}) +"aRZ" = (/obj/structure/grille,/obj/structure/window/reinforced/tinted{dir = 5; max_integrity = 120; reinf = 0},/turf/simulated/floor/plating,/area/hallway/secondary/construction{name = "\improper Garden"}) "aSa" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel{icon_state = "neutral"; dir = 8},/area/hallway/secondary/construction{name = "\improper Garden"}) "aSb" = (/obj/machinery/hydroponics/soil,/turf/simulated/floor/plasteel{icon_state = "bot"},/area/hallway/secondary/construction{name = "\improper Garden"}) "aSc" = (/turf/simulated/floor/plasteel{icon_state = "neutral"; dir = 4},/area/hallway/secondary/construction{name = "\improper Garden"}) @@ -2419,7 +2419,7 @@ "aUA" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/crew_quarters/locker) "aUB" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4; initialize_directions = 11},/turf/simulated/floor/plasteel,/area/crew_quarters/locker) "aUC" = (/obj/structure/rack,/obj/item/storage/toolbox/mechanical{pixel_x = -2; pixel_y = -1},/obj/item/storage/toolbox/mechanical{pixel_x = 4; pixel_y = -4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/turf/simulated/floor/plasteel{dir = 2; icon_state = "neutralcorner"},/area/crew_quarters/locker) -"aUD" = (/obj/structure/grille,/obj/structure/window/reinforced/tinted{dir = 5; health = 120; icon_state = "twindow"; reinf = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating,/area/hallway/secondary/construction{name = "\improper Garden"}) +"aUD" = (/obj/structure/grille,/obj/structure/window/reinforced/tinted{dir = 5; max_integrity = 120; reinf = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating,/area/hallway/secondary/construction{name = "\improper Garden"}) "aUE" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/turf/simulated/floor/plasteel{icon_state = "neutral"; dir = 8},/area/hallway/secondary/construction{name = "\improper Garden"}) "aUF" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = "90Curve"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/turf/simulated/floor/plasteel{dir = 1; icon_state = "warning"},/area/engine/engineering) "aUG" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/grass,/area/hallway/secondary/construction{name = "\improper Garden"}) @@ -2470,7 +2470,7 @@ "aVz" = (/obj/item/radio/intercom{broadcasting = 1; frequency = 1447; name = "Private AI Channel"; pixel_y = -25},/obj/machinery/camera/motion{c_tag = "AI Upload Chamber - Starboard"; dir = 1; network = list("SS13","RD","AIUpload")},/turf/simulated/floor/bluegrid,/area/turret_protected/ai_upload) "aVA" = (/obj/structure/table,/obj/machinery/light{dir = 4},/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 32; pixel_y = 0},/obj/machinery/flasher{id = "AI"; pixel_x = 0; pixel_y = -24},/obj/item/aiModule/protectStation,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/turret_protected/ai_upload) "aVB" = (/obj/machinery/light{icon_state = "tube1"; dir = 8},/obj/structure/extinguisher_cabinet{pixel_x = -27; pixel_y = 0},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8; initialize_directions = 11},/turf/simulated/floor/plasteel{dir = 8; icon_state = "redcorner"},/area/hallway/primary/fore) -"aVC" = (/obj/structure/grille,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/window/reinforced/tinted{dir = 5; health = 120; icon_state = "twindow"; reinf = 0},/turf/simulated/floor/plating,/area/crew_quarters/courtroom) +"aVC" = (/obj/structure/grille,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/window/reinforced/tinted{dir = 5; max_integrity = 120; reinf = 0},/turf/simulated/floor/plating,/area/crew_quarters/courtroom) "aVD" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/obj/machinery/vending/cigarette,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/crew_quarters/courtroom) "aVE" = (/obj/structure/stool/bed/chair{dir = 1},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/crew_quarters/courtroom) "aVF" = (/obj/structure/stool/bed/chair{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply{req_access_txt = 1},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/crew_quarters/courtroom) @@ -2624,7 +2624,7 @@ "aYx" = (/obj/effect/spawner/window/reinforced,/turf/simulated/floor/plating,/area/hallway/primary/central) "aYy" = (/obj/machinery/door/airlock/highsecurity{icon_state = "door_closed"; locked = 0; name = "AI Upload"; req_access_txt = "16"},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/turret_protected/ai_upload) "aYz" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/yellow{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/plasteel,/area/hallway/primary/fore) -"aYA" = (/obj/structure/grille,/obj/structure/window/reinforced/tinted{dir = 5; health = 120; icon_state = "twindow"; reinf = 0},/turf/simulated/floor/plating,/area/crew_quarters/courtroom) +"aYA" = (/obj/structure/grille,/obj/structure/window/reinforced/tinted{dir = 5; max_integrity = 120; reinf = 0},/turf/simulated/floor/plating,/area/crew_quarters/courtroom) "aYB" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 1; on = 1; scrub_N2O = 0; scrub_Toxins = 0},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/crew_quarters/courtroom) "aYC" = (/obj/structure/extinguisher_cabinet{pixel_x = 5; pixel_y = -32},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/crew_quarters/courtroom) "aYD" = (/obj/item/radio/intercom{frequency = 1459; name = "Station Intercom (General)"; pixel_x = 0; pixel_y = -26},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/crew_quarters/courtroom) @@ -2661,8 +2661,8 @@ "aZi" = (/obj/structure/sign/pods,/turf/simulated/wall,/area/hallway/secondary/entry{name = "Arrivals"}) "aZj" = (/obj/machinery/door/airlock/external{name = "Escape Pod One"},/turf/simulated/floor/plating,/area/hallway/secondary/entry{name = "Arrivals"}) "aZk" = (/obj/machinery/door/airlock/engineering{name = "Arrivals Expansion Area"; req_access_txt = "32"},/turf/simulated/floor/plating,/area/hallway/secondary/entry{name = "Arrivals"}) -"aZl" = (/obj/structure/grille,/obj/structure/window/reinforced/tinted{dir = 5; health = 120; icon_state = "twindow"; reinf = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/hallway/secondary/entry{name = "Arrivals"}) -"aZm" = (/obj/structure/grille,/obj/structure/window/reinforced/tinted{dir = 5; health = 120; icon_state = "twindow"; reinf = 0},/turf/simulated/floor/plating,/area/hallway/secondary/entry{name = "Arrivals"}) +"aZl" = (/obj/structure/grille,/obj/structure/window/reinforced/tinted{dir = 5; max_integrity = 120; reinf = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/hallway/secondary/entry{name = "Arrivals"}) +"aZm" = (/obj/structure/grille,/obj/structure/window/reinforced/tinted{dir = 5; max_integrity = 120; reinf = 0},/turf/simulated/floor/plating,/area/hallway/secondary/entry{name = "Arrivals"}) "aZn" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/airlock/engineering{name = "Arrivals Expansion Area"; req_access_txt = "32"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/hallway/secondary/entry{name = "Arrivals"}) "aZo" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8; initialize_directions = 11},/obj/structure/cable/yellow{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/plasteel,/area/engine/break_room) "aZp" = (/turf/space,/turf/simulated/shuttle/wall{tag = "icon-swall_f5"; icon_state = "swall_f5"; dir = 2},/area/shuttle/supply) @@ -4461,7 +4461,7 @@ "bHO" = (/obj/structure/stool{pixel_y = 8},/turf/simulated/floor/plasteel{icon_state = "bar"},/area/crew_quarters/bar) "bHP" = (/obj/machinery/hologram/holopad,/turf/simulated/floor/plasteel{icon_state = "bar"},/area/crew_quarters/bar) "bHQ" = (/obj/structure/stool{pixel_y = 8},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/effect/landmark/start{name = "Civilian"},/turf/simulated/floor/plasteel{icon_state = "bar"},/area/crew_quarters/bar) -"bHR" = (/obj/structure/grille,/obj/structure/window/reinforced/tinted{dir = 5; health = 120; icon_state = "twindow"; reinf = 0},/turf/simulated/floor/plating,/area/crew_quarters/bar) +"bHR" = (/obj/structure/grille,/obj/structure/window/reinforced/tinted{dir = 5; max_integrity = 120; reinf = 0},/turf/simulated/floor/plating,/area/crew_quarters/bar) "bHS" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/wood,/area/crew_quarters/bar) "bHT" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 2},/turf/simulated/floor/wood,/area/crew_quarters/bar) "bHU" = (/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/carpet,/area/crew_quarters/theatre) @@ -6878,9 +6878,9 @@ "cCn" = (/obj/structure/stool/bed/chair{dir = 1},/obj/machinery/light,/turf/simulated/floor/plasteel{dir = 2; icon_state = "whiteblue"},/area/medical/reception) "cCo" = (/obj/structure/disposalpipe/trunk{dir = 1},/obj/machinery/disposal,/obj/machinery/firealarm{dir = 1; pixel_y = -24},/turf/simulated/floor/plasteel{dir = 2; icon_state = "whiteblue"},/area/medical/reception) "cCp" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/obj/item/radio/intercom{frequency = 1459; name = "Station Intercom (General)"; pixel_x = -29},/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/turf/simulated/floor/plasteel{dir = 8; icon_state = "bluecorner"},/area/hallway/primary/aft) -"cCq" = (/obj/structure/flora/ausbushes/fernybush,/obj/structure/flora/ausbushes/fullgrass,/obj/structure/flora/ausbushes/ppflowers,/obj/structure/flora/ausbushes/palebush,/obj/structure/window/reinforced{dir = 5; health = 1e+007},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/grass,/area/medical/surgeryobs) +"cCq" = (/obj/structure/flora/ausbushes/fernybush,/obj/structure/flora/ausbushes/fullgrass,/obj/structure/flora/ausbushes/ppflowers,/obj/structure/flora/ausbushes/palebush,/obj/structure/window/reinforced{dir = 5; max_integrity = 1e+007},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/grass,/area/medical/surgeryobs) "cCr" = (/obj/machinery/power/apc{dir = 8; name = "west bump"; pixel_x = -24; shock_proof = 0},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plasteel{dir = 4; icon_state = "warnwhite"; tag = "icon-warnwhite (NORTH)"},/area/medical/surgeryobs) -"cCs" = (/obj/structure/flora/ausbushes/fernybush,/obj/structure/flora/ausbushes/fullgrass,/obj/structure/flora/ausbushes/brflowers,/obj/structure/flora/ausbushes/sunnybush,/obj/structure/window/reinforced{dir = 5; health = 1e+007},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/grass,/area/medical/surgeryobs) +"cCs" = (/obj/structure/flora/ausbushes/fernybush,/obj/structure/flora/ausbushes/fullgrass,/obj/structure/flora/ausbushes/brflowers,/obj/structure/flora/ausbushes/sunnybush,/obj/structure/window/reinforced{dir = 5; max_integrity = 1e+007},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/grass,/area/medical/surgeryobs) "cCt" = (/obj/structure/cable/yellow{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/structure/cable/yellow{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = 0},/turf/simulated/wall,/area/medical/surgeryobs) "cCu" = (/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/surgeryobs) "cCv" = (/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/hologram/holopad,/turf/simulated/floor/plasteel{dir = 8; icon_state = "warnwhite"; tag = "icon-warnwhite (NORTH)"},/area/medical/surgeryobs) @@ -7788,7 +7788,7 @@ "cTO" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plasteel{icon_state = "warningcorner"; dir = 4},/area/hallway/secondary/exit{name = "\improper Departure Lounge"}) "cTP" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plasteel,/area/hallway/secondary/exit{name = "\improper Departure Lounge"}) "cTQ" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9},/turf/simulated/floor/plasteel,/area/hallway/secondary/exit{name = "\improper Departure Lounge"}) -"cTR" = (/obj/structure/flora/ausbushes/fernybush,/obj/structure/flora/ausbushes/fullgrass,/obj/structure/flora/ausbushes/ppflowers,/obj/structure/flora/ausbushes/palebush,/obj/structure/window/reinforced{dir = 5; health = 1e+007},/turf/simulated/floor/grass,/area/hallway/secondary/exit{name = "\improper Departure Lounge"}) +"cTR" = (/obj/structure/flora/ausbushes/fernybush,/obj/structure/flora/ausbushes/fullgrass,/obj/structure/flora/ausbushes/ppflowers,/obj/structure/flora/ausbushes/palebush,/obj/structure/window/reinforced{dir = 5; max_integrity = 1e+007},/turf/simulated/floor/grass,/area/hallway/secondary/exit{name = "\improper Departure Lounge"}) "cTS" = (/obj/effect/spawner/window/reinforced,/obj/structure/cable/yellow{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area/hallway/secondary/exit{name = "\improper Departure Lounge"}) "cTT" = (/obj/machinery/computer/secure_data,/obj/structure/cable/yellow{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/plasteel{icon_state = "red"; dir = 8},/area/hallway/secondary/exit{name = "\improper Departure Lounge"}) "cTU" = (/obj/structure/stool/bed/chair/office/dark{dir = 4},/turf/simulated/floor/plasteel,/area/hallway/secondary/exit{name = "\improper Departure Lounge"}) @@ -7810,7 +7810,7 @@ "cUk" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/disposalpipe/segment,/turf/simulated/floor/plasteel{icon_state = "grimy"},/area/chapel/office) "cUl" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plasteel{icon_state = "grimy"},/area/chapel/office) "cUm" = (/obj/machinery/light_switch{pixel_x = 28; pixel_y = 0},/obj/machinery/light/small{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/obj/machinery/camera{c_tag = "Chapel Office"; dir = 8; network = list("SS13")},/turf/simulated/floor/plasteel{icon_state = "grimy"},/area/chapel/office) -"cUn" = (/obj/structure/grille,/obj/structure/window/reinforced/tinted{dir = 5; health = 120; icon_state = "twindow"; reinf = 0},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/chapel/office) +"cUn" = (/obj/structure/grille,/obj/structure/window/reinforced/tinted{dir = 5; max_integrity = 120; reinf = 0},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/chapel/office) "cUo" = (/obj/machinery/atmospherics/pipe/manifold4w/hidden/supply,/turf/simulated/floor/plasteel{dir = 8; icon_state = "whiteblue"},/area/medical/medbay3) "cUp" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4; level = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/medbay3) "cUq" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8; initialize_directions = 11; level = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/medbay3) @@ -7854,7 +7854,7 @@ "cVc" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 4; on = 1; scrub_N2O = 0; scrub_Toxins = 0},/turf/simulated/floor/plasteel,/area/hallway/secondary/exit{name = "\improper Departure Lounge"}) "cVd" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 2; initialize_directions = 11},/turf/simulated/floor/plasteel,/area/hallway/secondary/exit{name = "\improper Departure Lounge"}) "cVe" = (/obj/structure/stool/bed/chair{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plasteel{dir = 4; icon_state = "warning"},/area/hallway/secondary/exit{name = "\improper Departure Lounge"}) -"cVf" = (/obj/structure/flora/ausbushes/fernybush,/obj/structure/flora/ausbushes/fullgrass,/obj/structure/flora/ausbushes/brflowers,/obj/structure/flora/ausbushes/sunnybush,/obj/structure/window/reinforced{dir = 5; health = 1e+007},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/grass,/area/hallway/secondary/exit{name = "\improper Departure Lounge"}) +"cVf" = (/obj/structure/flora/ausbushes/fernybush,/obj/structure/flora/ausbushes/fullgrass,/obj/structure/flora/ausbushes/brflowers,/obj/structure/flora/ausbushes/sunnybush,/obj/structure/window/reinforced{dir = 5; max_integrity = 1e+007},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/grass,/area/hallway/secondary/exit{name = "\improper Departure Lounge"}) "cVg" = (/obj/structure/stool/bed/chair{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plasteel{dir = 8; icon_state = "warning"},/area/hallway/secondary/exit{name = "\improper Departure Lounge"}) "cVh" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plasteel,/area/hallway/secondary/exit{name = "\improper Departure Lounge"}) "cVi" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4; initialize_directions = 11},/turf/simulated/floor/plasteel,/area/hallway/secondary/exit{name = "\improper Departure Lounge"}) diff --git a/_maps/map_files/RandomZLevels/moonoutpost19.dmm b/_maps/map_files/RandomZLevels/moonoutpost19.dmm index 369c9363825..46fef62f780 100644 --- a/_maps/map_files/RandomZLevels/moonoutpost19.dmm +++ b/_maps/map_files/RandomZLevels/moonoutpost19.dmm @@ -2,13 +2,13 @@ "ab" = (/turf/simulated/mineral/random/labormineral,/area/awaycontent/a3{always_unpowered = 1; ambientsounds = list('sound/ambience/ambimine.ogg'); has_gravity = 1; name = "Khonsu 19"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0}) "ac" = (/obj/structure/alien/weeds,/obj/structure/alien/resin/wall,/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a5{always_unpowered = 1; has_gravity = 1; name = "The Hive"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0}) "ad" = (/obj/structure/alien/weeds{icon_state = "weeds1"},/obj/structure/alien/resin/wall,/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a5{always_unpowered = 1; has_gravity = 1; name = "The Hive"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0}) -"ae" = (/obj/structure/alien/weeds,/obj/structure/alien/weeds{desc = "A large mottled egg."; health = 100; icon_state = "egg_hatched"; name = "egg"},/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a5{always_unpowered = 1; has_gravity = 1; name = "The Hive"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0}) +"ae" = (/obj/structure/alien/weeds,/obj/structure/alien/weeds{desc = "A large mottled egg."; icon_state = "egg_hatched"; name = "egg"},/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a5{always_unpowered = 1; has_gravity = 1; name = "The Hive"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0}) "af" = (/obj/structure/alien/weeds{icon_state = "weeds2"},/obj/structure/alien/resin/wall,/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a5{always_unpowered = 1; has_gravity = 1; name = "The Hive"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0}) -"ag" = (/obj/structure/alien/weeds{icon_state = "weeds1"},/obj/structure/alien/weeds{desc = "A large mottled egg."; health = 100; icon_state = "egg_hatched"; name = "egg"},/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a5{always_unpowered = 1; has_gravity = 1; name = "The Hive"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0}) +"ag" = (/obj/structure/alien/weeds{icon_state = "weeds1"},/obj/structure/alien/weeds{desc = "A large mottled egg."; icon_state = "egg_hatched"; name = "egg"},/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a5{always_unpowered = 1; has_gravity = 1; name = "The Hive"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0}) "ah" = (/obj/structure/alien/weeds,/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a5{always_unpowered = 1; has_gravity = 1; name = "The Hive"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0}) "ai" = (/obj/structure/alien/weeds{icon_state = "weeds2"},/mob/living/simple_animal/hostile/alien,/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a5{always_unpowered = 1; has_gravity = 1; name = "The Hive"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0}) "aj" = (/obj/structure/alien/weeds,/obj/structure/stool/bed/nest,/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a5{always_unpowered = 1; has_gravity = 1; name = "The Hive"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0}) -"ak" = (/obj/structure/alien/weeds{icon_state = "weeds2"},/obj/structure/alien/weeds{desc = "A large mottled egg."; health = 100; icon_state = "egg_hatched"; name = "egg"},/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a5{always_unpowered = 1; has_gravity = 1; name = "The Hive"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0}) +"ak" = (/obj/structure/alien/weeds{icon_state = "weeds2"},/obj/structure/alien/weeds{desc = "A large mottled egg."; icon_state = "egg_hatched"; name = "egg"},/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a5{always_unpowered = 1; has_gravity = 1; name = "The Hive"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0}) "al" = (/obj/structure/alien/weeds{icon_state = "weeds1"},/obj/structure/stool/bed/nest,/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a5{always_unpowered = 1; has_gravity = 1; name = "The Hive"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0}) "am" = (/obj/structure/alien/weeds/node,/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a5{always_unpowered = 1; has_gravity = 1; name = "The Hive"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0}) "an" = (/obj/structure/alien/weeds{icon_state = "weeds2"},/obj/structure/stool/bed/nest,/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a5{always_unpowered = 1; has_gravity = 1; name = "The Hive"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0}) @@ -32,9 +32,9 @@ "aF" = (/obj/machinery/gateway{dir = 1},/turf/simulated/floor/plasteel{dir = 8; icon_state = "vault"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"}) "aG" = (/obj/machinery/gateway{dir = 9},/turf/simulated/floor/plasteel{dir = 1; icon_state = "vault"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"}) "aH" = (/obj/machinery/gateway{dir = 5},/turf/simulated/floor/plasteel{dir = 4; icon_state = "vault"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"}) -"aI" = (/obj/structure/alien/weeds{icon_state = "weeds1"},/obj/structure/alien/weeds{desc = "A large mottled egg."; health = 100; icon_state = "egg_hatched"; name = "egg"},/obj/effect/decal/cleanable/blood/gibs{color = "red"; icon_state = "gib1_flesh"},/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a5{always_unpowered = 1; has_gravity = 1; name = "The Hive"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0}) +"aI" = (/obj/structure/alien/weeds{icon_state = "weeds1"},/obj/structure/alien/weeds{desc = "A large mottled egg."; icon_state = "egg_hatched"; name = "egg"},/obj/effect/decal/cleanable/blood/gibs{color = "red"; icon_state = "gib1_flesh"},/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a5{always_unpowered = 1; has_gravity = 1; name = "The Hive"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0}) "aJ" = (/obj/structure/alien/weeds{icon_state = "weeds2"},/obj/effect/decal/cleanable/blood/gibs{color = "red"; icon_state = "gib2_flesh"},/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a5{always_unpowered = 1; has_gravity = 1; name = "The Hive"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0}) -"aK" = (/obj/structure/alien/weeds,/obj/structure/alien/weeds{desc = "A large mottled egg."; health = 100; icon_state = "egg_hatched"; name = "egg"},/obj/effect/decal/cleanable/blood{color = "red"},/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a5{always_unpowered = 1; has_gravity = 1; name = "The Hive"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0}) +"aK" = (/obj/structure/alien/weeds,/obj/structure/alien/weeds{desc = "A large mottled egg."; icon_state = "egg_hatched"; name = "egg"},/obj/effect/decal/cleanable/blood{color = "red"},/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a5{always_unpowered = 1; has_gravity = 1; name = "The Hive"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0}) "aL" = (/obj/structure/alien/weeds,/mob/living/simple_animal/hostile/alien/drone{plants_off = 1},/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a5{always_unpowered = 1; has_gravity = 1; name = "The Hive"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0}) "aM" = (/obj/machinery/light{dir = 8},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"}) "aN" = (/obj/machinery/gateway/centeraway{calibrated = 0},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"}) @@ -220,7 +220,7 @@ "el" = (/obj/structure/alien/weeds{icon_state = "weeds2"},/obj/structure/stool/bed/nest,/obj/effect/decal/cleanable/blood/tracks{color = "red"; desc = "Your instincts say you shouldn't be following these."; dir = 9; icon = 'icons/effects/blood.dmi'; icon_state = "tracks"},/turf/simulated/floor/engine,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"}) "em" = (/obj/structure/alien/weeds{icon_state = "weeds1"},/obj/effect/decal/cleanable/blood/tracks{color = "red"; desc = "Your instincts say you shouldn't be following these."; dir = 4; icon = 'icons/effects/blood.dmi'; icon_state = "tracks"},/turf/simulated/floor/engine,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"}) "en" = (/obj/structure/alien/weeds,/turf/simulated/floor/engine,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"}) -"eo" = (/obj/machinery/light{active_power_usage = 0; dir = 1; icon_state = "tube-broken"; status = 2},/obj/structure/alien/weeds,/obj/structure/alien/weeds{desc = "A large mottled egg."; health = 100; icon_state = "egg_hatched"; name = "egg"},/obj/machinery/camera{c_tag = "Xenobiology Containment North"; network = list("MO19X")},/turf/simulated/floor/engine,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"}) +"eo" = (/obj/machinery/light{active_power_usage = 0; dir = 1; icon_state = "tube-broken"; status = 2},/obj/structure/alien/weeds,/obj/structure/alien/weeds{desc = "A large mottled egg."; icon_state = "egg_hatched"; name = "egg"},/obj/machinery/camera{c_tag = "Xenobiology Containment North"; network = list("MO19X")},/turf/simulated/floor/engine,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"}) "ep" = (/obj/machinery/sparker{desc = "A wall-mounted ignition device. This one has been applied with an acid-proof coating."; id = "awayxenobio"; name = "Acid-Proof mounted igniter"; pixel_x = 0; pixel_y = 25; unacidable = 1},/obj/structure/alien/weeds{icon_state = "weeds1"},/obj/structure/alien/resin/wall,/turf/simulated/floor/engine,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"}) "eq" = (/obj/structure/alien/weeds,/obj/structure/alien/resin/wall,/turf/simulated/floor/engine,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"}) "er" = (/obj/structure/alien/weeds,/obj/structure/stool/bed/nest,/obj/item/clothing/mask/facehugger{icon_state = "facehugger_impregnated"; item_state = "facehugger_impregnated"; stat = 2},/turf/simulated/floor/engine,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"}) @@ -240,7 +240,7 @@ "eF" = (/obj/structure/alien/weeds{icon_state = "weeds2"},/obj/structure/alien/resin/wall,/turf/simulated/floor/engine,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"}) "eG" = (/obj/structure/alien/weeds,/obj/structure/stool/bed/nest,/turf/simulated/floor/engine,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"}) "eH" = (/obj/structure/alien/weeds{icon_state = "weeds2"},/obj/effect/decal/cleanable/blood/tracks{color = "red"; desc = "Your instincts say you shouldn't be following these."; icon = 'icons/effects/blood.dmi'; icon_state = "tracks"},/turf/simulated/floor/engine,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"}) -"eI" = (/obj/structure/alien/weeds,/obj/structure/alien/weeds{desc = "A large mottled egg."; health = 100; icon_state = "egg_hatched"; name = "egg"},/turf/simulated/floor/engine,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"}) +"eI" = (/obj/structure/alien/weeds,/obj/structure/alien/weeds{desc = "A large mottled egg."; icon_state = "egg_hatched"; name = "egg"},/turf/simulated/floor/engine,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"}) "eJ" = (/turf/simulated/wall,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"}) "eK" = (/turf/simulated/wall/rust,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"}) "eL" = (/turf/simulated/floor/plasteel{dir = 2; icon_state = "whitehall"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"}) @@ -248,7 +248,7 @@ "eN" = (/obj/machinery/light/small{active_power_usage = 0; dir = 8; icon_state = "bulb-broken"; status = 2},/obj/machinery/camera{c_tag = "Xenobiology"; dir = 4; network = list("MO19","MO19R")},/turf/simulated/floor/plasteel{dir = 6; icon_state = "whitehall"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"}) "eO" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/machinery/atmospherics/pipe/simple/visible,/obj/structure/stool/bed/chair/office/light{dir = 4},/turf/simulated/floor/plasteel{icon_state = "white"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"}) "eP" = (/obj/structure/table/reinforced,/obj/machinery/door_control{id = "Awaylab"; name = "Containment Chamber Blast Doors"; pixel_x = 4; pixel_y = -2; req_access_txt = "201"},/obj/machinery/ignition_switch{id = "awayxenobio"; pixel_x = 4; pixel_y = 8},/obj/structure/alien/weeds{icon_state = "weeds2"},/turf/simulated/floor/plasteel{dir = 8; icon_state = "warning"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"}) -"eQ" = (/obj/structure/alien/weeds{icon_state = "weeds1"},/obj/structure/alien/weeds{desc = "A large mottled egg."; health = 100; icon_state = "egg_hatched"; name = "egg"},/turf/simulated/floor/engine,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"}) +"eQ" = (/obj/structure/alien/weeds{icon_state = "weeds1"},/obj/structure/alien/weeds{desc = "A large mottled egg."; icon_state = "egg_hatched"; name = "egg"},/turf/simulated/floor/engine,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"}) "eR" = (/obj/structure/alien/weeds{icon_state = "weeds1"},/obj/effect/decal/cleanable/blood{color = "red"},/turf/simulated/floor/engine,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"}) "eS" = (/obj/structure/alien/weeds{icon_state = "weeds1"},/turf/simulated/floor/engine,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"}) "eT" = (/turf/simulated/wall,/area/awaycontent/a7) @@ -273,7 +273,7 @@ "fm" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/machinery/atmospherics/pipe/simple/visible,/turf/simulated/floor/plasteel{icon_state = "white"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"}) "fn" = (/obj/structure/closet/l3closet/scientist,/obj/structure/window/reinforced,/obj/structure/alien/weeds{icon_state = "weeds1"},/turf/simulated/floor/plasteel{dir = 8; icon_state = "warning"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"}) "fo" = (/obj/structure/cable,/obj/structure/cable{icon_state = "0-2"; d2 = 2},/obj/machinery/door/poddoor/preopen{desc = "A heavy duty blast door that opens mechanically. This one has been applied with an acid-proof coating."; id_tag = "Awaylab"; name = "Acid-Proof containment chamber blast door"; unacidable = 1},/obj/structure/grille,/obj/structure/window/full/reinforced,/turf/simulated/floor/plating,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"}) -"fp" = (/obj/structure/alien/weeds{icon_state = "weeds2"},/obj/structure/alien/weeds{desc = "A large mottled egg."; health = 100; icon_state = "egg_hatched"; name = "egg"},/turf/simulated/floor/engine,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"}) +"fp" = (/obj/structure/alien/weeds{icon_state = "weeds2"},/obj/structure/alien/weeds{desc = "A large mottled egg."; icon_state = "egg_hatched"; name = "egg"},/turf/simulated/floor/engine,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"}) "fq" = (/obj/structure/alien/weeds{icon_state = "weeds1"},/obj/structure/stool/bed/nest,/obj/item/clothing/mask/facehugger{icon_state = "facehugger_impregnated"; item_state = "facehugger_impregnated"; stat = 2},/turf/simulated/floor/engine,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"}) "fr" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plating,/area/awaycontent/a7) "fs" = (/obj/effect/decal/cleanable/blood/tracks{desc = "Your instincts say you shouldn't be following these."; dir = 8; icon_state = "ltrails_1"},/turf/simulated/floor/plating,/area/awaycontent/a7) diff --git a/_maps/map_files/RandomZLevels/terrorspiders.dmm b/_maps/map_files/RandomZLevels/terrorspiders.dmm index 0b6817624ba..d21991c7ca5 100644 --- a/_maps/map_files/RandomZLevels/terrorspiders.dmm +++ b/_maps/map_files/RandomZLevels/terrorspiders.dmm @@ -5,7 +5,7 @@ "ae" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/awaymission/UO71/queen) "af" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8; initialize_directions = 7; tag = "icon-manifold-b-f (WEST)"},/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/awaymission/UO71/queen) "ag" = (/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/awaymission/UO71/queen) -"ah" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 8; external_pressure_bound = 0; frequency = 1441; icon_state = "weld"; id_tag = "UO71_waste_out"; initialize_directions = 1; internal_pressure_bound = 4000; on = 1; pressure_checks = 2; pump_direction = 0; welded = 1},/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/awaymission/UO71/queen) +"ah" = (/obj/machinery/alarm/monitor{frequency = 1439; locked = 0; pixel_y = 23; req_access = null},/obj/machinery/camera{c_tag = "Gateway Ready Room"; dir = 2; network = list("UO71")},/obj/structure/table,/obj/machinery/computer/id_upgrader{light_color = "#00ffff"; light_power = 4; light_range = 2},/turf/simulated/floor/plasteel{dir = 8; icon_state = "floorgrime"; tag = "icon-floorgrime (WEST)"},/area/awaymission/UO71/gateway) "ai" = (/obj/structure/spider/cocoon{icon_state = "cocoon_large1"},/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/awaymission/UO71/queen) "aj" = (/turf/simulated/floor/plasteel{dir = 8; icon_state = "floorgrime"; tag = "icon-floorgrime (WEST)"},/area/awaymission/UO71/plaza) "ak" = (/obj/structure/closet/emcloset,/obj/item/clothing/mask/breath,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/awaymission/UO71/plaza) @@ -465,17 +465,16 @@ "iW" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk{dir = 4},/obj/structure/sign/deathsposal{desc = "A warning sign which reads 'DISPOSAL: LEADS TO EXTERIOR'"; name = "\improper DISPOSAL: LEADS TO EXTERIOR"; pixel_x = 0; pixel_y = -32},/turf/simulated/floor/plasteel{dir = 5; icon_state = "cafeteria"; tag = "icon-cafeteria (NORTHEAST)"},/area/awaymission/UO71/centralhall) "iX" = (/obj/structure/closet/secure_closet{icon_state = "secure"; locked = 0; name = "kitchen Cabinet"; req_access_txt = "271"},/obj/item/reagent_containers/food/condiment/flour,/obj/item/reagent_containers/food/condiment/flour,/obj/item/reagent_containers/food/condiment/sugar,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel{dir = 5; icon_state = "cafeteria"; tag = "icon-cafeteria (NORTHEAST)"},/area/awaymission/UO71/centralhall) "iY" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable{icon_state = "0-2"; d2 = 2},/turf/simulated/floor/plating,/area/awaymission/UO71/centralhall) -"iZ" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 4; icon_state = "weld"; on = 1; welded = 1},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel,/area/awaymission/UO71/gateway) +"iZ" = (/obj/effect/decal/cleanable/blood/gibs{color = "red"; icon_state = "gib2_flesh"},/turf/simulated/floor/plasteel,/area/awaymission/UO71/gateway) "ja" = (/obj/machinery/alarm/monitor{dir = 4; frequency = 1439; locked = 0; pixel_x = -23; pixel_y = 0; req_access = null},/obj/machinery/camera{c_tag = "Gateway Chamber"; dir = 4; network = list("UO71")},/turf/simulated/floor/plasteel{dir = 8; icon_state = "floorgrime"; tag = "icon-floorgrime (WEST)"},/area/awaymission/UO71/gateway) -"jb" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/effect/decal/cleanable/blood/gibs{color = "red"; icon_state = "gib2_flesh"},/turf/simulated/floor/plasteel,/area/awaymission/UO71/gateway) -"jc" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plasteel,/area/awaymission/UO71/gateway) -"jd" = (/obj/structure/grille,/obj/structure/window/full/reinforced,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating,/area/awaymission/UO71/gateway) -"je" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/stool,/turf/simulated/floor/plasteel,/area/awaymission/UO71/gateway) -"jf" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/awaymission/UO71/gateway) +"jb" = (/obj/structure/stool,/turf/simulated/floor/plasteel,/area/awaymission/UO71/gateway) +"jc" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel{icon_state = "white"},/area/awaymission/UO71/gateway) +"jd" = (/obj/machinery/door/poddoor{id_tag = "UO71_Start"; name = "UO71 Sealed Facility"},/obj/machinery/door/airlock/research{name = "Gateway Observation"; req_access_txt = "271"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/awaymission/UO71/gateway) +"je" = (/obj/structure/stool/bed/chair/comfy/black{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8; initialize_directions = 7; tag = "icon-manifold-b-f (WEST)"},/turf/simulated/floor/plasteel{dir = 8; icon_state = "neutral"},/area/awaymission/UO71/centralhall) +"jf" = (/obj/effect/decal/cleanable/dirt,/obj/machinery/atmospherics/unary/vent_pump{dir = 8; on = 1},/turf/simulated/floor/plasteel{dir = 10; icon_state = "neutral"},/area/awaymission/UO71/centralhall) "jg" = (/obj/structure/sign/biohazard,/turf/simulated/wall/r_wall,/area/awaymission/UO71/mother) -"jh" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4; initialize_directions = 11; level = 1},/turf/simulated/floor/plasteel{icon_state = "white"},/area/awaymission/UO71/gateway) +"jh" = (/obj/structure/stool/bed/chair/comfy/black{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8; initialize_directions = 7; tag = "icon-manifold-b-f (WEST)"},/turf/simulated/floor/plasteel{dir = 8; icon_state = "neutralcorner"},/area/awaymission/UO71/centralhall) "ji" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/wall,/area/awaymission/UO71/science) -"jj" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/door/poddoor{id_tag = "UO71_Start"; name = "UO71 Sealed Facility"},/obj/machinery/door/airlock/research{name = "Gateway Observation"; req_access_txt = "271"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/awaymission/UO71/gateway) "jk" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel{icon_state = "white"},/area/awaymission/UO71/gateway) "jl" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/mineral/random/labormineral,/area/awaymission/UO71/outside) "jm" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 2},/turf/simulated/shuttle/wall{dir = 4; icon_state = "wall3"},/area/awaymission/UO71/outside) @@ -596,7 +595,6 @@ "lx" = (/obj/structure/table,/obj/item/storage/toolbox/mechanical{pixel_x = -2; pixel_y = -1},/obj/item/multitool,/obj/structure/sign/nosmoking_2{pixel_x = -32},/obj/item/storage/toolbox/mechanical{pixel_x = -2; pixel_y = -1},/turf/simulated/floor/plasteel{dir = 4; icon_state = "warndark"; tag = "icon-warndark (EAST)"},/area/awaymission/UO71/gateway) "ly" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plasteel,/area/awaymission/UO71/gateway) "lz" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/turf/simulated/floor/plasteel,/area/awaymission/UO71/gateway) -"lA" = (/obj/machinery/alarm/monitor{frequency = 1439; locked = 0; pixel_y = 23; req_access = null},/obj/machinery/camera{c_tag = "Gateway Ready Room"; dir = 2; network = list("UO71")},/obj/structure/table,/obj/machinery/computer/id_upgrader,/turf/simulated/floor/plasteel{dir = 8; icon_state = "floorgrime"; tag = "icon-floorgrime (WEST)"},/area/awaymission/UO71/gateway) "lB" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/turf/simulated/floor/plasteel,/area/awaymission/UO71/gateway) "lC" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel,/area/awaymission/UO71/gateway) "lD" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/atmospherics/pipe/manifold/hidden/supply,/turf/simulated/floor/plasteel{icon_state = "white"},/area/awaymission/UO71/gateway) @@ -782,8 +780,6 @@ "pb" = (/obj/structure/closet/secure_closet{icon_broken = "secbroken"; icon_closed = "sec"; icon_locked = "sec1"; icon_off = "secoff"; icon_opened = "secopen"; icon_state = "sec1"; locked = 1; name = "security officer's locker"; req_access_txt = "271"},/obj/item/flash,/obj/item/reagent_containers/spray/pepper,/obj/item/restraints/handcuffs,/turf/simulated/floor/plasteel{dir = 10; icon_state = "red"},/area/awaymission/UO71/science) "pc" = (/obj/machinery/door/airlock/security/glass{name = "Security Office"; req_access_txt = "271"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/awaymission/UO71/science) "pd" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 2; on = 1; scrub_N2O = 0; scrub_Toxins = 0},/turf/simulated/floor/plasteel{dir = 6; icon_state = "red"},/area/awaymission/UO71/science) -"pe" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 4; on = 1},/turf/simulated/floor/plasteel,/area/awaymission/UO71/centralhall) -"pf" = (/obj/structure/stool/bed/chair/comfy/black{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel{dir = 8; icon_state = "neutral"},/area/awaymission/UO71/centralhall) "pg" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plasteel{dir = 2; icon_state = "neutralcorner"},/area/awaymission/UO71/centralhall) "ph" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1; initialize_directions = 14; tag = "icon-manifold-b-f (NORTH)"},/turf/simulated/floor/plasteel,/area/awaymission/UO71/centralhall) "pi" = (/obj/machinery/door/firedoor,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/door/airlock/public/glass{name = "Central Access"},/turf/simulated/floor/plasteel{dir = 8; icon_state = "neutralcorner"},/area/awaymission/UO71/centralhall) @@ -836,9 +832,7 @@ "qd" = (/obj/machinery/door/poddoor{id_tag = "UO71_SciStorage"; name = "SciStorage Door"},/turf/simulated/floor/plasteel{icon_state = "freezerfloor"},/area/awaymission/UO71/loot) "qe" = (/obj/structure/grille,/obj/structure/window/full/basic,/turf/simulated/floor/plating,/area/awaymission/UO71/medical) "qf" = (/obj/machinery/door/airlock/medical/glass{id_tag = null; name = "Medical Storage"; req_access_txt = "0"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/awaymission/UO71/medical) -"qg" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel{dir = 10; icon_state = "neutral"},/area/awaymission/UO71/centralhall) "qh" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers,/turf/simulated/wall,/area/awaymission/UO71/centralhall) -"qi" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/stool/bed/chair/comfy/black{dir = 4},/turf/simulated/floor/plasteel{dir = 8; icon_state = "neutralcorner"},/area/awaymission/UO71/centralhall) "qj" = (/turf/simulated/floor/plasteel{dir = 6; icon_state = "neutral"},/area/awaymission/UO71/centralhall) "qk" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel{icon_state = "neutral"},/area/awaymission/UO71/centralhall) "ql" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 1; external_pressure_bound = 101.325; on = 1; pressure_checks = 1},/obj/machinery/door_control{id = "awaydorm4"; name = "Door Bolt Control"; normaldoorcontrol = 1; pixel_x = -25; pixel_y = 0; req_access_txt = "0"; specialfunctions = 4},/turf/simulated/floor/carpet,/area/awaymission/UO71/centralhall) @@ -1331,7 +1325,6 @@ "zF" = (/obj/machinery/light{dir = 1},/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/awaymission/UO71/queen) "zG" = (/obj/machinery/door/poddoor{id_tag = "UO71_Caves"; name = "Caves Lockdown Door"},/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/awaymission/UO71/queen) "zH" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8; initialize_directions = 7; tag = "icon-manifold-r-f (WEST)"},/turf/simulated/wall,/area/awaymission/UO71/science) -"zI" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8; initialize_directions = 7; tag = "icon-manifold-b-f (WEST)"},/obj/structure/spider/terrorweb,/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/awaymission/UO71/queen) "zJ" = (/obj/structure/spider/terrorweb,/obj/structure/spider/terrorweb,/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/awaymission/UO71/queen) "zK" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/spider/terrorweb,/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/awaymission/UO71/queen) "zL" = (/obj/structure/table,/obj/machinery/light,/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/awaymission/UO71/queen) @@ -1417,19 +1410,19 @@ aaaaaaaaaaaaaaabababababfLghgQgSgRghgsgVgTfMgWgYgXfLgagpgpgpgUhWgpgpgafNgZhbhahd aaaaaaaaaaaaaaabababababfLghhuhwhvghgshyhxfMhzhBhAfLgagpgpgpgphWgpgpgafOhCighFhdhHhIfNabzcfPhDgegdgegdgdhEfPzcabfbhJfFfbabababababfbhKhLgEhNhMgEgEhOfehPgOhQgkhRfbgbfhabababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaa aaaaaaaaaaaaaaabababababfMhThShYhXhSgshyhZfLfLiafLfLgahUgphVgpmimhmxgafOibihicijiiikfNabzcidiegdifgdgdmygefPzcabfbhJfTfbabababababfbilhhgEhNimgEgEioiniqipgkgkirfeisfhabababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaa aaaaaaaaaaaaaaabababababfMiuitiwiviziyiGiEixiHiJiAiBiCiDgagaiOiOgaiFgafNiPiQgAfOfNfNfOabzciIfPfPfPiRiRiKiLiLjmiMiNiSfTfeabababababfbiTgEiohjhMgEgEiUfbiWiVgkfUiXfbiYfhabababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaa -aaaaaaaaaaaaaaabababababfMjaiZjcjbjejdjfjfjjjhjkfMababababjgjnjnjgjifOfOjojpgzfOababababzcyXzczcyYjqjqyYzczczcabfejsjrfefeababababfejtjugEiohMjyjvjAfbfbjBjwjwjxjxjCjzabababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaa +aaaaaaaaaaaaaaabababababfMjamliwiZjbgsghghjdjcjkfMababababjgjnjnjgjifOfOjojpgzfOababababzcyXzczcyYjqjqyYzczczcabfejsjrfefeababababfejtjugEiohMjyjvjAfbfbjBjwjwjxjxjCjzabababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaa aaaaaaaaaaaaaaabababababfLjEjDiwjFjHfLfLfMfMjIjJfMababababjGjKjKjGjifOfOjLjNjMfOabababababjlababjGjOjOjGababababfbjPfRjQfefbfbfbfefejRjShhjThjhjgEgEjUjWjVjYjXkajZkbfeabababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaa aaaaaaaaaaaaaaabababababfMfLfMkdkcfLfLkkkifMklkqfLfOfOfOfOkekfkgkekhfNkrkjktksfOfOfOfOfOfOkmfOfOknkokpkefOfOfNfOfOkufRfRkvfRfFfRfRjrgEgEgEkwiogEkxkykykAkzfbkBkDkCfefbabababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaa -aaaaaaaaaaaaaaababababababfLkEiwkFlAkGkRkHixkSkUkTkIkJkKkLkMkJkNkOkPkQlckVleldkJkWkNkJkJkXkYkZlalblglflhfOljlilkfOlmlllllllnlllplojrgEiogElrlqlqlqlulslwlvfbfbfefefeababababababababababababababltltltltltabababababababababababababababababababaaaaaaaaaaaaaa +aaaaaaaaaaaaaaababababababfLkEiwkFahkGkRkHixkSkUkTkIkJkKkLkMkJkNkOkPkQlckVleldkJkWkNkJkJkXkYkZlalblglflhfOljlilkfOlmlllllllnlllplojrgEiogElrlqlqlqlulslwlvfbfbfefefeababababababababababababababltltltltltabababababababababababababababababababaaaaaaaaaaaaaa aaaaaaaaaaaaaaababababababfLlxlzlylElylClBmMlDlGlFlHlHlIlHlJlHlLlKlNlMlPlOlRlQlTlSlVlUlXlWlXlXlXlYgAlflhlZgAgAgAlZmbmafFmcfbfefbfbfefefbfbfbmdmehhmffbjsmgfeababababababababababababababababababltnBmzmjltabababababababababababababababababababaaaaaaaaaaaaaa aaaaaaaaaaaaaaababababababfMmkmmmliwjHjHmnfLmompfMfNfOfOfOfNfOfOmqfOfOmsmrfOfOfOmtfOfOfOfNmumumumumvlflhfOokmwqDtDqKfEmBmAfbmCmDmCfemEmGmFfefefbfbfefbmImHfeababababababababababababababababababltmKmJmjltabababababababababababababababababababaaaaaaaaaaaaaa aaaaaaaaaaaaaaababababababfLmLmlmNmPmOmSmQfMfLfLfLabfOgAgAmTfOmVmUmTfNmRmWfOmXmZmYnbnancfOnendnfmumvlbfOfOmRfOfOfNnhngfefefbninknjfbnlnnnmfenonsnqntfbnumHfbabababababababababababababababababnpltltnvnrnrnpababababababababababababababababababaaaaaaaaaaaaaa aaaaaaaaaaaaaaababababababfLfLfMfMfLfLfMfMfLababababfOgAgAgAfOnwmUnxfOmRnyfOnzojnAnDnanafNnFnEnGmumvnCfNnHzDnInInKnMnLnOnNfbfXnPfbfefXnQfbfbnRfFnSnVnUnZnWfbabababababababababababababababababnToaobobobocnpababababababababababababababababababaaaaaaaaaaaaaa aaaaaaaaaaaaaaabababababababababababababababababababfOnXnYgAodgAoeoffOkmogfOohojoiooonopfNoroqosmumvlbfNogzHolomomouotowovoyoxoAozoCoBoAoDoFoEoHoGoJoIoNoMfbabababababababababababababababababnToOoQoPoQoOnpnpnpnpabababababababababababababababaaaaaaaaaaaaaa -aaaaaaaaaaaaaaabababababababababababababababababababfOoKoLgAfOoSoRoTfOkmoUfOoVojoWoYoXoZfNpbpapdpcmvlbfOnymRfbfbfbpfpellpgpiphpkpjplphpnpmpppopkpqprfbptpsfeabababababababababababababababababnppwpypxpApznppupvnpabababababababababababababababaaaaaaaaaaaaaa -aaaaaaaaaaaaaaabababababababababababababababababababfOfOfOfOfOfOfOfOfNpDpCfOpEpFnapGnaoXfOfOpBkmfOmvlafNpHmRfbfbfbpJpIfRpKfbpLfbfhfepMfbfbfepNfbfbpOfbpRmHfbabababababababababababababababababnppSpYpUpYpZnTpPpQnpabababababababababababababababaaaaaaaaaaaaaa -aaaaaaaaaaaaaaabababababababababababababababababababababababababababfNqbjifOfOfOqcfOpTqdpTpTpVpWpXqfqeqaogkmfbfbfbqiqgqkqjfeqlqmqhqoqnfeqpqtqqqwfeqxfehJmHfbababababababababnTnTnpnpnTababababnpqyqyqzqyqynpqrqsnpnpnpabababababababababababababaaaaaaaaaaaaaa -aaaaaaaaaaaaaaabababababababababababababababababababababababababababfOqAkhquqvmuqBqCpTqFzOpTpVqHqGqJqIqaogmRfbfbfbqEzPzQzQzPqLqMfbqOqNfbfbfbqPqQfeqRfbhJmHfbababababababababnTqTqSqSnpnTnTnTnpnpqUqWqVqYqXrcqZrerdrfnpabababababababababababababaaaaaaaaaaaaaa +aaaaaaaaaaaaaaabababababababababababababababababababfOoKoLgAfOoSoRoTfOkmoUfOoVojoWoYoXoZfNpbpapdpcmvlbfOnymRfOfOfbjellllpgpiphpkpjplphpnpmpppopkpqprfbptpsfeabababababababababababababababababnppwpypxpApznppupvnpabababababababababababababababaaaaaaaaaaaaaa +aaaaaaaaaaaaaaabababababababababababababababababababfOfOfOfOfOfOfOfOfNpDpCfOpEpFnapGnaoXfOfOpBkmfOmvlafNpHmRfOfOfbpJpIfRpKfbpLfbfhfepMfbfbfepNfbfbpOfbpRmHfbabababababababababababababababababnppSpYpUpYpZnTpPpQnpabababababababababababababababaaaaaaaaaaaaaa +aaaaaaaaaaaaaaabababababababababababababababababababababababababababfNqbjifOfOfOqcfOpTqdpTpTpVpWpXqfqeqaogkmfOfOfbjhjfqkqjfeqlqmqhqoqnfeqpqtqqqwfeqxfehJmHfbababababababababnTnTnpnpnTababababnpqyqyqzqyqynpqrqsnpnpnpabababababababababababababaaaaaaaaaaaaaa +aaaaaaaaaaaaaaabababababababababababababababababababababababababababfOqAkhquqvmuqBqCpTqFzOpTpVqHqGqJqIqaogmRfOfOfbqEzPzQzQzPqLqMfbqOqNfbfbfbqPqQfeqRfbhJmHfbababababababababnTqTqSqSnpnTnTnTnpnpqUqWqVqYqXrcqZrerdrfnpabababababababababababababaaaaaaaaaaaaaa aaaaaaaaaaaaaaabababababababababababababababababababababababababababfOrgjirarbrjrirkpTqFqFpTrhroqJqJrpqarqrlrmrmrmrnrmrsrrsartmCfbrvrufbrwrxqqryfbrzfbrBrAfbfbfbfbfefbfbfbfbnprDrCrFrEnTrHrJrIrGrKrMrLrOrNrNrPrSrRrfnpnpnTnTababababababababababaaaaaaaaaaaaaa aaaaaaaaaaaaaaabababababababababababababababababababababababababababfNrTkhqurQmurUrVpTrXrWpTpVrZrYscsbqasdmRsasgsfshsesirrsafefefefbfefbfefesjfbfbskfesmslsosnsqspsrsnstsssvsusxswszsysBsAsDsCsFsEsHsGsJsIsOsOsPsPsQsKsLsMnTababababababababababaaaaaaaaaaaaaa aaaaaaaaaaaaaaabababababababababababababababababababababababababababfNrgkhfOfOfOfNfNpTpTsNpTpVsSsRsUsTqaogmRsarrrrsVsarrsWsaabababababfbsXsYqqsZferzfejPtanUtbtctbtdtbtftethtgtititktjtmtltotnsFtptrtqtttstvtutAtztBtwtxtynpababababababababababaaaaaaaaaaaaaa @@ -1471,7 +1464,7 @@ aaaaaaaaaaaaaaababababababababababababababababababababababababababababababababab aaaaaaaaaaaaaaabababababababababababababababababababuWababababababababababababababababababababababababababuWuWuWuWababababababababababababuWuWuWzyzdzyzzzBzyzyzyzyzgzgzdzguWuWabababuWuWuWabababuWuWuWuWuWuWuWuWuWabuWuWuWuWuWabababababababababaaaaaaaaaaaaaa aaaaaaaaaaaaaaabababababababababababababababababababuWuWabababababababababababababababababababababababababuWuWuWababababababababababababababuWuWzyzdzyzzagzFzCzAzyzyzyzdzguWabababababuWababababuWabababuWuWuWabuWuWuWuWuWuWuWabababababababababaaaaaaaaaaaaaa aaaaaaaaaaaaaaababababababababababababababababababababuWuWabababababababababababababababababababababababuWuWzrabababababababababababababababuWuWzBagzGzqaiagagzAzAzyzyzdzguWababuWabuWuWabababababababuWuWuWababababuWuWuWuWuWuWababababababababaaaaaaaaaaaaaa -aaaaaaaaaaaaaaabababababababababababababababababababababuWuWuWababababababababababababababababababababuWuWuWabababababababababababababababababuWzyzdzyzIaeahagzAzJzyzyzdzguWababuWabuWabababababababuWuWuWababababababuWuWuWuWzrababababababababaaaaaaaaaaaaaa +aaaaaaaaaaaaaaabababababababababababababababababababababuWuWuWababababababababababababababababababababuWuWuWabababababababababababababababababuWzyzdzyzKagagagzAzJzyzyzdzguWababuWabuWabababababababuWuWuWababababababuWuWuWuWzrababababababababaaaaaaaaaaaaaa aaaaaaaaaaaaaaababababababababababababababababababababababuWuWuWababababababababuWuWuWuWuWabababababuWuWuWabababababababababababababababababababzyzdzyzKzAagagaizAzyzyzdzyuWababuWuWuWababuWababababuWuWabababababababuWuWuWuWuWababababababababaaaaaaaaaaaaaa aaaaaaaaaaaaaaababababababababababababababababababababababababuWuWababababababuWuWuWuWuWuWuWuWabababuWuWzrabababababababababababababababababababzyzdzyzMzAzAagagagagzyzdzyuWababuWuWabababuWababababuWuWabababababababzruWuWuWuWababababababababaaaaaaaaaaaaaa aaaaaaaaaaaaaaabababababababababababababababababababababababababuWuWuWuWuWuWuWuWababababababuWuWuWabuWuWababababababababababababababababababababzyzdzyzMzAzCagagagagzyzdzyuWabababababababuWuWababuWuWababababababababuWuWuWuWuWababababababababaaaaaaaaaaaaaa @@ -1487,7 +1480,7 @@ aaaaaaaaaaaaaaababababababababababababababababababababababababababababababababab aaaaaaaaaaaaaaababababababababababababababababababababababababababababababababababababababababababuWuWuWuWuWuWuWuWuWuWuWuWuWuWuWuWuWuWuWuWuWuWuWzyzdzyzqzAagzgzgagagzyzdzyuWuWuWababuWuWababuWuWuWababuWababuWuWuWuWuWabababababababababababababaaaaaaaaaaaaaa aaaaaaaaaaaaaaababababababababababababababababababababababababababababababababababababababababababababuWuWuWuWuWuWuWuWuWuWuWuWuWuWuWuWuWababababzyzdzgzqagzAzgagzAaizGagzBuWuWababababuWabababuWuWababuWuWabuWuWuWuWuWabababababababababababababaaaaaaaaaaaaaa aaaaaaaaaaaaaaabababababababababababababababababababababababababababababababababababababababababababababuWuWuWuWuWuWuWuWuWuWuWuWuWuWuWuWuWabababzyzdzgzqagaizFagagagzyzdzyabuWababuWabuWuWababuWuWabababuWuWuWuWuWuWuWabababababababababababababaaaaaaaaaaaaaa -aaaaaaaaaaaaaaababababababababababababababababababababababababababababababababababababababababababababababababababuWuWuWuWuWabababuWuWuWuWabababzyzdzgafaeahagaiagagzyzdzyabuWuWuWuWababuWababuWuWuWababuWuWuWuWuWuWababababababababababababababaaaaaaaaaaaaaa +aaaaaaaaaaaaaaababababababababababababababababababababababababababababababababababababababababababababababababababuWuWuWuWuWabababuWuWuWuWabababzyzdzgzqagagagaiagagzyzdzyabuWuWuWuWababuWababuWuWuWababuWuWuWuWuWuWababababababababababababababaaaaaaaaaaaaaa aaaaaaaaaaaaaaabababababababababababababababababababababababababababababababababababababababababababababababababuWuWuWuWuWuWabababababuWuWuWababzyzdzgzMagagagagagzgzyzdzyabababababababuWabababuWuWabuWuWuWabuWuWuWababababababababababababababaaaaaaaaaaaaaa aaaaaaaaaaaaaaababababababababababababababababababababababababababababababababababababababababababababababababuWuWuWuWuWuWabababababababuWuWuWabzyzdzyzMzgagagagzgzgzyzdzyababababababuWuWababababuWuWuWuWabuWuWuWabababababababababababababababaaaaaaaaaaaaaa aaaaaaaaaaaaaaabababababababababababababababababababababababababababababababababababababababababababababababuWuWuWuWuWuWabababababababababuWuWabzgzdzdzezdzRzRzRzdzdzdzdzgababuWuWuWuWuWabababuWuWuWuWabuWuWuWuWababababababababababababababababaaaaaaaaaaaaaa diff --git a/_maps/map_files/RandomZLevels/wildwest.dmm b/_maps/map_files/RandomZLevels/wildwest.dmm index 52dae9cef94..5f8aa9e293a 100644 --- a/_maps/map_files/RandomZLevels/wildwest.dmm +++ b/_maps/map_files/RandomZLevels/wildwest.dmm @@ -156,7 +156,7 @@ "cZ" = (/obj/structure/window/reinforced{tag = "icon-fwindow (EAST)"; icon_state = "fwindow"; dir = 4},/obj/structure/window/reinforced{tag = "icon-fwindow (WEST)"; icon_state = "fwindow"; dir = 8},/obj/structure/grille,/obj/structure/window/reinforced{tag = "icon-fwindow (NORTH)"; icon_state = "fwindow"; dir = 1},/turf/simulated/floor/plating/ironsand{tag = "icon-ironsand1"; icon_state = "ironsand1"},/area/awaymission/wwgov) "da" = (/obj/effect/landmark/corpse/syndicatecommando{mobname = "Syndicate Commando"},/turf/simulated/floor/carpet,/area/awaymission/wwgov) "db" = (/obj/machinery/mineral/mint,/turf/simulated/floor/plating,/area/awaymission/wwrefine) -"dc" = (/obj/structure/window/reinforced{dir = 5; health = 1e+007},/turf/simulated/floor/wood,/area/awaymission/wwmines) +"dc" = (/obj/structure/window/reinforced{dir = 5; max_integrity = 1e+007},/turf/simulated/floor/wood,/area/awaymission/wwmines) "dd" = (/obj/structure/mineral_door/wood,/turf/simulated/floor/plating/ironsand{tag = "icon-ironsand1"; icon_state = "ironsand1"},/area/awaymission/wwmines) "de" = (/obj/structure/mineral_door/wood,/obj/effect/decal/cleanable/blood/tracks,/turf/simulated/floor/plating/ironsand{tag = "icon-ironsand1"; icon_state = "ironsand1"},/area/awaymission/wwmines) "df" = (/obj/structure/window/reinforced{dir = 4},/turf/space,/area/space) diff --git a/_maps/map_files/cyberiad/cyberiad.dmm b/_maps/map_files/cyberiad/cyberiad.dmm index e9974435ba9..618b257bcd7 100644 --- a/_maps/map_files/cyberiad/cyberiad.dmm +++ b/_maps/map_files/cyberiad/cyberiad.dmm @@ -7418,8 +7418,8 @@ "cNb" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 1; external_pressure_bound = 101; on = 1; pressure_checks = 1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/light{dir = 1},/obj/structure/cable/yellow{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor/plasteel{dir = 1; icon_state = "warning"},/area/engine/engineering) "cNc" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1; initialize_directions = 11; level = 1},/obj/machinery/camera{c_tag = "Engineering Particle Accelerator"; dir = 2; pixel_x = 23; network = list("Singularity","SS13")},/obj/machinery/light{dir = 1},/obj/structure/cable/yellow{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/plasteel{dir = 1; icon_state = "warning"},/area/engine/engineering) "cNd" = (/obj/structure/barricade/wooden,/turf/simulated/floor/plating,/area/maintenance/asmaint) -"cNe" = (/obj/structure/disposalpipe/segment,/obj/structure/grille,/obj/structure/window/reinforced{dir = 5; health = 1e+007},/turf/simulated/floor/plating,/area/maintenance/asmaint) -"cNf" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 5; health = 1e+007},/turf/simulated/floor/plating,/area/maintenance/asmaint) +"cNe" = (/obj/structure/disposalpipe/segment,/obj/structure/grille,/obj/structure/window/reinforced{dir = 5; max_integrity = 1e+007},/turf/simulated/floor/plating,/area/maintenance/asmaint) +"cNf" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 5; max_integrity = 1e+007},/turf/simulated/floor/plating,/area/maintenance/asmaint) "cNg" = (/obj/structure/sign/barsign,/turf/simulated/wall,/area/maintenance/asmaint) "cNh" = (/obj/effect/decal/cleanable/vomit,/turf/simulated/floor/plating,/area/maintenance/genetics) "cNi" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plasteel,/area/engine/engineering) diff --git a/_maps/map_files/cyberiad/z6.dmm b/_maps/map_files/cyberiad/z6.dmm index ee16cf0c496..5e8b66e6c24 100644 --- a/_maps/map_files/cyberiad/z6.dmm +++ b/_maps/map_files/cyberiad/z6.dmm @@ -69,7 +69,7 @@ "bq" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; icon_state = "space"; layer = 4; name = "EXTERNAL AIRLOCK"; pixel_x = 0; pixel_y = -32},/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/djstation) "br" = (/obj/machinery/light_switch{pixel_x = 28; pixel_y = 28},/obj/machinery/access_button{command = "cycle_interior"; frequency = 1479; master_tag = "dj_station_airlock"; name = "interior access button"; pixel_x = 25; pixel_y = -25; req_access_txt = "0"},/obj/machinery/atmospherics/pipe/simple/hidden,/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/djstation) "bs" = (/obj/structure/lattice,/obj/structure/grille,/turf/space,/area/space) -"bt" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 5; health = 1e+007},/turf/simulated/floor/plating,/area/derelict/solar_control) +"bt" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 5; max_integrity = 1e+007},/turf/simulated/floor/plating,/area/derelict/solar_control) "bu" = (/turf/simulated/floor/plating,/area/derelict/solar_control) "bv" = (/obj/machinery/door/airlock/external{frequency = 1479; icon_state = "door_locked"; id_tag = "dj_station_inner"; locked = 1; name = "DJ Station Interior Access"; req_access = null; req_access_txt = "0"},/obj/machinery/atmospherics/pipe/simple/hidden,/turf/simulated/floor/plating,/area/djstation) "bw" = (/obj/machinery/door/airlock/external{name = "Air Bridge Access"},/turf/simulated/floor/plating,/area/derelict/solar_control) @@ -180,7 +180,7 @@ "dy" = (/obj/machinery/power/emitter{dir = 1; icon_state = "emitter"},/turf/simulated/floor/plating/airless,/area/derelict/singularity_engine) "dz" = (/obj/machinery/field/generator,/turf/simulated/floor/plating/airless,/area/derelict/singularity_engine) "dA" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/window/reinforced,/turf/simulated/floor/plasteel,/area/derelict/bridge/access) -"dB" = (/obj/structure/window/reinforced{dir = 5; health = 1e+007},/turf/simulated/floor/plasteel,/area/derelict/bridge/access) +"dB" = (/obj/structure/window/reinforced{dir = 5; max_integrity = 1e+007},/turf/simulated/floor/plasteel,/area/derelict/bridge/access) "dC" = (/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plasteel,/area/derelict/bridge) "dD" = (/obj/item/stack/rods,/turf/simulated/floor/plating/airless,/area/space) "dE" = (/obj/structure/grille,/obj/structure/window/reinforced,/turf/simulated/floor/plating/airless,/area/derelict/singularity_engine) @@ -509,7 +509,7 @@ "jQ" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating/airless,/area/space) "jR" = (/obj/structure/closet/wardrobe/mixed,/turf/simulated/floor/plasteel,/area/derelict/arrival) "jS" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating/airless,/area/space) -"jT" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 5; health = 1e+007},/turf/simulated/floor/plating,/area/derelict/arrival) +"jT" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 5; max_integrity = 1e+007},/turf/simulated/floor/plating,/area/derelict/arrival) "jU" = (/obj/machinery/door/airlock/external{name = "Escape Airlock"},/turf/simulated/floor/plating,/area/derelict/arrival) "jV" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plating/airless,/area/space) "jW" = (/turf/simulated/wall,/area/derelict/hallway/secondary) @@ -521,7 +521,7 @@ "kc" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; tag = ""},/turf/simulated/wall/r_wall,/area/derelict/hallway/secondary) "kd" = (/obj/structure/window/basic{dir = 1},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/turf/simulated/floor/plating/airless,/area/derelict/hallway/secondary) "ke" = (/obj/structure/grille,/obj/item/shard,/obj/item/shard{icon_state = "medium"},/turf/simulated/floor/plating/airless,/area/space) -"kf" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 5; health = 1e+007},/turf/simulated/floor/plating/airless,/area/space) +"kf" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 5; max_integrity = 1e+007},/turf/simulated/floor/plating/airless,/area/space) "kg" = (/obj/structure/girder,/turf/simulated/floor/plating/airless,/area/derelict/hallway/primary) "kh" = (/obj/item/stack/rods,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plasteel/airless,/area/derelict/hallway/secondary) "ki" = (/obj/item/shard{icon_state = "small"},/turf/space,/area/space) diff --git a/code/__DEFINES/clothing.dm b/code/__DEFINES/clothing.dm index 69561ee97ef..f7fe5b8b28e 100644 --- a/code/__DEFINES/clothing.dm +++ b/code/__DEFINES/clothing.dm @@ -90,6 +90,6 @@ #define ONESIZEFITSALL 1 // determines if something can be worn by a fatty or not. //flags for muzzle speech blocking -#define MUTE_NONE 0 // Does not mute you. -#define MUTE_MUFFLE 1 // Muffles everything you say "MHHPHHMMM!!! -#define MUTE_ALL 2 // Completely mutes you. \ No newline at end of file +#define MUZZLE_MUTE_NONE 0 // Does not mute you. +#define MUZZLE_MUTE_MUFFLE 1 // Muffles everything you say "MHHPHHMMM!!! +#define MUZZLE_MUTE_ALL 2 // Completely mutes you. \ No newline at end of file diff --git a/code/__DEFINES/combat.dm b/code/__DEFINES/combat.dm index 4c2708bf9dd..c244dc0c7a7 100644 --- a/code/__DEFINES/combat.dm +++ b/code/__DEFINES/combat.dm @@ -39,8 +39,7 @@ #define IGNORESLOWDOWN 256 #define GODMODE 4096 #define FAKEDEATH 8192 //Replaces stuff like changeling.changeling_fakedeath -#define DISFIGURED 16384 //I'll probably move this elsewhere if I ever get wround to writing a bitflag mob-damage system -#define XENO_HOST 32768 //Tracks whether we're gonna be a baby alien's mummy. +#define XENO_HOST 16384 //Tracks whether we're gonna be a baby alien's mummy. //Grab levels diff --git a/code/__DEFINES/construction.dm b/code/__DEFINES/construction.dm index 9d8ca0b3013..fa62fd7af4f 100644 --- a/code/__DEFINES/construction.dm +++ b/code/__DEFINES/construction.dm @@ -18,6 +18,11 @@ #define RWALL_SUPPORT_RODS 5 #define RWALL_SHEATH 6 +//window construction states +#define WINDOW_OUT_OF_FRAME 0 +#define WINDOW_IN_FRAME 1 +#define WINDOW_SCREWED_TO_FRAME 2 + //airlock assembly construction states #define AIRLOCK_ASSEMBLY_NEEDS_WIRES 0 #define AIRLOCK_ASSEMBLY_NEEDS_ELECTRONICS 1 @@ -32,6 +37,9 @@ //windows affected by nar-sie turn this color. #define NARSIE_WINDOW_COLOUR "#7D1919" +//let's just pretend fulltile windows being children of border windows is fine +#define FULLTILE_WINDOW_DIR NORTHEAST + //Material defines, for determining how much of a given material an item contains #define MAT_METAL "$metal" #define MAT_GLASS "$glass" diff --git a/code/__DEFINES/is_helpers.dm b/code/__DEFINES/is_helpers.dm index d480bb6bbbd..2862010d316 100644 --- a/code/__DEFINES/is_helpers.dm +++ b/code/__DEFINES/is_helpers.dm @@ -26,6 +26,16 @@ var/list/static/global/pointed_types = typecacheof(list( #define is_pointed(W) (is_type_in_typecache(W, pointed_types)) +GLOBAL_LIST_INIT(glass_sheet_types, typecacheof(list( + /obj/item/stack/sheet/glass, + /obj/item/stack/sheet/rglass, + /obj/item/stack/sheet/plasmaglass, + /obj/item/stack/sheet/plasmarglass, + /obj/item/stack/sheet/titaniumglass, + /obj/item/stack/sheet/plastitaniumglass))) + +#define is_glass_sheet(O) (is_type_in_typecache(O, GLOB.glass_sheet_types)) + //Turfs #define issimulatedturf(A) istype(A, /turf/simulated) diff --git a/code/__DEFINES/layers.dm b/code/__DEFINES/layers.dm index 8ec06dbcbd4..58e2be31b01 100644 --- a/code/__DEFINES/layers.dm +++ b/code/__DEFINES/layers.dm @@ -7,6 +7,7 @@ #define PLANE_SPACE_PARALLAX -90 #define GAME_PLANE 0 +#define SPACE_LAYER 1.8 //#define TURF_LAYER 2 //For easy recordkeeping; this is a byond define #define MID_TURF_LAYER 2.02 #define HIGH_TURF_LAYER 2.03 diff --git a/code/__DEFINES/lighting.dm b/code/__DEFINES/lighting.dm index b23c5699e4b..3db7c467c24 100644 --- a/code/__DEFINES/lighting.dm +++ b/code/__DEFINES/lighting.dm @@ -2,7 +2,6 @@ #define LIGHTING_LAMBERTIAN 0 // use lambertian shading for light sources #define LIGHTING_HEIGHT 1 // height off the ground of light sources on the pseudo-z-axis, you should probably leave this alone -#define LIGHTING_LAYER 10 // drawing layer for lighting overlays #define LIGHTING_ICON 'icons/effects/lighting_overlay.dmi' // icon used for lighting shading effects #define LIGHTING_ROUND_VALUE (1 / 128) //Value used to round lumcounts, values smaller than 1/255 don't matter (if they do, thanks sinking points), greater values will make lighting less precise, but in turn increase performance, VERY SLIGHTLY. diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm index adc21f00452..6e489098c29 100644 --- a/code/__DEFINES/misc.dm +++ b/code/__DEFINES/misc.dm @@ -200,7 +200,7 @@ #define MARKINGS_LAYER 4 #define UNDERWEAR_LAYER 5 #define MUTATIONS_LAYER 6 -#define DAMAGE_LAYER 7 +#define H_DAMAGE_LAYER 7 #define UNIFORM_LAYER 8 #define ID_LAYER 9 #define SHOES_LAYER 10 @@ -328,7 +328,6 @@ #define SECOND_DIAG_STEP 2 #define ARBITRARY_VIEWRANGE_NOHUD 2 -#define SECOND_DIAG_STEP 2 //Bloody shoes/footprints #define MAX_SHOE_BLOODINESS 100 @@ -348,3 +347,14 @@ // The SQL version required by this version of the code #define SQL_VERSION 3 + +// Vending machine stuff +#define CAT_NORMAL 1 +#define CAT_HIDDEN 2 +#define CAT_COIN 4 + +// Jobs +// used for alternate_option +#define GET_RANDOM_JOB 0 +#define BE_ASSISTANT 1 +#define RETURN_TO_LOBBY 2 diff --git a/code/__DEFINES/vv.dm b/code/__DEFINES/vv.dm index 3acd09a1a81..22e13f87f8a 100644 --- a/code/__DEFINES/vv.dm +++ b/code/__DEFINES/vv.dm @@ -18,4 +18,5 @@ #define VV_NEW_LIST "New List" #define VV_NULL "NULL" #define VV_RESTORE_DEFAULT "Restore to Default" -#define VV_MARKED_DATUM "Marked Datum" \ No newline at end of file +#define VV_MARKED_DATUM "Marked Datum" +#define VV_REGEX "Regex" \ No newline at end of file diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm index 5c483b310fe..b62f32c2da9 100644 --- a/code/__HELPERS/game.dm +++ b/code/__HELPERS/game.dm @@ -490,19 +490,26 @@ proc/pollCandidates(Question, be_special_type, antag_age_check = 0, poll_time = return candidates -/proc/pollCandidatesByKeyWithVeto(adminclient, adminusr, max_slots, Question, be_special_type, antag_age_check = 0, poll_time = 300, ignore_respawnability = 0, min_hours = 0, flashwindow = TRUE, check_antaghud = TRUE) +/proc/pollCandidatesWithVeto(adminclient, adminusr, max_slots, Question, be_special_type, antag_age_check = 0, poll_time = 300, ignore_respawnability = 0, min_hours = 0, flashwindow = TRUE, check_antaghud = TRUE) var/list/willing_ghosts = pollCandidates(Question, be_special_type, antag_age_check, poll_time, ignore_respawnability, min_hours, flashwindow, check_antaghud) - var/list/candidate_ckeys = list() - var/list/selected_ckeys = list() + var/list/selected_ghosts = list() if(!willing_ghosts.len) - return selected_ckeys - for(var/mob/dead/observer/G in willing_ghosts) - candidate_ckeys += G.key - for(var/i = max_slots, (i > 0 && candidate_ckeys.len), i--) - var/this_ckey = input("Pick players. This will go on until there either no more ghosts to pick from or the slots are full.", "Candidates") as null|anything in candidate_ckeys - candidate_ckeys -= this_ckey - selected_ckeys += this_ckey - return selected_ckeys + return selected_ghosts + + var/list/candidate_ghosts = willing_ghosts.Copy() + + to_chat(adminusr, "Candidate Ghosts:"); + for(var/mob/dead/observer/G in candidate_ghosts) + if(G.key && G.client) + to_chat(adminusr, "- [G] ([G.key])"); + else + candidate_ghosts -= G + + for(var/i = max_slots, (i > 0 && candidate_ghosts.len), i--) + var/this_ghost = input("Pick players. This will go on until there either no more ghosts to pick from or the [i] remaining slot(s) are full.", "Candidates") as null|anything in candidate_ghosts + candidate_ghosts -= this_ghost + selected_ghosts += this_ghost + return selected_ghosts /proc/window_flash(client/C) if(ismob(C)) diff --git a/code/__HELPERS/mobs.dm b/code/__HELPERS/mobs.dm index 7f7b9715907..a8a6307e70c 100644 --- a/code/__HELPERS/mobs.dm +++ b/code/__HELPERS/mobs.dm @@ -255,8 +255,8 @@ This is always put in the attack log. add_attack_logs(user, M, what_done, admin_notify) return - var/user_str = key_name(user) - var/target_str = key_name(target) + var/user_str = key_name_log(user) + var/target_str = key_name_log(target) if(istype(user)) user.create_attack_log("Attacked [target_str]: [what_done]") @@ -478,4 +478,17 @@ This is always put in the attack log. /proc/update_all_mob_security_hud() for(var/mob/living/carbon/human/H in mob_list) - H.sec_hud_set_security_status() \ No newline at end of file + H.sec_hud_set_security_status() + +/proc/getviewsize(view) + var/viewX + var/viewY + if(isnum(view)) + var/totalviewrange = 1 + 2 * view + viewX = totalviewrange + viewY = totalviewrange + else + var/list/viewrangelist = splittext(view, "x") + viewX = text2num(viewrangelist[1]) + viewY = text2num(viewrangelist[2]) + return list(viewX, viewY) \ No newline at end of file diff --git a/code/__HELPERS/text.dm b/code/__HELPERS/text.dm index 54c79d26a7f..5fb559651d5 100644 --- a/code/__HELPERS/text.dm +++ b/code/__HELPERS/text.dm @@ -547,3 +547,5 @@ proc/checkhtml(var/t) text = replacetext(text, "", "\[cell\]") text = replacetext(text, "", "\[logo\]") return text + +#define string2charlist(string) (splittext(string, regex("(\\x0A|.)")) - splittext(string, "")) \ No newline at end of file diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index 20c707b38f7..35d271461df 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -170,9 +170,12 @@ Turf and target are seperate in case you want to teleport some distance from a t // Checks if doors are open /proc/DirBlocked(turf/loc,var/dir) for(var/obj/structure/window/D in loc) - if(!D.density) continue - if(D.is_fulltile()) return 1 - if(D.dir == dir) return 1 + if(!D.density) + continue + if(D.fulltile) + return 1 + if(D.dir == dir) + return 1 for(var/obj/machinery/door/D in loc) if(!D.density)//if the door is open @@ -1052,6 +1055,8 @@ proc/get_mob_with_client_list() //Find coordinates var/turf/T = get_turf(AM) //use AM's turfs, as it's coords are the same as AM's AND AM's coords are lost if it is inside another atom + if(!T) + return null var/final_x = T.x + rough_x var/final_y = T.y + rough_y @@ -1500,6 +1505,22 @@ var/mob/dview/dview_mob = new return TRUE return FALSE +//can a window be here, or is there a window blocking it? +/proc/valid_window_location(turf/T, dir_to_check) + if(!T) + return FALSE + for(var/obj/O in T) + if(istype(O, /obj/machinery/door/window) && (O.dir == dir_to_check || dir_to_check == FULLTILE_WINDOW_DIR)) + return FALSE + if(istype(O, /obj/structure/windoor_assembly)) + var/obj/structure/windoor_assembly/W = O + if(W.ini_dir == dir_to_check || dir_to_check == FULLTILE_WINDOW_DIR) + return FALSE + if(istype(O, /obj/structure/window)) + var/obj/structure/window/W = O + if(W.ini_dir == dir_to_check || W.ini_dir == FULLTILE_WINDOW_DIR || dir_to_check == FULLTILE_WINDOW_DIR) + return FALSE + return TRUE //Get the dir to the RIGHT of dir if they were on a clock //NORTH --> NORTHEAST diff --git a/code/_onclick/ai.dm b/code/_onclick/ai.dm index d88ff6201f8..b2521527a98 100644 --- a/code/_onclick/ai.dm +++ b/code/_onclick/ai.dm @@ -35,6 +35,17 @@ return var/turf/pixel_turf = get_turf_pixel(A) + if(isnull(pixel_turf)) + return + if(!can_see(A)) + if(isturf(A)) //On unmodified clients clicking the static overlay clicks the turf underneath + return // So there's no point messaging admins + message_admins("[key_name_admin(src)] might be running a modified client! (failed can_see on AI click of [A]([ADMIN_COORDJMP(pixel_turf)]))") + var/message = "[key_name(src)] might be running a modified client! (failed can_see on AI click of [A]([COORD(pixel_turf)]))" + log_admin(message) + send2irc_adminless_only("NOCHEAT", "[key_name(src)] might be running a modified client! (failed checkTurfVis on AI click of [A]([COORD(pixel_turf)]))") + + var/turf_visible if(pixel_turf) turf_visible = cameranet.checkTurfVis(pixel_turf) @@ -157,9 +168,6 @@ return /atom/proc/AICtrlClick(var/mob/living/silicon/ai/user) - if(user.holo) - var/obj/machinery/hologram/holopad/H = user.holo - H.face_atom(src) return /obj/machinery/door/airlock/AICtrlClick() // Bolts doors diff --git a/code/_onclick/hud/movable_screen_objects.dm b/code/_onclick/hud/movable_screen_objects.dm index 315fce5bf65..668e0e67fc7 100644 --- a/code/_onclick/hud/movable_screen_objects.dm +++ b/code/_onclick/hud/movable_screen_objects.dm @@ -11,6 +11,8 @@ /obj/screen/movable var/snap2grid = FALSE var/moved = FALSE + var/x_off = -16 + var/y_off = -16 //Snap Screen Object //Tied to the grid, snaps to the nearest turf @@ -39,8 +41,8 @@ screen_loc = "[screen_loc_X[1]],[screen_loc_Y[1]]" else //Normalise Pixel Values (So the object drops at the center of the mouse, not 16 pixels off) - var/pix_X = text2num(screen_loc_X[2]) - 16 - var/pix_Y = text2num(screen_loc_Y[2]) - 16 + var/pix_X = text2num(screen_loc_X[2]) + x_off + var/pix_Y = text2num(screen_loc_Y[2]) + y_off screen_loc = "[screen_loc_X[1]]:[pix_X],[screen_loc_Y[1]]:[pix_Y]" moved = screen_loc diff --git a/code/_onclick/other_mobs.dm b/code/_onclick/other_mobs.dm index 87b78259593..dcac994c7c7 100644 --- a/code/_onclick/other_mobs.dm +++ b/code/_onclick/other_mobs.dm @@ -12,6 +12,11 @@ if(proximity && istype(G) && G.Touch(A, 1)) return + if(HULK in mutations) + if(proximity) //no telekinetic hulk attack + if(A.attack_hulk(src)) + return + A.attack_hand(src) /atom/proc/attack_hand(mob/user as mob) diff --git a/code/controllers/subsystem/air.dm b/code/controllers/subsystem/air.dm index 4c2774d58db..d46ec164e35 100644 --- a/code/controllers/subsystem/air.dm +++ b/code/controllers/subsystem/air.dm @@ -367,5 +367,5 @@ SUBSYSTEM_DEF(air) #undef SSAIR_ACTIVETURFS #undef SSAIR_EXCITEDGROUPS #undef SSAIR_HIGHPRESSURE -#undef SSAIR_HOTSPOT +#undef SSAIR_HOTSPOTS #undef SSAIR_SUPERCONDUCTIVITY diff --git a/code/datums/diseases/advance/advance.dm b/code/datums/diseases/advance/advance.dm index 71c1bd74a28..435ccad80cd 100644 --- a/code/datums/diseases/advance/advance.dm +++ b/code/datums/diseases/advance/advance.dm @@ -438,5 +438,3 @@ var/list/advance_cures = list( var/datum/symptom/S = i total_transmittable += S.transmittable return total_transmittable - -#undef RANDOM_STARTING_LEVEL diff --git a/code/datums/holocall.dm b/code/datums/holocall.dm new file mode 100644 index 00000000000..a98a65cb1a2 --- /dev/null +++ b/code/datums/holocall.dm @@ -0,0 +1,190 @@ +#define HOLOPAD_MAX_DIAL_TIME 200 + +/mob/camera/aiEye/remote/holo/setLoc() + . = ..() + var/obj/machinery/hologram/holopad/H = origin + H.move_hologram(eye_user, loc) + +//this datum manages it's own references + +/datum/holocall + var/mob/living/user //the one that called + var/obj/machinery/hologram/holopad/calling_holopad //the one that sent the call + var/obj/machinery/hologram/holopad/connected_holopad //the one that answered the call (may be null) + var/list/dialed_holopads //all things called, will be cleared out to just connected_holopad once answered + + var/mob/camera/aiEye/remote/holo/eye //user's eye, once connected + var/obj/effect/overlay/holo_pad_hologram/hologram //user's hologram, once connected + var/datum/action/innate/end_holocall/hangup //hangup action + + var/call_start_time + +//creates a holocall made by `caller` from `calling_pad` to `callees` +/datum/holocall/New(mob/living/caller, obj/machinery/hologram/holopad/calling_pad, list/callees) + call_start_time = world.time + user = caller + calling_pad.outgoing_call = src + calling_holopad = calling_pad + dialed_holopads = list() + + for(var/I in callees) + var/obj/machinery/hologram/holopad/H = I + if(!QDELETED(H) && !(H.stat & NOPOWER)) + dialed_holopads += H + var/area/area = get_area(H) + LAZYADD(H.holo_calls, src) + H.atom_say("[area] pad beeps: Incoming call from [caller]!") + + if(!dialed_holopads.len) + calling_holopad.atom_say("Connection failure.") + qdel(src) + return + +//cleans up ALL references :) +/datum/holocall/Destroy() + QDEL_NULL(hangup) + + var/user_good = !QDELETED(user) + if(user_good) + user.reset_perspective() + user.remote_control = null + + if(!QDELETED(eye)) + eye.RemoveImages() + QDEL_NULL(eye) + + if(connected_holopad && !QDELETED(hologram)) + hologram = null + connected_holopad.clear_holo(user) + + user = null + + //Hologram survived holopad destro + if(!QDELETED(hologram)) + hologram.HC = null + QDEL_NULL(hologram) + + + for(var/I in dialed_holopads) + var/obj/machinery/hologram/holopad/H = I + LAZYREMOVE(H.holo_calls, src) + dialed_holopads.Cut() + + if(calling_holopad) + calling_holopad.outgoing_call = null + calling_holopad.SetLightsAndPower() + calling_holopad = null + if(connected_holopad) + connected_holopad.SetLightsAndPower() + connected_holopad = null + + + return ..() + + +//Gracefully disconnects a holopad `H` from a call. Pads not in the call are ignored. Notifies participants of the disconnection +/datum/holocall/proc/Disconnect(obj/machinery/hologram/holopad/H) + if(H == connected_holopad) + var/area/A = get_area(connected_holopad) + calling_holopad.atom_say("[A] holopad disconnected.") + else if(H == calling_holopad && connected_holopad) + connected_holopad.atom_say("[user] disconnected.") + + user.unset_machine(H) + if(istype(hangup)) + hangup.Remove(user) + + ConnectionFailure(H, TRUE) + +//Forcefully disconnects a holopad `H` from a call. Pads not in the call are ignored. +/datum/holocall/proc/ConnectionFailure(obj/machinery/hologram/holopad/H, graceful = FALSE) + if(H == connected_holopad || H == calling_holopad) + if(!graceful && H != calling_holopad) + calling_holopad.atom_say("Connection failure.") + qdel(src) + return + + LAZYREMOVE(H.holo_calls, src) + dialed_holopads -= H + if(!dialed_holopads.len) + if(graceful) + calling_holopad.atom_say("Call rejected.") + qdel(src) + +//Answers a call made to a holopad `H` which cannot be the calling holopad. Pads not in the call are ignored +/datum/holocall/proc/Answer(obj/machinery/hologram/holopad/H) + if(H == calling_holopad) + return + + if(!(H in dialed_holopads)) + return + + if(connected_holopad) + return + + for(var/I in dialed_holopads) + if(I == H) + continue + Disconnect(I) + + for(var/I in H.holo_calls) + var/datum/holocall/HC = I + if(HC != src) + HC.Disconnect(H) + + connected_holopad = H + + if(!Check()) + return + + hologram = H.activate_holo(user) + hologram.HC = src + + user.unset_machine(H) + //eyeobj code is horrid, this is the best copypasta I could make + eye = new() + eye.origin = H + eye.eye_initialized = TRUE + eye.eye_user = user + eye.name = "Camera Eye ([user.name])" + user.remote_control = eye + user.remote_view = 1 + user.reset_perspective(eye) + eye.setLoc(get_turf(H)) + + hangup = new(eye,src) + hangup.Grant(user) + +//Checks the validity of a holocall and qdels itself if it's not. Returns TRUE if valid, FALSE otherwise +/datum/holocall/proc/Check() + for(var/I in dialed_holopads) + var/obj/machinery/hologram/holopad/H = I + if((H.stat & NOPOWER)) + ConnectionFailure(H) + + if(QDELETED(src)) + return FALSE + + . = !QDELETED(user) && !user.incapacitated() && !QDELETED(calling_holopad) && !(calling_holopad.stat & NOPOWER) && user.loc == calling_holopad.loc + + if(.) + if(!connected_holopad) + . = world.time < (call_start_time + HOLOPAD_MAX_DIAL_TIME) + if(!.) + calling_holopad.atom_say("No answer received.") + calling_holopad.temp = "" + + else if(!.) + qdel(src) + +/datum/action/innate/end_holocall + name = "End Holocall" + button_icon_state = "camera_off" + var/datum/holocall/hcall + +/datum/action/innate/end_holocall/New(Target, datum/holocall/HC) + ..() + hcall = HC + +/datum/action/innate/end_holocall/Activate() + hcall.Disconnect(hcall.calling_holopad) diff --git a/code/datums/spell.dm b/code/datums/spell.dm index cc3b85bf94e..e46ad460490 100644 --- a/code/datums/spell.dm +++ b/code/datums/spell.dm @@ -171,10 +171,13 @@ var/list/spells = typesof(/obj/effect/proc_holder/spell) //needed for the badmin /obj/effect/proc_holder/spell/proc/invocation(mob/user = usr) //spelling the spell out and setting it on recharge/reducing charges amount switch(invocation_type) if("shout") - if(prob(50))//Auto-mute? Fuck that noise - user.say(invocation) + if(!user.IsVocal()) + user.emote("makes frantic gestures!") else - user.say(replacetext(invocation," ","`")) + if(prob(50))//Auto-mute? Fuck that noise + user.say(invocation) + else + user.say(replacetext(invocation," ","`")) if("whisper") if(prob(50)) user.whisper(invocation) diff --git a/code/datums/uplink_item.dm b/code/datums/uplink_item.dm index 956c19e055b..f1c4141720f 100644 --- a/code/datums/uplink_item.dm +++ b/code/datums/uplink_item.dm @@ -1339,7 +1339,7 @@ var/list/uplink_items = list() /datum/uplink_item/badass/rapid name = "Gloves of the North Star" - desc = "These gloves let the user punch people very fast. Does not improve weapon attack speed." + desc = "These gloves let the user punch people very fast. Does not improve weapon attack speed or the meaty fists of a hulk." reference = "RPGD" item = /obj/item/clothing/gloves/fingerless/rapid cost = 8 diff --git a/code/datums/wires/vending.dm b/code/datums/wires/vending.dm index 286ac454efc..054a7e4f669 100644 --- a/code/datums/wires/vending.dm +++ b/code/datums/wires/vending.dm @@ -1,5 +1,3 @@ -#define CAT_HIDDEN 2 // Also in code/game/machinery/vending.dm - /datum/wires/vending holder_type = /obj/machinery/vending wire_count = 4 diff --git a/code/defines/procs/admin.dm b/code/defines/procs/admin.dm index 0f2a2bd4393..cdf25ce9651 100644 --- a/code/defines/procs/admin.dm +++ b/code/defines/procs/admin.dm @@ -76,6 +76,10 @@ var/message = "[key_name(whom, 1)] [isLivingSSD(whom) ? "(SSD!)" : ""] ([admin_jump_link(whom)])" return message +/proc/key_name_log(whom) + // Key_name_admin, but does not include (?) or jump link - For logging purpose to reduce clutter while figuring out who is SSD and/or antag when being attacked. Also remove formatting since it is not displayed + var/message = "[key_name(whom, 0)][isAntag(whom) ? "(ANTAG)" : ""][isLivingSSD(whom) ? "(SSD!)": ""]" + return message /proc/log_and_message_admins(var/message as text) log_admin("[key_name(usr)] " + message) diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 19af319aa20..136c8950028 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -143,6 +143,12 @@ /atom/proc/setDir(newdir) dir = newdir +/atom/proc/attack_hulk(mob/living/carbon/human/user, does_attack_animation = FALSE) + if(does_attack_animation) + user.changeNext_move(CLICK_CD_MELEE) + add_attack_logs(user, src, "Punched with hulk powers") + user.do_attack_animation(src, ATTACK_EFFECT_SMASH) + /atom/proc/CheckParts(list/parts_list) for(var/A in parts_list) if(istype(A, /datum/reagent)) diff --git a/code/game/dna/genes/goon_powers.dm b/code/game/dna/genes/goon_powers.dm index 8517016e1a9..37292beb8fe 100644 --- a/code/game/dna/genes/goon_powers.dm +++ b/code/game/dna/genes/goon_powers.dm @@ -179,8 +179,7 @@ C.ExtinguishMob() C.visible_message("[user] sprays a cloud of fine ice crystals, engulfing [C]!") - log_attack(user, C, "Used cryokinesis on a victim without internals or a suit") - msg_admin_attack("[key_name_admin(user)] has cast cryokinesis on [key_name_admin(C)] (NO SUIT)") + add_attack_logs(user, C, "Cryokinesis- NO SUIT/INTERNALS") //playsound(user.loc, 'bamf.ogg', 50, 0) diff --git a/code/game/gamemodes/blob/theblob.dm b/code/game/gamemodes/blob/theblob.dm index e53a74c8daa..15a3b2e222f 100644 --- a/code/game/gamemodes/blob/theblob.dm +++ b/code/game/gamemodes/blob/theblob.dm @@ -147,6 +147,9 @@ ..() take_damage(power/400, BURN) +/obj/structure/blob/hulk_damage() + return 15 + /obj/structure/blob/attackby(var/obj/item/W, var/mob/living/user, params) user.changeNext_move(CLICK_CD_MELEE) user.do_attack_animation(src) diff --git a/code/game/gamemodes/changeling/powers/revive.dm b/code/game/gamemodes/changeling/powers/revive.dm index 23efc38b403..b3881ee54fb 100644 --- a/code/game/gamemodes/changeling/powers/revive.dm +++ b/code/game/gamemodes/changeling/powers/revive.dm @@ -24,13 +24,13 @@ user.CureNearsighted() user.reagents.clear_reagents() user.germ_level = 0 - user.next_pain_time = 0 user.timeofdeath = 0 if(ishuman(user)) var/mob/living/carbon/human/H = user H.restore_blood() H.traumatic_shock = 0 H.shock_stage = 0 + H.next_pain_time = 0 H.species.create_organs(H) // Now that recreating all organs is necessary, the rest of this organ stuff probably // isn't, but I don't want to remove it, just in case. diff --git a/code/game/gamemodes/cult/cult_structures.dm b/code/game/gamemodes/cult/cult_structures.dm index d8d7d03b6c4..84941f4d7a7 100644 --- a/code/game/gamemodes/cult/cult_structures.dm +++ b/code/game/gamemodes/cult/cult_structures.dm @@ -161,7 +161,7 @@ var/obj/item/organ/external/head/head = C.get_organ("head") if(head) C.apply_damage(30, BURN, "head") //30 fire damage because it's FUCKING LAVA - head.disfigure("burn") //Your face is unrecognizable because it's FUCKING LAVA + head.disfigure() //Your face is unrecognizable because it's FUCKING LAVA return 1 else ..() diff --git a/code/game/gamemodes/cult/runes.dm b/code/game/gamemodes/cult/runes.dm index e014fa07785..087bfbb4008 100644 --- a/code/game/gamemodes/cult/runes.dm +++ b/code/game/gamemodes/cult/runes.dm @@ -1,4 +1,4 @@ -/var/list/sacrificed = list() +var/list/sacrificed = list() var/list/non_revealed_runes = (subtypesof(/obj/effect/rune) - /obj/effect/rune/malformed) /* @@ -153,7 +153,10 @@ structure_check() searches for nearby cultist structures required for the invoca for(var/M in invokers) var/mob/living/L = M if(invocation) - L.say(invocation) + if(!L.IsVocal()) + L.emote("gestures ominously.") + else + L.say(invocation) L.changeNext_move(CLICK_CD_MELEE)//THIS IS WHY WE CAN'T HAVE NICE THINGS if(invoke_damage) L.apply_damage(invoke_damage, BRUTE) @@ -473,7 +476,6 @@ var/list/teleport_runes = list() rune_in_use = 0 - //Ritual of Dimensional Rending: Calls forth the avatar of Nar-Sie upon the station. /obj/effect/rune/narsie cultist_name = "Tear Reality (God)" @@ -875,7 +877,7 @@ var/list/teleport_runes = list() fail_invoke() log_game("Summon Cultist rune failed - target in away mission") return - if((cultist_to_summon.reagents.has_reagent("holywater") || cultist_to_summon.restrained()) && invokers < 3) + if((cultist_to_summon.reagents.has_reagent("holywater") || cultist_to_summon.restrained()) && invokers.len < 3) to_chat(user, "The summoning of [cultist_to_summon] is being blocked somehow! You need 3 chanters to counter it!") fail_invoke() new /obj/effect/temp_visual/cult/sparks(get_turf(cultist_to_summon)) //observer warning diff --git a/code/game/gamemodes/miniantags/revenant/revenant_abilities.dm b/code/game/gamemodes/miniantags/revenant/revenant_abilities.dm index baea323518e..5a7825c0cfe 100644 --- a/code/game/gamemodes/miniantags/revenant/revenant_abilities.dm +++ b/code/game/gamemodes/miniantags/revenant/revenant_abilities.dm @@ -263,8 +263,8 @@ new/obj/effect/temp_visual/revenant(T) T.ChangeTurf(/turf/simulated/wall/r_wall/rust) for(var/obj/structure/window/window in T.contents) - window.hit(rand(30,80)) - if(window && window.is_fulltile()) + window.take_damage(rand(30,80)) + if(window && window.fulltile) new/obj/effect/temp_visual/revenant/cracks(window.loc) for(var/obj/structure/closet/closet in T.contents) closet.open() diff --git a/code/game/gamemodes/shadowling/shadowling_abilities.dm b/code/game/gamemodes/shadowling/shadowling_abilities.dm index 6e9d5f7da8c..89aee290422 100644 --- a/code/game/gamemodes/shadowling/shadowling_abilities.dm +++ b/code/game/gamemodes/shadowling/shadowling_abilities.dm @@ -540,9 +540,7 @@ sp.start() S.Weaken(6) for(var/obj/structure/window/W in T.contents) - W.hit(rand(80, 100)) - - + W.take_damage(rand(80, 100)) /obj/effect/proc_holder/spell/aoe_turf/drainLife name = "Drain Life" diff --git a/code/game/gamemodes/vampire/vampire_powers.dm b/code/game/gamemodes/vampire/vampire_powers.dm index a2e8c2bf70d..c9dad5c510d 100644 --- a/code/game/gamemodes/vampire/vampire_powers.dm +++ b/code/game/gamemodes/vampire/vampire_powers.dm @@ -270,7 +270,7 @@ C.Stun(4) C.Jitter(150) for(var/obj/structure/window/W in view(4)) - W.destroy() + W.deconstruct(FALSE) playsound(user.loc, 'sound/effects/creepyshriek.ogg', 100, 1) diff --git a/code/game/jobs/job_controller.dm b/code/game/jobs/job_controller.dm index 61c14efc2e5..0e315e03b2c 100644 --- a/code/game/jobs/job_controller.dm +++ b/code/game/jobs/job_controller.dm @@ -1,10 +1,6 @@ var/global/datum/controller/occupations/job_master -#define GET_RANDOM_JOB 0 -#define BE_ASSISTANT 1 -#define RETURN_TO_LOBBY 2 - /datum/controller/occupations //List of all jobs var/list/occupations = list() diff --git a/code/game/machinery/OpTable.dm b/code/game/machinery/OpTable.dm index 3c9c27f1590..f7925fecda5 100644 --- a/code/game/machinery/OpTable.dm +++ b/code/game/machinery/OpTable.dm @@ -54,13 +54,12 @@ if(prob(75)) qdel(src) -/obj/machinery/optable/attack_hand(mob/user as mob) - if(HULK in usr.mutations) - to_chat(usr, text("You destroy the table.")) - visible_message("[usr] destroys the operating table!") - src.density = 0 +/obj/machinery/optable/attack_hulk(mob/living/carbon/human/user, does_attack_animation = FALSE) + if(user.a_intent == INTENT_HARM) + ..(user, TRUE) + visible_message("[user] destroys the operating table!") qdel(src) - return + return TRUE /obj/machinery/optable/CanPass(atom/movable/mover, turf/target, height=0) if(height==0) return 1 diff --git a/code/game/machinery/alarm.dm b/code/game/machinery/alarm.dm index f9d83ff43f6..f24197009bd 100644 --- a/code/game/machinery/alarm.dm +++ b/code/game/machinery/alarm.dm @@ -118,6 +118,8 @@ var/report_danger_level = 1 + var/automatic_emergency = 1 //Does the alarm automaticly respond to an emergency condition + /obj/machinery/alarm/monitor report_danger_level = 0 @@ -236,9 +238,11 @@ elect_master() /obj/machinery/alarm/proc/master_is_operating() - if(! alarm_area) + if(!alarm_area) alarm_area = areaMaster - + if(!alarm_area) + log_runtime(EXCEPTION("Air alarm /obj/machinery/alarm lacks alarm_area and areaMaster vars during proc/master_is_operating()"), src) + return FALSE return alarm_area.master_air_alarm && !(alarm_area.master_air_alarm.stat & (NOPOWER|BROKEN)) @@ -304,7 +308,7 @@ if(old_danger_level!=danger_level) apply_danger_level() - if(mode == AALARM_MODE_SCRUBBING && danger_level == ATMOS_ALARM_DANGER) + if(automatic_emergency && mode == AALARM_MODE_SCRUBBING && danger_level == ATMOS_ALARM_DANGER) if(pressure_dangerlevel == ATMOS_ALARM_DANGER) mode = AALARM_MODE_OFF if(temperature_dangerlevel == ATMOS_ALARM_DANGER && cur_tlv.max2 <= environment.temperature) diff --git a/code/game/machinery/computer/camera_advanced.dm b/code/game/machinery/computer/camera_advanced.dm index 2195ee25522..00f6a98f2bc 100644 --- a/code/game/machinery/computer/camera_advanced.dm +++ b/code/game/machinery/computer/camera_advanced.dm @@ -8,16 +8,39 @@ var/list/networks = list("SS13") var/datum/action/innate/camera_off/off_action = new var/datum/action/innate/camera_jump/jump_action = new + var/list/actions = list() /obj/machinery/computer/camera_advanced/proc/CreateEye() eyeobj = new() eyeobj.origin = src -/obj/machinery/computer/camera_advanced/proc/GrantActions(mob/living/carbon/user) - off_action.target = user - off_action.Grant(user) - jump_action.target = user - jump_action.Grant(user) +/obj/machinery/computer/camera_advanced/proc/GrantActions(mob/living/user) + if(off_action) + off_action.target = user + off_action.Grant(user) + actions += off_action + + if(jump_action) + jump_action.target = user + jump_action.Grant(user) + actions += jump_action + +/obj/machinery/computer/camera_advanced/proc/remove_eye_control(mob/living/user) + if(!user) + return + for(var/V in actions) + var/datum/action/A = V + A.Remove(user) + if(user.client) + user.reset_perspective(null) + eyeobj.RemoveImages() + eyeobj.eye_user = null + user.remote_control = null + user.remote_view = FALSE + + current_user = null + user.unset_machine() + playsound(src, 'sound/machines/terminal_off.ogg', 25, 0) /obj/machinery/computer/camera_advanced/check_eye(mob/user) if((stat & (NOPOWER|BROKEN)) || !Adjacent(user) || !user.has_vision() || user.incapacitated()) @@ -33,7 +56,7 @@ /obj/machinery/computer/camera_advanced/on_unset_machine(mob/M) if(M == current_user) - off_action.Activate() + remove_eye_control(M) /obj/machinery/computer/camera_advanced/attack_hand(mob/user) if(current_user) @@ -95,6 +118,13 @@ origin = null return ..() +/mob/camera/aiEye/remote/RemoveImages() + ..() + if(visible_icon) + var/client/C = GetViewerClient() + if(C) + C.images -= user_image + /mob/camera/aiEye/remote/GetViewerClient() if(eye_user) return eye_user.client @@ -140,20 +170,8 @@ return var/mob/living/carbon/C = target var/mob/camera/aiEye/remote/remote_eye = C.remote_control - C.remote_view = 0 - remote_eye.origin.current_user = null - remote_eye.origin.jump_action.Remove(C) - remote_eye.eye_user = null - if(C.client) - C.reset_perspective(null) - if(remote_eye.visible_icon) - C.client.images -= remote_eye.user_image - for(var/datum/camerachunk/chunk in remote_eye.visibleCameraChunks) - C.client.images -= chunk.obscured - C.remote_control = null - C.unset_machine() - src.Remove(C) - playsound(remote_eye.origin, 'sound/machines/terminal_off.ogg', 25, 0) + var/obj/machinery/computer/camera_advanced/console = remote_eye.origin + console.remove_eye_control(target) /datum/action/innate/camera_jump name = "Jump To Camera" diff --git a/code/game/machinery/computer/hologram.dm b/code/game/machinery/computer/hologram.dm deleted file mode 100644 index 2d2e5d37ae0..00000000000 --- a/code/game/machinery/computer/hologram.dm +++ /dev/null @@ -1,118 +0,0 @@ -/obj/machinery/computer/hologram_comp - name = "hologram computer" - desc = "Rumoured to control holograms." - icon = 'icons/obj/stationobjs.dmi' - icon_keyboard = "tech_key" - icon_screen = "holocontrol" - var/obj/machinery/hologram/projector/projector = null - var/temp = null - var/lumens = 0.0 - var/h_r = 245.0 - var/h_g = 245.0 - var/h_b = 245.0 - - -/obj/machinery/computer/hologram_comp/New() - ..() - spawn( 10 ) - src.projector = locate(/obj/machinery/hologram/projector, get_step(src.loc, NORTH)) - return - return - -/obj/machinery/computer/hologram_comp/attack_hand() - if(!in_range(src, usr)) - return 0 - src.show_console(usr) - return - -/obj/machinery/computer/hologram_comp/proc/render() - var/icon/I = new /icon('icons/mob/human.dmi', "body_m_s") - - if(src.lumens >= 0) - I.Blend(rgb(src.lumens, src.lumens, src.lumens), ICON_ADD) - else - I.Blend(rgb(- src.lumens, -src.lumens, -src.lumens), ICON_SUBTRACT) - - I.Blend(new /icon('icons/mob/human.dmi', "mouth_m_s"), ICON_OVERLAY) - I.Blend(new /icon('icons/mob/underwear.dmi', "Mens White"), ICON_OVERLAY) - - var/icon/U = new /icon('icons/mob/human_face.dmi', "hair_a_s") - U.Blend(rgb(src.h_r, src.h_g, src.h_b), ICON_ADD) - - I.Blend(U, ICON_OVERLAY) - - src.projector.hologram.icon = I - -/obj/machinery/computer/hologram_comp/proc/show_console(var/mob/user as mob) - var/dat - user.set_machine(src) - if(src.temp) - dat = text("[]

Clear", src.temp) - else - dat = text({"Hologram Status:
\n - Power: []
\n - Hologram Control:
\n - Color Luminosity: []/220 \[Reset\]
\n - Lighten: 1 10
\n - Darken: 1 10
\n -
\nHair Color: ([],[],[]) \[Reset\]
\n - Red (0-255): \[0\] -10 -1 [] 1 10 \[255\]
\n - Green (0-255): \[0\] -10 -1 [] 1 10 \[255\]
\n - Blue (0-255): \[0\] -10 -1 [] 1 10 \[255\]
- "}, (src.projector.hologram ? "On" : "Off"), -src.lumens + 35, src.h_r, src.h_g, src.h_b, src.h_r, src.h_g, src.h_b) - user << browse(dat, "window=hologram_console") - onclose(user, "hologram_console") - return - -/obj/machinery/computer/hologram_comp/Topic(href, href_list) - if(..()) - return 1 - if(in_range(src, usr)) - flick("holo_console1", src) - if(href_list["power"]) - if(src.projector.hologram) - src.projector.icon_state = "hologram0" - //src.projector.hologram = null - qdel(src.projector.hologram) - else - src.projector.hologram = new(src.projector.loc) - src.projector.hologram.icon = 'icons/mob/human.dmi' - src.projector.hologram.icon_state = "body_m_s" - src.projector.icon_state = "hologram1" - src.render() - else - if(href_list["h_r"]) - if(src.projector.hologram) - src.h_r += text2num(href_list["h_r"]) - src.h_r = min(max(src.h_r, 0), 255) - render() - else - if(href_list["h_g"]) - if(src.projector.hologram) - src.h_g += text2num(href_list["h_g"]) - src.h_g = min(max(src.h_g, 0), 255) - render() - else - if(href_list["h_b"]) - if(src.projector.hologram) - src.h_b += text2num(href_list["h_b"]) - src.h_b = min(max(src.h_b, 0), 255) - render() - else - if(href_list["light"]) - if(src.projector.hologram) - src.lumens += text2num(href_list["light"]) - src.lumens = min(max(src.lumens, -185.0), 35) - render() - else - if(href_list["reset"]) - if(src.projector.hologram) - src.lumens = 0 - render() - else - if(href_list["temp"]) - src.temp = null - for(var/mob/M in viewers(1, src)) - if((M.client && M.machine == src)) - src.show_console(M) - return diff --git a/code/game/machinery/doors/airlock_electronics.dm b/code/game/machinery/doors/airlock_electronics.dm index 678e29d3ae0..db508b9288f 100644 --- a/code/game/machinery/doors/airlock_electronics.dm +++ b/code/game/machinery/doors/airlock_electronics.dm @@ -10,8 +10,6 @@ usesound = 'sound/items/Deconstruct.ogg' var/list/conf_access = null var/one_access = 0 //if set to 1, door would receive req_one_access instead of req_access - var/last_configurator = null - var/locked = TRUE var/const/max_brain_damage = 60 // Maximum brain damage a mob can have until it can't use the electronics /obj/item/airlock_electronics/attack_self(mob/user) @@ -26,31 +24,23 @@ var/t1 = text("Access control
\n") - if(last_configurator) - t1 += "Operator: [last_configurator]
" + t1 += "Access requirement is set to " + t1 += one_access ? "ONE
" : "ALL
" - if(locked) - t1 += "Swipe ID
" - else - t1 += "Block
" + t1 += conf_access == null ? "All
" : "All
" - t1 += "Access requirement is set to " - t1 += one_access ? "ONE
" : "ALL
" + t1 += "
" - t1 += conf_access == null ? "All
" : "All
" + var/list/accesses = get_all_accesses() + for(var/acc in accesses) + var/aname = get_access_desc(acc) - t1 += "
" - - var/list/accesses = get_all_accesses() - for(var/acc in accesses) - var/aname = get_access_desc(acc) - - if(!conf_access || !conf_access.len || !(acc in conf_access)) - t1 += "[aname]
" - else if(one_access) - t1 += "[aname]
" - else - t1 += "[aname]
" + if(!conf_access || !conf_access.len || !(acc in conf_access)) + t1 += "[aname]
" + else if(one_access) + t1 += "[aname]
" + else + t1 += "[aname]
" t1 += "

Close

\n" @@ -66,20 +56,9 @@ return 1 if(href_list["close"]) - usr << browse(null, "window=airlock") + usr << browse(null, "window=airlock_electronics") return - if(href_list["login"]) - if(allowed(usr)) - locked = FALSE - last_configurator = usr.name - - if(locked) - return - - if(href_list["logout"]) - locked = TRUE - if(href_list["one_access"]) one_access = !one_access diff --git a/code/game/machinery/doors/windowdoor.dm b/code/game/machinery/doors/windowdoor.dm index 181e273dd43..1ab22f341b6 100644 --- a/code/game/machinery/doors/windowdoor.dm +++ b/code/game/machinery/doors/windowdoor.dm @@ -16,17 +16,20 @@ var/obj/item/airlock_electronics/electronics var/base_state = "left" var/reinf = 0 + var/cancolor = TRUE var/shards = 2 var/rods = 2 var/cable = 1 var/list/debris = list() -/obj/machinery/door/window/New() +/obj/machinery/door/window/New(loc, set_dir) ..() + if(set_dir) + setDir(set_dir) if(req_access && req_access.len) icon_state = "[icon_state]" base_state = icon_state - if(!color) + if(!color && cancolor) color = color_windows(src) for(var/i in 1 to shards) debris += new /obj/item/shard(src) @@ -97,6 +100,16 @@ return 1 if(get_dir(loc, target) == dir) //Make sure looking at appropriate border return !density + if(istype(mover, /obj/structure/window)) + var/obj/structure/window/W = mover + if(!valid_window_location(loc, W.ini_dir)) + return FALSE + else if(istype(mover, /obj/structure/windoor_assembly)) + var/obj/structure/windoor_assembly/W = mover + if(!valid_window_location(loc, W.ini_dir)) + return FALSE + else if(istype(mover, /obj/machinery/door/window) && !valid_window_location(loc, mover.dir)) + return FALSE else return 1 @@ -128,7 +141,7 @@ if(emagged) return 0 if(!operating) //in case of emag - operating = 1 + operating = TRUE do_animate("opening") playsound(loc, 'sound/machines/windowdoor.ogg', 100, 1) icon_state ="[base_state]open" @@ -152,7 +165,7 @@ if(forced < 2) if(emagged) return 0 - operating = 1 + operating = TRUE do_animate("closing") playsound(loc, 'sound/machines/windowdoor.ogg', 100, 1) icon_state = base_state @@ -186,6 +199,11 @@ /obj/machinery/door/window/narsie_act() color = NARSIE_WINDOW_COLOUR +/obj/machinery/door/window/ratvar_act() + var/obj/machinery/door/window/clockwork/C = new(loc, dir) + C.name = name + qdel(src) + /obj/machinery/door/window/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) if(exposed_temperature > T0C + (reinf ? 1600 : 800)) take_damage(round(exposed_volume / 200), BURN, 0, 0) @@ -204,7 +222,7 @@ /obj/machinery/door/window/emag_act(mob/user, obj/weapon) if(!operating && density && !emagged) emagged = TRUE - operating = 1 + operating = TRUE flick("[base_state]spark", src) playsound(src, "sparks", 75, 1) sleep(6) @@ -314,6 +332,45 @@ desc = "For keeping in criminal scum." req_access = list(access_brig) +/obj/machinery/door/window/clockwork + name = "brass windoor" + desc = "A thin door with translucent brass paneling." + icon_state = "clockwork" + base_state = "clockwork" + shards = 0 + rods = 0 + burn_state = FIRE_PROOF + cancolor = FALSE + var/made_glow = FALSE + +/obj/machinery/door/window/clockwork/New(loc, set_dir) + ..() + debris += new/obj/item/stack/tile/brass(src, 2) + +/obj/machinery/door/window/clockwork/setDir(direct) + if(!made_glow) + var/obj/effect/E = new /obj/effect/temp_visual/ratvar/door/window(get_turf(src)) + E.setDir(direct) + made_glow = TRUE + ..() + +/obj/machinery/door/window/clockwork/emp_act(severity) + if(prob(80/severity)) + open() + +/obj/machinery/door/window/clockwork/ratvar_act() + obj_integrity = max_integrity + +/obj/machinery/door/window/clockwork/hasPower() + return TRUE //yup that's power all right + +/obj/machinery/door/window/clockwork/narsie_act() + take_damage(rand(30, 60), BRUTE) + if(src) + var/previouscolor = color + color = "#960000" + animate(src, color = previouscolor, time = 8) + /obj/machinery/door/window/northleft dir = NORTH diff --git a/code/game/machinery/hologram.dm b/code/game/machinery/hologram.dm index 58404b133bd..0fc532ab0e4 100644 --- a/code/game/machinery/hologram.dm +++ b/code/game/machinery/hologram.dm @@ -1,7 +1,7 @@ -/* Holograms! +/* holograms! * Contains: * Holopad - * Hologram + * hologram * Other stuff */ @@ -9,11 +9,10 @@ Revised. Original based on space ninja hologram code. Which is also mine. /N How it works: AI clicks on holopad in camera view. View centers on holopad. -AI clicks again on the holopad to display a hologram. Hologram stays as long as AI is looking at the pad and it (the hologram) is in range of the pad. +AI clicks again on the holopad to display a hologram. hologram stays as long as AI is looking at the pad and it (the hologram) is in range of the pad. AI can use the directional keys to move the hologram around, provided the above conditions are met and the AI in question is the holopad's master. Only one AI may project from a holopad at any given time. AI may cancel the hologram at any time by clicking on the holopad once more. - Possible to do for anyone motivated enough: Give an AI variable for different hologram icons. Itegrate EMP effect to disable the unit. @@ -27,19 +26,35 @@ Possible to do for anyone motivated enough: // HOLOPAD MODE // 0 = RANGE BASED // 1 = AREA BASED -var/const/HOLOPAD_MODE = 0 +#define HOLOPAD_PASSIVE_POWER_USAGE 1 +#define HOLOGRAM_POWER_USAGE 2 +#define RANGE_BASED 0 +#define AREA_BASED 1 + +var/const/HOLOPAD_MODE = RANGE_BASED + var/list/holopads = list() /obj/machinery/hologram/holopad - name = "\improper AI holopad" - desc = "It's a floor-mounted device for projecting holographic images. It is activated remotely." + name = "holopad" + desc = "It's a floor-mounted device for projecting holographic images." icon_state = "holopad0" - + anchored = 1 + use_power = 1 + idle_power_usage = 5 + active_power_usage = 100 layer = TURF_LAYER+0.1 //Preventing mice and drones from sneaking under them. armor = list(melee = 50, bullet = 20, laser = 20, energy = 20, bomb = 0, bio = 0, rad = 0) - var/mob/living/silicon/ai/master//Which AI, if any, is controlling the object? Only one AI may control a hologram at any time. + var/list/masters = list()//List of living mobs that use the holopad + var/list/holorays = list()//Holoray-mob link. var/last_request = 0 //to prevent request spam. ~Carn var/holo_range = 5 // Change to change how far the AI can move away from the holopad before deactivating. + var/temp = "" + var/list/holo_calls //array of /datum/holocalls + var/datum/holocall/outgoing_call //do not modify the datums only check and call the public procs + var/static/force_answer_call = FALSE //Calls will be automatically answered after a couple rings, here for debugging + var/obj/effect/overlay/holoray/ray + var/ringing = FALSE /obj/machinery/hologram/holopad/New() ..() @@ -49,6 +64,27 @@ var/list/holopads = list() component_parts += new /obj/item/stock_parts/capacitor(null) RefreshParts() +/obj/machinery/hologram/holopad/Destroy() + if(outgoing_call) + outgoing_call.ConnectionFailure(src) + + for(var/I in holo_calls) + var/datum/holocall/HC = I + HC.ConnectionFailure(src) + + for(var/I in masters) + clear_holo(I) + holopads -= src + return ..() + +/obj/machinery/hologram/holopad/power_change() + if(powered()) + stat &= ~NOPOWER + else + stat |= NOPOWER + if(outgoing_call) + outgoing_call.ConnectionFailure(src) + /obj/machinery/hologram/holopad/RefreshParts() var/holograph_range = 4 for(var/obj/item/stock_parts/capacitor/B in component_parts) @@ -68,197 +104,383 @@ var/list/holopads = list() default_deconstruction_crowbar(P) -/obj/machinery/hologram/holopad/attack_hand(var/mob/living/carbon/human/user) //Carn: Hologram requests. +/obj/machinery/hologram/holopad/attack_hand(mob/living/carbon/human/user) + if(..()) + return + + if(outgoing_call) + return + + user.set_machine(src) + interact(user) + +/obj/machinery/hologram/holopad/AltClick(mob/living/carbon/human/user) + if(..()) + return + if(isAI(user)) + hangup_all_calls() + return + +//Stop ringing the AI!! +/obj/machinery/hologram/holopad/proc/hangup_all_calls() + for(var/I in holo_calls) + var/datum/holocall/HC = I + HC.Disconnect(src) + +/obj/machinery/hologram/holopad/interact(mob/living/carbon/human/user) //Carn: hologram requests. if(!istype(user)) return - if(alert(user,"Would you like to request an AI's presence?",,"Yes","No") == "Yes") - if(last_request + 200 < world.time) //don't spam the AI with requests you jerk! - last_request = world.time - to_chat(user, "You request an AI's presence.") - var/area/area = get_area(src) - for(var/mob/living/silicon/ai/AI in living_mob_list) - if(!AI.client) continue - to_chat(AI, "Your presence is requested at \the [area].") - else - to_chat(user, "A request for AI presence was already sent recently.") + var/dat + if(temp) + dat = temp + else + dat = "Request an AI's presence.
" + dat += "Call another holopad.
" + + if(LAZYLEN(holo_calls)) + dat += "=====================================================
" + + var/one_answered_call = FALSE + var/one_unanswered_call = FALSE + for(var/I in holo_calls) + var/datum/holocall/HC = I + if(HC.connected_holopad != src) + dat += "Answer call from [get_area(HC.calling_holopad)].
" + one_unanswered_call = TRUE + else + one_answered_call = TRUE + + if(one_answered_call && one_unanswered_call) + dat += "=====================================================
" + //we loop twice for formatting + for(var/I in holo_calls) + var/datum/holocall/HC = I + if(HC.connected_holopad == src) + dat += "Disconnect call from [HC.user].
" + + var/area/area = get_area(src) + var/datum/browser/popup = new(user, "holopad", "[area] holopad", 400, 300) + popup.set_content(dat) + popup.set_title_image(user.browse_rsc_icon(icon, icon_state)) + popup.open() + +/obj/machinery/hologram/holopad/Topic(href, href_list) + if(..() || isAI(usr)) + return + add_fingerprint(usr) + if(stat & NOPOWER) + return + if(href_list["AIrequest"]) + if(last_request + 200 < world.time) + last_request = world.time + temp = "You requested an AI's presence.
" + temp += "Main Menu" + var/area/area = get_area(src) + for(var/mob/living/silicon/ai/AI in ai_list) + if(!AI.client) + continue + to_chat(AI, "Your presence is requested at \the [area].") + else + temp = "A request for AI presence was already sent recently.
" + temp += "Main Menu" + + else if(href_list["Holocall"]) + if(outgoing_call) + return + + temp = "You must stand on the holopad to make a call!
" + temp += "Main Menu" + if(usr.loc == loc) + var/list/callnames = list() + for(var/I in holopads) + var/area/A = get_area(I) + if(A) + LAZYADD(callnames[A], I) + callnames -= get_area(src) + + var/result = input(usr, "Choose an area to call", "Holocall") as null|anything in callnames + + if(QDELETED(usr) || !result || outgoing_call) + return + + if(usr.loc == loc) + temp = "Dialing...
" + temp += "Main Menu" + new /datum/holocall(usr, src, callnames[result]) + + else if(href_list["connectcall"]) + var/datum/holocall/call_to_connect = locateUID(href_list["connectcall"]) + if(!QDELETED(call_to_connect) && (call_to_connect in holo_calls)) + call_to_connect.Answer(src) + temp = "" + + else if(href_list["disconnectcall"]) + var/datum/holocall/call_to_disconnect = locateUID(href_list["disconnectcall"]) + if(!QDELETED(call_to_disconnect)) + call_to_disconnect.Disconnect(src) + temp = "" + + else if(href_list["mainmenu"]) + temp = "" + if(outgoing_call) + outgoing_call.Disconnect() + + updateDialog() + +//do not allow AIs to answer calls or people will use it to meta the AI satellite /obj/machinery/hologram/holopad/attack_ai(mob/living/silicon/ai/user) if(!istype(user)) return + if(outgoing_call) + return /*There are pretty much only three ways to interact here. I don't need to check for client since they're clicking on an object. This may change in the future but for now will suffice.*/ - if(user.eyeobj.loc != src.loc)//Set client eye on the object if it's not already. + if(user.eyeobj.loc != loc)//Set client eye on the object if it's not already. user.eyeobj.setLoc(get_turf(src)) - else if(!hologram)//If there is no hologram, possibly make one. - activate_holo(user, 0) - else if(master == user)//If there is a hologram, remove it. But only if the user is the master. Otherwise do nothing. - clear_holo() - return + else if(!LAZYLEN(masters) || !masters[user])//If there is no hologram, possibly make one. + activate_holo(user, 1) + else//If there is a hologram, remove it. + clear_holo(user) -/obj/machinery/hologram/holopad/proc/activate_holo(mob/living/silicon/ai/user, var/force = 0) - if(!force && user.eyeobj.loc != src.loc) // allows holopads to pass off holograms to the next holopad in the chain +/obj/machinery/hologram/holopad/process() + for(var/I in masters) + var/mob/living/master = I + if((stat & NOPOWER) || !validate_user(master)) + clear_holo(master) + + if(outgoing_call) + outgoing_call.Check() + + ringing = FALSE + + for(var/I in holo_calls) + var/datum/holocall/HC = I + //Sanity check and skip if no longer valid call + if(!HC.Check()) + atom_say("Call was terminated at remote terminal.") + continue + + if(HC.connected_holopad != src) + if(force_answer_call && world.time > (HC.call_start_time + (HOLOPAD_MAX_DIAL_TIME / 2))) + HC.Answer(src) + break + if(outgoing_call) + HC.Disconnect(src)//can't answer calls while calling + else + playsound(src, 'sound/machines/twobeep.ogg', 100) //bring, bring! + ringing = TRUE + + update_icon() + + +//Try to transfer hologram to another pad that can project on T +/obj/machinery/hologram/holopad/proc/transfer_to_nearby_pad(turf/T, mob/holo_owner) + if(!isAI(holo_owner)) + return + for(var/pad in holopads) + var/obj/machinery/hologram/holopad/another = pad + if(another == src) + continue + if(another.validate_location(T)) + var/obj/effect/overlay/holo_pad_hologram/h = masters[holo_owner] + unset_holo(holo_owner) + another.set_holo(holo_owner, h) + return TRUE + return FALSE + +/obj/machinery/hologram/holopad/proc/validate_user(mob/living/user) + if(QDELETED(user) || user.incapacitated() || !user.client) + return FALSE + + if(istype(user, /mob/living/silicon/ai)) + var/mob/living/silicon/ai/AI = user + if(!AI.current) + return FALSE + return TRUE + +//Can we display holos there +//Area check instead of line of sight check because this is a called a lot if AI wants to move around. +/obj/machinery/hologram/holopad/proc/validate_location(turf/T,check_los = FALSE) + if(T.z == z && get_dist(T, src) <= holo_range && T.loc == get_area(src)) + return TRUE + return FALSE + + +/obj/machinery/hologram/holopad/proc/move_hologram(mob/living/user, turf/new_turf) + if(masters[user]) + var/obj/effect/overlay/holo_pad_hologram/holo = masters[user] + var/transfered = FALSE + if(!validate_location(new_turf)) + if(!transfer_to_nearby_pad(new_turf,user)) + clear_holo(user) + return FALSE + else + transfered = TRUE + //All is good. + holo.setDir(get_dir(holo.loc, new_turf)) + holo.forceMove(new_turf) + if(!transfered) + update_holoray(user,new_turf) + return TRUE + +/obj/machinery/hologram/holopad/proc/activate_holo(mob/living/user, var/force = 0) + var/mob/living/silicon/ai/AI = user + if(!istype(AI)) + AI = null + if(AI && !force && AI.eyeobj.loc != loc) // allows holopads to pass off holograms to the next holopad in the chain to_chat(user, "ERROR: Unable to project hologram.") - else if(!(stat & NOPOWER))//If the projector has power - if(user.holo) - var/obj/machinery/hologram/holopad/current = user.holo - current.clear_holo() - if(!hologram)//If there is not already a hologram. - create_holo(user)//Create one. - src.visible_message("A holographic image of [user] flicks to life right before your eyes!") - else - to_chat(user, "ERROR: Image feed in progress.") - else - to_chat(user, "ERROR: Unable to project hologram.") - return + if(!(stat & NOPOWER) && (!AI || force)) + if(AI && (istype(AI.current, /obj/machinery/hologram/holopad))) + to_chat(user, "ERROR: Image feed in progress.") + return + + var/obj/effect/overlay/holo_pad_hologram/hologram = new(loc)//Spawn a blank effect at the location. + if(isAI(user)) + hologram.icon = AI.holo_icon + else //make it like real life + hologram.icon = getHologramIcon(get_id_photo(user)) + hologram.icon_state = user.icon_state + hologram.alpha = 100 + hologram.Impersonation = user + + hologram.mouse_opacity = 0//So you can't click on it. + hologram.layer = FLY_LAYER//Above all the other objects/mobs. Or the vast majority of them. + hologram.anchored = 1//So space wind cannot drag it. + hologram.name = "[user.name] (hologram)"//If someone decides to right click. + hologram.set_light(2) //hologram lighting + move_hologram() + + set_holo(user, hologram) + + if(!masters[user])//If there is not already a hologram. + visible_message("A holographic image of [user] flicks to life right before your eyes!") + + return hologram + + + to_chat(user, "ERROR: Hologram Projection Malfunction.") + clear_holo(user)//safety check /*This is the proc for special two-way communication between AI and holopad/people talking near holopad. For the other part of the code, check silicon say.dm. Particularly robot talk.*/ -/obj/machinery/hologram/holopad/hear_talk(mob/living/M, text, verb, datum/language/speaking) - if(M && hologram && master)//Master is mostly a safety in case lag hits or something. - master.relay_speech(M, text, verb, speaking) +/obj/machinery/hologram/holopad/hear_talk(atom/movable/speaker, message, verb, datum/language/message_language) + if(speaker && masters.len)//Master is mostly a safety in case lag hits or something. Radio_freq so AIs dont hear holopad stuff through radios. + for(var/mob/living/silicon/ai/master in masters) + if(masters[master] && speaker != master) + master.relay_speech(speaker, message, verb, message_language) -/obj/machinery/hologram/holopad/hear_message(mob/living/M, text) - if(M&&hologram&&master)//Master is mostly a safety in case lag hits or something. - var/name_used = M.GetVoice() - var/rendered = "Holopad received, [name_used] [text]" - master.show_message(rendered, 2) - return + for(var/I in holo_calls) + var/datum/holocall/HC = I + if(HC.connected_holopad == src && speaker != HC.hologram) + HC.user.hear_say(message, verb, message_language, speaker = speaker) -/obj/machinery/hologram/holopad/proc/create_holo(mob/living/silicon/ai/A, turf/T = loc) - hologram = new(T)//Spawn a blank effect at the location. - hologram.icon = A.holo_icon - hologram.mouse_opacity = 0//So you can't click on it. - hologram.layer = FLY_LAYER//Above all the other objects/mobs. Or the vast majority of them. - hologram.anchored = 1//So space wind cannot drag it. - hologram.name = "[A.name] (Hologram)"//If someone decides to right click. - hologram.set_light(2) //hologram lighting - set_light(2) //pad lighting - icon_state = "holopad1" - A.holo = src - master = A//AI is the master. - use_power = 2//Active power usage. - return 1 + if(outgoing_call && speaker == outgoing_call.user) + outgoing_call.hologram.atom_say(message) -/obj/machinery/hologram/holopad/proc/clear_holo() -// hologram.set_light(0)//Clear lighting. //handled by the lighting controller when its ower is deleted - QDEL_NULL(hologram)//Get rid of hologram. - if(master.holo == src) - master.holo = null - master = null//Null the master, since no-one is using it now. - set_light(0) //pad lighting (hologram lighting will be handled automatically since its owner was deleted) - icon_state = "holopad0" - use_power = 1//Passive power usage. - return 1 -/obj/machinery/hologram/holopad/process() - if(hologram)//If there is a hologram. - if(master && !master.stat && master.client && master.eyeobj)//If there is an AI attached, it's not incapacitated, it has a client, and the client eye is centered on the projector. - if(!(stat & NOPOWER))//If the machine has power. - if((HOLOPAD_MODE == 0 && (get_dist(master.eyeobj, src) <= holo_range))) - return 1 - else if(HOLOPAD_MODE == 1) - - var/area/holo_area = get_area(src) - var/area/eye_area = get_area(master.eyeobj) - - if(eye_area != holo_area) - return 1 - - var/mob/living/silicon/ai/theai = master - var/turf/target_turf = get_turf(master.eyeobj) - var/newdir = hologram.dir - clear_holo()//If not, we want to get rid of the hologram. - var/obj/machinery/hologram/holopad/pad_close = get_closest_atom(/obj/machinery/hologram/holopad, holopads, theai.eyeobj) - if(get_dist(pad_close, theai.eyeobj) <= pad_close.holo_range) - if(!(pad_close.stat & NOPOWER) && !pad_close.hologram && (theai && !theai.stat && theai.client)) - pad_close.activate_holo(theai, 1) - if(pad_close.hologram) - pad_close.hologram.forceMove(target_turf) - pad_close.hologram.dir = newdir - return 1 - -/obj/machinery/hologram/holopad/proc/move_hologram() - if(hologram) - step_to(hologram, master.eyeobj) // So it turns. - hologram.loc = get_turf(master.eyeobj) - - return 1 - -// Simple helper to face what you clicked on, in case it should be needed in more than one place -/obj/machinery/hologram/holopad/proc/face_atom(var/atom/A) - if( !hologram || !A || !hologram.x || !hologram.y || !A.x || !A.y ) return - var/dx = A.x - hologram.x - var/dy = A.y - hologram.y - if(!dx && !dy) // Wall items are graphically shifted but on the floor - if(A.pixel_y > 16) hologram.dir = NORTH - else if(A.pixel_y < -16)hologram.dir = SOUTH - else if(A.pixel_x > 16) hologram.dir = EAST - else if(A.pixel_x < -16)hologram.dir = WEST - return - - if(abs(dx) < abs(dy)) - if(dy > 0) hologram.dir = NORTH - else hologram.dir = SOUTH +/obj/machinery/hologram/holopad/proc/SetLightsAndPower() + var/total_users = masters.len + LAZYLEN(holo_calls) + use_power = HOLOPAD_PASSIVE_POWER_USAGE + HOLOGRAM_POWER_USAGE * total_users + if(total_users) + set_light(2) + icon_state = "holopad1" else - if(dx > 0) hologram.dir = EAST - else hologram.dir = WEST + set_light(0) + icon_state = "holopad0" + update_icon() -/* - * Hologram - */ +/obj/machinery/hologram/holopad/update_icon() + var/total_users = LAZYLEN(masters) + LAZYLEN(holo_calls) + if(ringing) + icon_state = "holopad_ringing" + else if(total_users) + icon_state = "holopad1" + else + icon_state = "holopad0" -/obj/machinery/hologram - anchored = 1 - use_power = 1 - idle_power_usage = 5 - active_power_usage = 100 - var/obj/effect/overlay/hologram//The projection itself. If there is one, the instrument is on, off otherwise. -//Destruction procs. -/obj/machinery/hologram/ex_act(severity) - switch(severity) - if(1.0) - qdel(src) - if(2.0) - if(prob(50)) - qdel(src) - if(3.0) - if(prob(5)) - qdel(src) - return +/obj/machinery/hologram/holopad/proc/set_holo(mob/living/user, var/obj/effect/overlay/holo_pad_hologram/h) + masters[user] = h + holorays[user] = new /obj/effect/overlay/holoray(loc) + var/mob/living/silicon/ai/AI = user + if(istype(AI)) + AI.current = src + SetLightsAndPower() + update_holoray(user, get_turf(loc)) + return TRUE -/obj/machinery/hologram/blob_act() - qdel(src) - return +/obj/machinery/hologram/holopad/proc/clear_holo(mob/living/user) + qdel(masters[user]) // Get rid of user's hologram + unset_holo(user) + return TRUE -/obj/machinery/hologram/holopad/Destroy() - holopads -= src - if(hologram) - clear_holo() +/obj/machinery/hologram/holopad/proc/unset_holo(mob/living/user) + var/mob/living/silicon/ai/AI = user + if(istype(AI) && AI.current == src) + AI.current = null + masters -= user // Discard AI from the list of those who use holopad + qdel(holorays[user]) + holorays -= user + SetLightsAndPower() + return TRUE + +/obj/machinery/hologram/holopad/proc/update_holoray(mob/living/user, turf/new_turf) + var/obj/effect/overlay/holo_pad_hologram/holo = masters[user] + var/obj/effect/overlay/holoray/ray = holorays[user] + var/disty = holo.y - ray.y + var/distx = holo.x - ray.x + var/newangle + if(!disty) + if(distx >= 0) + newangle = 90 + else + newangle = 270 + else + newangle = arctan(distx/disty) + if(disty < 0) + newangle += 180 + else if(distx < 0) + newangle += 360 + var/matrix/M = matrix() + if(get_dist(get_turf(holo), new_turf) <= 1) + animate(ray, transform = turn(M.Scale(1, sqrt(distx*distx+disty*disty)), newangle), time = 1) + else + ray.transform = turn(M.Scale(1, sqrt(distx*distx+disty*disty)), newangle) + + +/obj/effect/overlay/holo_pad_hologram + var/mob/living/Impersonation + var/datum/holocall/HC + +/obj/effect/overlay/holo_pad_hologram/Destroy() + Impersonation = null + if(!QDELETED(HC)) + HC.Disconnect(HC.calling_holopad) return ..() -/* -Holographic project of everything else. +/obj/effect/overlay/holo_pad_hologram/Process_Spacemove(movement_dir = 0) + return 1 -/mob/verb/hologram_test() - set name = "Hologram Debug New" - set category = "CURRENT DEBUG" +/obj/effect/overlay/holo_pad_hologram/examine(mob/user) + if(Impersonation) + return Impersonation.examine(user) + return ..() - var/obj/effect/overlay/hologram = new(loc)//Spawn a blank effect at the location. - var/icon/flat_icon = icon(getFlatIcon(src,0))//Need to make sure it's a new icon so the old one is not reused. - flat_icon.ColorTone(rgb(125,180,225))//Let's make it bluish. - flat_icon.ChangeOpacity(0.5)//Make it half transparent. - var/input = input("Select what icon state to use in effect.",,"") - if(input) - var/icon/alpha_mask = new('icons/effects/effects.dmi', "[input]") - flat_icon.AddAlphaMask(alpha_mask)//Finally, let's mix in a distortion effect. - hologram.icon = flat_icon - to_chat(world, "Your icon should appear now.") - return -*/ +/obj/effect/overlay/holoray + name = "holoray" + icon = 'icons/effects/96x96.dmi' + icon_state = "holoray" + layer = FLY_LAYER + density = FALSE + anchored = TRUE + mouse_opacity = 1 + pixel_x = -32 + pixel_y = -32 + alpha = 100 /* * Other Stuff: Is this even used? @@ -268,3 +490,6 @@ Holographic project of everything else. desc = "It makes a hologram appear...with magnets or something..." icon = 'icons/obj/stationobjs.dmi' icon_state = "hologram0" + +#undef HOLOPAD_PASSIVE_POWER_USAGE +#undef HOLOGRAM_POWER_USAGE diff --git a/code/game/machinery/status_display.dm b/code/game/machinery/status_display.dm index a77bd744f92..ebf3cfeadf9 100644 --- a/code/game/machinery/status_display.dm +++ b/code/game/machinery/status_display.dm @@ -276,7 +276,6 @@ overlays.Cut() overlays += image('icons/obj/status_display.dmi', icon_state=picture_state) -#undef CHARS_PER_LINE #undef FONT_SIZE #undef FONT_COLOR #undef WARNING_FONT_COLOR diff --git a/code/game/machinery/telecomms/broadcaster.dm b/code/game/machinery/telecomms/broadcaster.dm index 48384f78f1e..64e387fb731 100644 --- a/code/game/machinery/telecomms/broadcaster.dm +++ b/code/game/machinery/telecomms/broadcaster.dm @@ -156,8 +156,26 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept signal.data["realname"], signal.data["vname"], 3, signal.data["compression"], list(0), connection.frequency, signal.data["verb"], signal.data["language"]) - - +#define CREW_RADIO_TYPE 0 +#define CENTCOMM_RADIO_TYPE 1 +#define SYNDICATE_RADIO_TYPE 2 +/proc/Is_Bad_Connection(old_freq, new_freq) //Makes sure players cant read radios of a higher level than they are + var/old_type = CREW_RADIO_TYPE + var/new_type = CREW_RADIO_TYPE + for(var/antag_freq in ANTAG_FREQS) + if(old_freq == antag_freq) + old_type = SYNDICATE_RADIO_TYPE + if(new_freq == antag_freq) + new_type = SYNDICATE_RADIO_TYPE + + for(var/cent_freq in CENT_FREQS) + if(old_freq == cent_freq) + old_type = CENTCOMM_RADIO_TYPE + if(new_freq == cent_freq) + new_type = CENTCOMM_RADIO_TYPE + + return new_type > old_type + /** Here is the big, bad function that broadcasts a message given the appropriate @@ -226,21 +244,28 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept var/display_freq = freq + var/bad_connection = FALSE + var/datum/radio_frequency/new_connection = connection + + if(connection.frequency != display_freq) + bad_connection = Is_Bad_Connection(connection.frequency, display_freq) + new_connection = radio_controller.return_frequency(display_freq) + var/list/obj/item/radio/radios = list() // --- Broadcast only to intercom devices --- - if(data == 1) + if(data == 1 && !bad_connection) - for(var/obj/item/radio/intercom/R in connection.devices["[RADIO_CHAT]"]) + for(var/obj/item/radio/intercom/R in new_connection.devices["[RADIO_CHAT]"]) if(R.receive_range(display_freq, level) > -1) radios += R // --- Broadcast only to intercoms and station-bounced radios --- - else if(data == 2) + else if(data == 2 && !bad_connection) - for(var/obj/item/radio/R in connection.devices["[RADIO_CHAT]"]) + for(var/obj/item/radio/R in new_connection.devices["[RADIO_CHAT]"]) if(istype(R, /obj/item/radio/headset)) continue @@ -259,9 +284,9 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept // --- Broadcast to ALL radio devices --- - else + else if(!bad_connection) - for(var/obj/item/radio/R in connection.devices["[RADIO_CHAT]"]) + for(var/obj/item/radio/R in new_connection.devices["[RADIO_CHAT]"]) if(R.receive_range(display_freq, level) > -1) radios += R diff --git a/code/game/machinery/telecomms/telecomunications.dm b/code/game/machinery/telecomms/telecomunications.dm index 9dc30edf61e..0b9b1449137 100644 --- a/code/game/machinery/telecomms/telecomunications.dm +++ b/code/game/machinery/telecomms/telecomunications.dm @@ -436,7 +436,7 @@ var/global/list/obj/machinery/telecomms/telecomms_list = list() var/totaltraffic = 0 // gigabytes (if > 1024, divide by 1024 -> terrabytes) var/list/memory = list() // stored memory - var/rawcode = "" // the code to compile (raw text) + var/list/rawcode = list() // the code to compile (list of characters) var/datum/TCS_Compiler/Compiler // the compiler that compiles and runs the code var/autoruncode = 0 // 1 if the code is set to run every time a signal is picked up @@ -516,10 +516,9 @@ var/global/list/obj/machinery/telecomms/telecomms_list = list() relay_information(signal, "/obj/machinery/telecomms/broadcaster") -/obj/machinery/telecomms/server/proc/setcode(var/t) - if(t) - if(istext(t)) - rawcode = t +/obj/machinery/telecomms/server/proc/setcode(var/list/code) + if(istype(code)) + rawcode = code /obj/machinery/telecomms/server/proc/compile(mob/user as mob) if(Compiler) @@ -548,8 +547,8 @@ var/global/list/obj/machinery/telecomms/telecomms_list = list() /obj/machinery/telecomms/server/proc/admin_log(var/mob/mob) var/msg="[key_name(mob)] has compiled a script to server [src]:" log_game("NTSL: [msg]") - log_game("NTSL: [rawcode]") - src.investigate_log("[msg]
[rawcode]", "ntsl") + log_game("NTSL: [rawcode.Join("")]") + src.investigate_log("[msg]
[rawcode.Join("")]", "ntsl") if(length(rawcode)) // Let's not bother the admins for empty code. message_admins("[key_name_admin(mob)] has compiled and uploaded a NTSL script to [src.id] (JMP)") diff --git a/code/game/machinery/telecomms/traffic_control.dm b/code/game/machinery/telecomms/traffic_control.dm index a2580285a38..45f0817ef55 100644 --- a/code/game/machinery/telecomms/traffic_control.dm +++ b/code/game/machinery/telecomms/traffic_control.dm @@ -117,6 +117,7 @@ function compileCode() { var codeText = cMirror_fSubmit.getValue(); document.getElementById("cMirrorPost").value = codeText; + document.getElementById("cMirrorPostList").value = JSON.stringify(codeText.split('')); document.getElementById("theform").submit(); } @@ -135,6 +136,7 @@ + "} else @@ -189,6 +191,10 @@ if(code) storedcode = code + var/list/codelist = href_list["cMirrorList"] + if(istext(codelist)) + codelist = json_decode(codelist) + add_fingerprint(user) user.set_machine(src) @@ -198,14 +204,14 @@ switch(href_list["choice"]) if("Compile") - if(!code) + if(!istype(codelist)) return 0 if(user != editingcode) return 0 //only one editor if(SelectedServer) var/obj/machinery/telecomms/server/Server = SelectedServer - Server.setcode(code) + Server.setcode(codelist) spawn(0) // Output all the compile-time errors @@ -234,7 +240,7 @@ updateUsrDialog() for(var/obj/machinery/telecomms/server/Server in servers) - Server.setcode(code) + Server.setcode(codelist) var/list/compileerrors = Server.compile(user) if(!telecomms_check(user)) return diff --git a/code/game/machinery/vending.dm b/code/game/machinery/vending.dm index db228aff04f..fb8b8fb0f32 100644 --- a/code/game/machinery/vending.dm +++ b/code/game/machinery/vending.dm @@ -1,7 +1,3 @@ -#define CAT_NORMAL 1 -#define CAT_HIDDEN 2 // also used in corresponding wires/vending.dm -#define CAT_COIN 4 - /** * Datum used to hold information about a product in a vending machine */ diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm index 23134bc3144..ca43f87ae46 100644 --- a/code/game/mecha/mecha.dm +++ b/code/game/mecha/mecha.dm @@ -470,19 +470,10 @@ /obj/mecha/attack_hand(mob/living/user) user.changeNext_move(CLICK_CD_MELEE) log_message("Attack by hand/paw. Attacker - [user].",1) - - if((HULK in user.mutations) && !prob(deflect_chance)) - do_attack_animation(src, ATTACK_EFFECT_SMASH) - take_damage(15) - check_for_internal_damage(list(MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST)) - user.visible_message("[user] hits [name], doing some damage.", - "You hit [name] with all your might. The metal creaks and bends.") - else - user.do_attack_animation(src, ATTACK_EFFECT_PUNCH) - playsound(loc, 'sound/weapons/tap.ogg', 40, 1, -1) - user.visible_message("[user] hits [name]. Nothing happens","You hit [name] with no visible effect.") - log_append_to_last("Armor saved.") - return + user.do_attack_animation(src, ATTACK_EFFECT_PUNCH) + playsound(loc, 'sound/weapons/tap.ogg', 40, 1, -1) + user.visible_message("[user] hits [name]. Nothing happens", "You hit [name] with no visible effect.") + log_append_to_last("Armor saved.") /obj/mecha/attack_alien(mob/living/user) @@ -526,6 +517,16 @@ user.create_attack_log("attacked [name]") return +/obj/mecha/hulk_damage() + return 15 + +/obj/mecha/attack_hulk(mob/living/carbon/human/user) + . = ..() + if(.) + check_for_internal_damage(list(MECHA_INT_TEMP_CONTROL, MECHA_INT_TANK_BREACH, MECHA_INT_CONTROL_LOST)) + log_message("Attack by hulk. Attacker - [user].", 1) + add_attack_logs(user, src, "Punched with hulk powers") + /obj/mecha/hitby(atom/movable/A) //wrapper ..() log_message("Hit by [A].",1) diff --git a/code/game/objects/effects/decals/misc.dm b/code/game/objects/effects/decals/misc.dm index 6bcfb253454..301fd71a98d 100644 --- a/code/game/objects/effects/decals/misc.dm +++ b/code/game/objects/effects/decals/misc.dm @@ -1,12 +1,3 @@ -/obj/effect/decal/point - name = "arrow" - desc = "It's an arrow hanging in mid-air. There may be a wizard about." - icon = 'icons/mob/screen_gen.dmi' - icon_state = "arrow" - layer = 16.0 - anchored = 1 - mouse_opacity = 0 - // Used for spray that you spray at walls, tables, hydrovats etc /obj/effect/decal/spraystill density = 0 diff --git a/code/game/objects/effects/effect_system/effects_foam.dm b/code/game/objects/effects/effect_system/effects_foam.dm index 93763c464e7..e765e59442d 100644 --- a/code/game/objects/effects/effect_system/effects_foam.dm +++ b/code/game/objects/effects/effect_system/effects_foam.dm @@ -163,13 +163,14 @@ // dense and opaque, but easy to break /obj/structure/foamedmetal - icon = 'icons/effects/effects.dmi' - icon_state = "metalfoam" - density = 1 - opacity = 1 // changed in New() - anchored = 1 name = "foamed metal" desc = "A lightweight foamed metal wall." + icon = 'icons/effects/effects.dmi' + icon_state = "metalfoam" + density = TRUE + opacity = TRUE // changed in New() + anchored = TRUE + max_integrity = 20 var/metal = MFOAM_ALUMINUM /obj/structure/foamedmetal/Initialize() @@ -177,7 +178,6 @@ air_update_turf(1) /obj/structure/foamedmetal/Destroy() - density = 0 air_update_turf(1) return ..() @@ -186,64 +186,31 @@ ..() move_update_air(T) +/obj/structure/foamedmetal/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0) + playsound(loc, 'sound/weapons/tap.ogg', 100, 1) + /obj/structure/foamedmetal/proc/updateicon() if(metal == MFOAM_ALUMINUM) icon_state = "metalfoam" + max_integrity = 20 + obj_integrity = max_integrity else icon_state = "ironfoam" - -/obj/structure/foamedmetal/ex_act(severity) - qdel(src) - -/obj/structure/foamedmetal/blob_act() - qdel(src) - -/obj/structure/foamedmetal/bullet_act() - if(metal==MFOAM_ALUMINUM || prob(50)) - qdel(src) + max_integrity = 50 + obj_integrity = max_integrity /obj/structure/foamedmetal/attack_hand(mob/user) user.changeNext_move(CLICK_CD_MELEE) user.do_attack_animation(src, ATTACK_EFFECT_PUNCH) - if((HULK in user.mutations) || (prob(75 - metal*25))) - user.visible_message("[user] smashes through \the [src].", "You smash through \the [src].") + if(prob(75 - metal * 25)) + user.visible_message("[user] smashes through [src].", "You smash through [src].") qdel(src) else to_chat(user, "You hit the metal foam but bounce off it.") + playsound(loc, 'sound/weapons/tap.ogg', 100, 1) -/obj/structure/foamedmetal/attackby(obj/item/I, mob/user, params) - user.changeNext_move(CLICK_CD_MELEE) - user.do_attack_animation(src) - if(istype(I, /obj/item/grab)) - var/obj/item/grab/G = I - G.affecting.loc = src.loc - user.visible_message("[G.assailant] smashes [G.affecting] through the foamed metal wall.") - qdel(I) - qdel(src) - return - - if(prob(I.force*20 - metal*25)) - user.visible_message("[user] smashes through the foamed metal with \the [I].", "You smash through the foamed metal with \the [I].") - qdel(src) - else - to_chat(user, "You hit the metal foam to no effect.") - -/obj/structure/foamedmetal/attack_animal(mob/living/simple_animal/M) - M.do_attack_animation(src) - if(M.melee_damage_upper == 0) - M.visible_message("[M] nudges \the [src].") - else - if(M.attack_sound) - playsound(loc, M.attack_sound, 50, 1, 1) - M.visible_message("\The [M] [M.attacktext] [src]!") - qdel(src) - -/obj/structure/foamedmetal/attack_alien(mob/living/carbon/alien/humanoid/M) - M.visible_message("[M] tears apart \the [src]!"); - qdel(src) - -/obj/structure/foamedmetal/CanPass(atom/movable/mover, turf/target, height=1.5) +/obj/structure/foamedmetal/CanPass(atom/movable/mover, turf/target) return !density /obj/structure/foamedmetal/CanAtmosPass() - return !density + return !density \ No newline at end of file diff --git a/code/game/objects/effects/effects.dm b/code/game/objects/effects/effects.dm index 467858ad670..0e8bd6691f2 100644 --- a/code/game/objects/effects/effects.dm +++ b/code/game/objects/effects/effects.dm @@ -11,4 +11,7 @@ return /obj/effect/fire_act() - return \ No newline at end of file + return + +/obj/effect/attack_hulk(mob/living/carbon/human/user, does_attack_animation = FALSE) + return FALSE \ No newline at end of file diff --git a/code/game/objects/effects/temporary_visuals/clockcult.dm b/code/game/objects/effects/temporary_visuals/clockcult.dm index 4a70c73c9c3..f6b654ccbbe 100644 --- a/code/game/objects/effects/temporary_visuals/clockcult.dm +++ b/code/game/objects/effects/temporary_visuals/clockcult.dm @@ -6,6 +6,10 @@ randomdir = 0 layer = ABOVE_NORMAL_TURF_LAYER +/obj/effect/temp_visual/ratvar/door/window + icon_state = "ratvarwindoorglow" + layer = ABOVE_WINDOW_LAYER + /obj/effect/temp_visual/ratvar/beam icon_state = "ratvarbeamglow" @@ -15,6 +19,13 @@ /obj/effect/temp_visual/ratvar/floor icon_state = "ratvarfloorglow" +/obj/effect/temp_visual/ratvar/window + icon_state = "ratvarwindowglow" + layer = ABOVE_OBJ_LAYER + +/obj/effect/temp_visual/ratvar/window/single + icon_state = "ratvarwindowglow_s" + /obj/effect/temp_visual/ratvar/grille icon_state = "ratvargrilleglow" layer = BELOW_OBJ_LAYER diff --git a/code/game/objects/effects/temporary_visuals/miscellaneous.dm b/code/game/objects/effects/temporary_visuals/miscellaneous.dm index 001c482a922..03e8ea8fcd9 100644 --- a/code/game/objects/effects/temporary_visuals/miscellaneous.dm +++ b/code/game/objects/effects/temporary_visuals/miscellaneous.dm @@ -1,3 +1,12 @@ +/obj/effect/temp_visual/point + name = "arrow" + desc = "It's an arrow hanging in mid-air. There may be a wizard about." + icon = 'icons/mob/screen_gen.dmi' + icon_state = "arrow" + layer = POINT_LAYER + duration = 20 + randomdir = FALSE + /obj/effect/temp_visual/dir_setting/bloodsplatter icon = 'icons/effects/blood.dmi' duration = 5 diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 4977120fcc9..d83660e4de6 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -550,3 +550,6 @@ var/global/image/fire_overlay = image("icon" = 'icons/goonstation/effects/fire.d /obj/item/proc/on_trip(mob/living/carbon/human/H) if(H.slip(src, trip_stun, trip_weaken, trip_tiles, trip_walksafe, trip_any, trip_verb)) return TRUE + +/obj/item/attack_hulk(mob/living/carbon/human/user) + return FALSE \ No newline at end of file diff --git a/code/game/objects/items/devices/aicard.dm b/code/game/objects/items/devices/aicard.dm index 154a2032825..291f0fd7b2a 100644 --- a/code/game/objects/items/devices/aicard.dm +++ b/code/game/objects/items/devices/aicard.dm @@ -84,7 +84,7 @@ var/confirm = alert("Are you sure you want to wipe this card's memory? This cannot be undone once started.", "Confirm Wipe", "Yes", "No") if(confirm == "Yes" && (CanUseTopic(user, state) == STATUS_INTERACTIVE)) msg_admin_attack("[key_name_admin(user)] wiped [key_name_admin(AI)] with \the [src].") - log_attack(user, AI, "Wiped with [src].") + add_attack_logs(user, AI, "Wiped with [src].") flush = 1 AI.suiciding = 1 to_chat(AI, "Your core files are being wiped!") diff --git a/code/game/objects/items/stacks/sheets/glass.dm b/code/game/objects/items/stacks/sheets/glass.dm index a30c3e1b716..ebc89cdca7a 100644 --- a/code/game/objects/items/stacks/sheets/glass.dm +++ b/code/game/objects/items/stacks/sheets/glass.dm @@ -13,6 +13,15 @@ /* * Glass sheets */ + +GLOBAL_LIST_INIT(glass_recipes, list ( \ + new/datum/stack_recipe/window("directional window", /obj/structure/window/basic, time = 0, on_floor = TRUE, window_checks = TRUE), \ + new/datum/stack_recipe/window("fulltile window", /obj/structure/window/full/basic, 2, time = 0, on_floor = TRUE, window_checks = TRUE), \ + new/datum/stack_recipe("fishbowl", /obj/machinery/fishtank/bowl, 1, time = 0), \ + new/datum/stack_recipe("fish tank", /obj/machinery/fishtank/tank, 3, time = 0, on_floor = TRUE), \ + new/datum/stack_recipe("wall aquariam", /obj/machinery/fishtank/wall, 4, time = 0, on_floor = TRUE) \ +)) + /obj/item/stack/sheet/glass name = "glass" desc = "HOLY SHEET! That is a lot of glass." @@ -30,8 +39,9 @@ /obj/item/stack/sheet/glass/cyborg materials = list() -/obj/item/stack/sheet/glass/attack_self(mob/user as mob) - construct_window(user) +/obj/item/stack/sheet/glass/New(loc, amount) + recipes = GLOB.glass_recipes + ..() /obj/item/stack/sheet/glass/attackby(obj/item/W, mob/user, params) ..() @@ -59,94 +69,18 @@ else return ..() -/obj/item/stack/sheet/glass/proc/construct_window(mob/user as mob) - if(!user || !src) return 0 - if(!istype(user.loc,/turf)) return 0 - if(!user.IsAdvancedToolUser()) - to_chat(user, "You don't have the dexterity to do this!") - return 0 - var/title = "Sheet-Glass" - title += " ([src.amount] sheet\s left)" - switch(input(title, "What would you like to construct?") in list("One Direction Window", "Full Window", "Fishbowl", "Fish Tank", "Wall Aquarium", "Cancel")) - if("One Direction Window") - if(!src) return 1 - if(src.loc != user) return 1 - - var/list/directions = new/list(cardinal) - var/i = 0 - for(var/obj/structure/window/win in user.loc) - i++ - if(i >= 4) - to_chat(user, "There are too many windows in this location.") - return 1 - directions-=win.dir - if(win.is_fulltile()) - to_chat(user, "Can't let you do that.") - return 1 - - //Determine the direction. It will first check in the direction the person making the window is facing, if it finds an already made window it will try looking at the next cardinal direction, etc. - var/dir_to_set = 2 - for(var/direction in list( user.dir, turn(user.dir,90), turn(user.dir,180), turn(user.dir,270) )) - var/found = 0 - for(var/obj/structure/window/WT in user.loc) - if(WT.dir == direction) - found = 1 - if(!found) - dir_to_set = direction - break - - var/obj/structure/window/W - W = new /obj/structure/window/basic( user.loc, 0 ) - W.dir = dir_to_set - W.ini_dir = W.dir - W.state = 0 - W.anchored = 0 - W.air_update_turf(1) - src.use(1) - if("Full Window") - if(!src) return 1 - if(src.loc != user) return 1 - if(src.amount < 2) - to_chat(user, "You need more glass to do that.") - return 1 - if(locate(/obj/structure/window/full) in user.loc) - to_chat(user, "There is a full window in the way.") - return 1 - var/obj/structure/window/W = new full_window( user.loc, 0 ) - W.state = 0 - W.anchored = 0 - W.air_update_turf(1) - src.use(2) - if("Fishbowl") - if(!src) return 1 - if(src.loc != user) return 1 - var/obj/machinery/fishtank/F = new /obj/machinery/fishtank/bowl(user.loc, 0) - F.air_update_turf(1) - src.use(1) - if("Fish Tank") - if(!src) return 1 - if(src.loc != user) return 1 - if(src.amount < 3) - to_chat(user, "You need more glass to do that.") - return 1 - var/obj/machinery/fishtank/F = new /obj/machinery/fishtank/tank(user.loc, 0) - F.air_update_turf(1) - src.use(3) - if("Wall Aquarium") - if(!src) return 1 - if(src.loc != user) return 1 - if(src.amount < 4) - to_chat(user, "You need more glass to do that.") - return 1 - var/obj/machinery/fishtank/F = new /obj/machinery/fishtank/wall(user.loc, 0) - F.air_update_turf(1) - src.use(4) - return 0 - /* * Reinforced glass sheets */ + +GLOBAL_LIST_INIT(reinforced_glass_recipes, list ( \ + new/datum/stack_recipe/window("windoor frame", /obj/structure/windoor_assembly, 5, time = 0, on_floor = TRUE, window_checks = TRUE), \ + null, \ + new/datum/stack_recipe/window("directional reinforced window", /obj/structure/window/reinforced, time = 0, on_floor = TRUE, window_checks = TRUE), \ + new/datum/stack_recipe/window("fulltile reinforced window", /obj/structure/window/full/reinforced, 2, time = 0, on_floor = TRUE, window_checks = TRUE) \ +)) + /obj/item/stack/sheet/rglass name = "reinforced glass" desc = "Glass which seems to have rods or something stuck in them." @@ -161,105 +95,14 @@ /obj/item/stack/sheet/rglass/cyborg materials = list() -/obj/item/stack/sheet/rglass/attack_self(mob/user as mob) - construct_window(user) - -/obj/item/stack/sheet/rglass/proc/construct_window(mob/user as mob) - if(!user || !src) return 0 - if(!istype(user.loc,/turf)) return 0 - if(!user.IsAdvancedToolUser()) - to_chat(user, "You don't have the dexterity to do this!") - return 0 - var/title = "Sheet Reinf. Glass" - title += " ([src.amount] sheet\s left)" - switch(input(title, "Would you like full tile glass a one direction glass pane or a windoor?") in list("One Direction", "Full Window", "Windoor", "Cancel")) - if("One Direction") - if(!src) return 1 - if(src.loc != user) return 1 - var/list/directions = new/list(cardinal) - var/i = 0 - for(var/obj/structure/window/win in user.loc) - i++ - if(i >= 4) - to_chat(user, "There are too many windows in this location.") - return 1 - directions-=win.dir - if(win.is_fulltile()) - to_chat(user, "Can't let you do that.") - return 1 - - //Determine the direction. It will first check in the direction the person making the window is facing, if it finds an already made window it will try looking at the next cardinal direction, etc. - var/dir_to_set = 2 - for(var/direction in list( user.dir, turn(user.dir,90), turn(user.dir,180), turn(user.dir,270) )) - var/found = 0 - for(var/obj/structure/window/WT in user.loc) - if(WT.dir == direction) - found = 1 - if(!found) - dir_to_set = direction - break - - var/obj/structure/window/W - W = new /obj/structure/window/reinforced( user.loc, 1 ) - W.state = 0 - W.dir = dir_to_set - W.ini_dir = W.dir - W.anchored = 0 - src.use(1) - - if("Full Window") - if(!src) return 1 - if(src.loc != user) return 1 - if(src.amount < 2) - to_chat(user, "You need more glass to do that.") - return 1 - if(locate(/obj/structure/window/full) in user.loc) - to_chat(user, "There is a window in the way.") - return 1 - var/obj/structure/window/W = new full_window( user.loc, 0 ) - W.state = 0 - W.anchored = 0 - src.use(2) - - if("Windoor") - if(!src || src.loc != user) return 1 - - if(isturf(user.loc) && locate(/obj/structure/windoor_assembly/, user.loc)) - to_chat(user, "There is already a windoor assembly in that location.") - return 1 - - if(isturf(user.loc) && locate(/obj/machinery/door/window/, user.loc)) - to_chat(user, "There is already a windoor in that location.") - return 1 - - if(src.amount < 5) - to_chat(user, "You need more glass to do that.") - return 1 - - var/obj/structure/windoor_assembly/WD - WD = new /obj/structure/windoor_assembly(user.loc) - WD.state = "01" - WD.anchored = 0 - src.use(5) - switch(user.dir) - if(SOUTH) - WD.dir = SOUTH - WD.ini_dir = SOUTH - if(EAST) - WD.dir = EAST - WD.ini_dir = EAST - if(WEST) - WD.dir = WEST - WD.ini_dir = WEST - else//If the user is facing northeast. northwest, southeast, southwest or north, default to north - WD.dir = NORTH - WD.ini_dir = NORTH - else - return 1 - - - return 0 +/obj/item/stack/sheet/rglass/New(loc, amount) + recipes = GLOB.reinforced_glass_recipes + ..() +GLOBAL_LIST_INIT(pglass_recipes, list ( \ + new/datum/stack_recipe/window("directional window", /obj/structure/window/plasmabasic, time = 0, on_floor = TRUE, window_checks = TRUE), \ + new/datum/stack_recipe/window("fulltile window", /obj/structure/window/full/plasmabasic, 2, time = 0, on_floor = TRUE, window_checks = TRUE) \ +)) /obj/item/stack/sheet/plasmaglass name = "plasma glass" @@ -271,8 +114,9 @@ created_window = /obj/structure/window/plasmabasic full_window = /obj/structure/window/full/plasmabasic -/obj/item/stack/sheet/plasmaglass/attack_self(mob/user as mob) - construct_window(user) +/obj/item/stack/sheet/plasmaglass/New(loc, amount) + recipes = GLOB.pglass_recipes + ..() /obj/item/stack/sheet/plasmaglass/attackby(obj/item/W, mob/user, params) ..() @@ -291,64 +135,15 @@ else return ..() -/obj/item/stack/sheet/plasmaglass/proc/construct_window(mob/user as mob) - if(!user || !src) return 0 - if(!istype(user.loc,/turf)) return 0 - if(!user.IsAdvancedToolUser()) - to_chat(user, " You don't have the dexterity to do this!") - return 0 - var/title = "Plasma-glass alloy" - title += " ([src.amount] sheet\s left)" - switch(alert(title, "Would you like full tile glass or one direction?", "One Direction", "Full Window", "Cancel", null)) - if("One Direction") - if(!src) return 1 - if(src.loc != user) return 1 - var/list/directions = new/list(cardinal) - var/i = 0 - for(var/obj/structure/window/win in user.loc) - i++ - if(i >= 4) - to_chat(user, "There are too many windows in this location.") - return 1 - directions-=win.dir - if(!(win.ini_dir in cardinal)) - to_chat(user, "Can't let you do that.") - return 1 - //Determine the direction. It will first check in the direction the person making the window is facing, if it finds an already made window it will try looking at the next cardinal direction, etc. - var/dir_to_set = 2 - for(var/direction in list( user.dir, turn(user.dir,90), turn(user.dir,180), turn(user.dir,270) )) - var/found = 0 - for(var/obj/structure/window/WT in user.loc) - if(WT.dir == direction) - found = 1 - if(!found) - dir_to_set = direction - break - var/obj/structure/window/W - W = new /obj/structure/window/plasmabasic( user.loc, 0 ) - W.dir = dir_to_set - W.ini_dir = W.dir - W.state = 0 - W.anchored = 0 - src.use(1) - if("Full Window") - if(!src) return 1 - if(src.loc != user) return 1 - if(src.amount < 2) - to_chat(user, "You need more glass to do that.") - return 1 - if(locate(/obj/structure/window) in user.loc) - to_chat(user, "There is a window in the way.") - return 1 - var/obj/structure/window/W = new full_window( user.loc, 0 ) - W.state = 0 - W.anchored = 0 - src.use(2) - return 0 - /* * Reinforced plasma glass sheets */ + +GLOBAL_LIST_INIT(prglass_recipes, list ( \ + new/datum/stack_recipe/window("directional reinforced window", /obj/structure/window/plasmareinforced, time = 0, on_floor = TRUE, window_checks = TRUE), \ + new/datum/stack_recipe/window("fulltile reinforced window", /obj/structure/window/full/plasmareinforced, 2, time = 0, on_floor = TRUE, window_checks = TRUE) \ +)) + /obj/item/stack/sheet/plasmarglass name = "reinforced plasma glass" desc = "Plasma glass which seems to have rods or something stuck in them." @@ -360,60 +155,42 @@ full_window = /obj/structure/window/full/plasmareinforced armor = list("melee" = 20, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0) -/obj/item/stack/sheet/plasmarglass/attack_self(mob/user as mob) - construct_window(user) +/obj/item/stack/sheet/plasmarglass/New(loc, amount) + recipes = GLOB.prglass_recipes + ..() -/obj/item/stack/sheet/plasmarglass/proc/construct_window(mob/user as mob) - if(!user || !src) return 0 - if(!istype(user.loc,/turf)) return 0 - if(!user.IsAdvancedToolUser()) - to_chat(user, "You don't have the dexterity to do this!") - return 0 - var/title = "Reinforced plasma-glass alloy" - title += " ([src.amount] sheet\s left)" - switch(alert(title, "Would you like full tile glass or one direction?", "One Direction", "Full Window", "Cancel", null)) - if("One Direction") - if(!src) return 1 - if(src.loc != user) return 1 - var/list/directions = new/list(cardinal) - var/i = 0 - for(var/obj/structure/window/win in user.loc) - i++ - if(i >= 4) - to_chat(user, "There are too many windows in this location.") - return 1 - directions-=win.dir - if(!(win.ini_dir in cardinal)) - to_chat(user, "Can't let you do that.") - return 1 - //Determine the direction. It will first check in the direction the person making the window is facing, if it finds an already made window it will try looking at the next cardinal direction, etc. - var/dir_to_set = 2 - for(var/direction in list( user.dir, turn(user.dir,90), turn(user.dir,180), turn(user.dir,270) )) - var/found = 0 - for(var/obj/structure/window/WT in user.loc) - if(WT.dir == direction) - found = 1 - if(!found) - dir_to_set = direction - break - var/obj/structure/window/W - W = new /obj/structure/window/plasmareinforced( user.loc, 0 ) - W.dir = dir_to_set - W.ini_dir = W.dir - W.state = 0 - W.anchored = 0 - src.use(1) - if("Full Window") - if(!src) return 1 - if(src.loc != user) return 1 - if(src.amount < 2) - to_chat(user, "You need more glass to do that.") - return 1 - if(locate(/obj/structure/window) in user.loc) - to_chat(user, "There is a window in the way.") - return 1 - var/obj/structure/window/W = new full_window( user.loc, 0 ) - W.state = 0 - W.anchored = 0 - src.use(2) - return 0 +GLOBAL_LIST_INIT(titaniumglass_recipes, list( + new/datum/stack_recipe/window("shuttle window", /obj/structure/window/full/shuttle, 2, time = 0, on_floor = TRUE, window_checks = TRUE) + )) + +/obj/item/stack/sheet/titaniumglass + name = "titanium glass" + desc = "A glass sheet made out of a titanium-silicate alloy." + singular_name = "titanium glass sheet" + icon_state = "sheet-titaniumglass" + item_state = "sheet-titaniumglass" + materials = list(MAT_TITANIUM=MINERAL_MATERIAL_AMOUNT, MAT_GLASS=MINERAL_MATERIAL_AMOUNT) + merge_type = /obj/item/stack/sheet/titaniumglass + full_window = /obj/structure/window/full/shuttle + +/obj/item/stack/sheet/titaniumglass/New(loc, amount) + recipes = GLOB.titaniumglass_recipes + ..() + +GLOBAL_LIST_INIT(plastitaniumglass_recipes, list( + new/datum/stack_recipe/window("plastitanium window", /obj/structure/window/plastitanium, 2, time = 0, on_floor = TRUE, window_checks = TRUE) + )) + +/obj/item/stack/sheet/plastitaniumglass + name = "plastitanium glass" + desc = "A glass sheet made out of a plasma-titanium-silicate alloy." + singular_name = "plastitanium glass sheet" + icon_state = "sheet-plastitaniumglass" + item_state = "sheet-plastitaniumglass" + materials = list(MAT_TITANIUM=MINERAL_MATERIAL_AMOUNT, MAT_PLASMA=MINERAL_MATERIAL_AMOUNT, MAT_GLASS=MINERAL_MATERIAL_AMOUNT) + merge_type = /obj/item/stack/sheet/plastitaniumglass + full_window = /obj/structure/window/plastitanium + +/obj/item/stack/sheet/plastitaniumglass/New(loc, amount) + recipes = GLOB.plastitaniumglass_recipes + ..() diff --git a/code/game/objects/items/stacks/sheets/sheet_types.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm index 4412b547b19..5ef40ee25e8 100644 --- a/code/game/objects/items/stacks/sheets/sheet_types.dm +++ b/code/game/objects/items/stacks/sheets/sheet_types.dm @@ -318,7 +318,11 @@ var/global/list/datum/stack_recipe/cult = list ( \ /* * Brass */ -var/global/list/datum/stack_recipe/brass_recipes = list ( \ +var/global/list/datum/stack_recipe/brass_recipes = list (\ + new/datum/stack_recipe/window("brass windoor", /obj/machinery/door/window/clockwork, 2, time = 30, on_floor = TRUE, window_checks = TRUE), \ + null, + new/datum/stack_recipe/window("directional brass window", /obj/structure/window/reinforced/clockwork, time = 0, on_floor = TRUE, window_checks = TRUE), \ + new/datum/stack_recipe/window("fulltile brass window", /obj/structure/window/reinforced/clockwork/fulltile, 2, time = 0, on_floor = TRUE, window_checks = TRUE), \ new/datum/stack_recipe("brass table frame", /obj/structure/table_frame/brass, 1, time = 5, one_per_turf = TRUE, on_floor = TRUE), \ ) diff --git a/code/game/objects/items/stacks/stack.dm b/code/game/objects/items/stacks/stack.dm index 4dd6ca365bf..e55569b23e8 100644 --- a/code/game/objects/items/stacks/stack.dm +++ b/code/game/objects/items/stacks/stack.dm @@ -149,6 +149,10 @@ to_chat(usr, "You haven't got enough [src] to build \the [R.title]!") return 0 + if(R.window_checks && !valid_window_location(usr.loc, usr.dir)) + to_chat(usr, "The [R.title] won't fit here!") + return FALSE + if(R.one_per_turf && (locate(R.result_type) in creation_loc)) to_chat(usr, "There is another [R.title] here!") return 0 @@ -166,7 +170,7 @@ return var/atom/O = new R.result_type(creation_loc) - O.dir = usr.dir + O.setDir(usr.dir) if(R.max_res_amount > 1) var/obj/item/stack/new_item = O new_item.amount = R.res_amount * multiplier diff --git a/code/game/objects/items/stacks/stack_recipe.dm b/code/game/objects/items/stacks/stack_recipe.dm index 67ddd964d0d..10d06e9741d 100644 --- a/code/game/objects/items/stacks/stack_recipe.dm +++ b/code/game/objects/items/stacks/stack_recipe.dm @@ -11,8 +11,9 @@ var/time = 0 var/one_per_turf = 0 var/on_floor = 0 + var/window_checks = FALSE -/datum/stack_recipe/New(title, result_type, req_amount = 1, res_amount = 1, max_res_amount = 1, time = 0, one_per_turf = 0, on_floor = 0) +/datum/stack_recipe/New(title, result_type, req_amount = 1, res_amount = 1, max_res_amount = 1, time = 0, one_per_turf = 0, on_floor = 0, window_checks = FALSE) src.title = title src.result_type = result_type src.req_amount = req_amount @@ -21,6 +22,7 @@ src.time = time src.one_per_turf = one_per_turf src.on_floor = on_floor + src.window_checks = window_checks /datum/stack_recipe/proc/post_build(var/obj/item/stack/S, var/obj/result) return @@ -40,6 +42,17 @@ R.update_icon() ..() +/datum/stack_recipe/window +/datum/stack_recipe/window/post_build(obj/item/stack/S, obj/result) + if(istype(result, /obj/structure/windoor_assembly)) + var/obj/structure/windoor_assembly/W = result + W.ini_dir = W.dir + else if(istype(result, /obj/structure/window)) + var/obj/structure/window/W = result + W.ini_dir = W.dir + W.anchored = FALSE + W.state = WINDOW_OUT_OF_FRAME + /* * Recipe list datum */ diff --git a/code/game/objects/items/weapons/RCD.dm b/code/game/objects/items/weapons/RCD.dm index fe132c107b0..5cc7ee684af 100644 --- a/code/game/objects/items/weapons/RCD.dm +++ b/code/game/objects/items/weapons/RCD.dm @@ -9,10 +9,10 @@ RCD icon_state = "rcd" opacity = 0 density = 0 - anchored = 0.0 - flags = CONDUCT - force = 10.0 - throwforce = 10.0 + anchored = 0 + flags = CONDUCT | NOBLUDGEON + force = 0 + throwforce = 10 throw_speed = 3 throw_range = 5 w_class = WEIGHT_CLASS_NORMAL @@ -296,8 +296,6 @@ RCD var/turf/T1 = get_turf(A) QDEL_NULL(A) for(var/obj/structure/window/W in T1.contents) - W.disassembled = 1 - W.density = 0 qdel(W) for(var/cdir in cardinal) var/turf/T2 = get_step(T1, cdir) @@ -307,8 +305,6 @@ RCD continue for(var/obj/structure/window/W in T2.contents) if(W.dir == turn(cdir, 180)) - W.disassembled = 1 - W.density = 0 qdel(W) var/obj/structure/window/reinforced/W = new(T2) W.dir = turn(cdir, 180) @@ -331,16 +327,12 @@ RCD activate() new /obj/structure/grille(A) for(var/obj/structure/window/W in contents) - W.disassembled = 1 // Prevent that annoying glass breaking sound - W.density = 0 qdel(W) for(var/cdir in cardinal) var/turf/T = get_step(A, cdir) if(locate(/obj/structure/grille) in T.contents) for(var/obj/structure/window/W in T.contents) if(W.dir == turn(cdir, 180)) - W.disassembled = 1 - W.density = 0 qdel(W) else // Build a window! var/obj/structure/window/reinforced/W = new(A) diff --git a/code/game/objects/items/weapons/storage/fancy.dm b/code/game/objects/items/weapons/storage/fancy.dm index 9bf760aee29..4896f2cfb60 100644 --- a/code/game/objects/items/weapons/storage/fancy.dm +++ b/code/game/objects/items/weapons/storage/fancy.dm @@ -403,6 +403,7 @@ icon_state = "AquaticKit" throw_speed = 2 throw_range = 8 + med_bot_skin = "fish" /obj/item/storage/firstaid/aquatic_kit/full desc = "It's a starter kit for an acquarium; includes 1 tank brush, 1 egg scoop, 1 fish net, and 1 container of fish food." diff --git a/code/game/objects/items/weapons/storage/firstaid.dm b/code/game/objects/items/weapons/storage/firstaid.dm index 34e350e3d50..ddc8b79012f 100644 --- a/code/game/objects/items/weapons/storage/firstaid.dm +++ b/code/game/objects/items/weapons/storage/firstaid.dm @@ -21,6 +21,8 @@ var/treatment_fire = "salglu_solution" var/treatment_tox = "charcoal" var/treatment_virus = "spaceacillin" + var/med_bot_skin = null + var/syndicate_aligned = FALSE /obj/item/storage/firstaid/fire @@ -28,6 +30,7 @@ desc = "A medical kit that contains several medical patches and pills for treating burns. Contains one epinephrine syringe for emergency use and a health analyzer." icon_state = "ointment" item_state = "firstaid-ointment" + med_bot_skin = "ointment" New() ..() @@ -68,6 +71,7 @@ desc = "A medical kit designed to counter poisoning by common toxins. Contains three pills and syringes, and a health analyzer to determine the health of the patient." icon_state = "antitoxin" item_state = "firstaid-toxin" + med_bot_skin = "tox" New() ..() @@ -92,6 +96,7 @@ desc = "A first aid kit that contains four pills of salbutamol, which is able to counter injuries caused by suffocation. Also contains a health analyzer to determine the health of the patient." icon_state = "o2" item_state = "firstaid-o2" + med_bot_skin = "o2" New() ..() @@ -111,6 +116,7 @@ desc = "A medical kit that contains several medical patches and pills for treating brute injuries. Contains one epinephrine syringe for emergency use and a health analyzer." icon_state = "brute" item_state = "firstaid-brute" + med_bot_skin = "brute" New() ..() @@ -135,6 +141,7 @@ desc = "Contains advanced medical treatments." icon_state = "advfirstaid" item_state = "firstaid-advanced" + med_bot_skin = "adv" /obj/item/storage/firstaid/adv/New() ..() @@ -157,10 +164,12 @@ desc = "I hope you've got insurance." max_w_class = WEIGHT_CLASS_NORMAL treatment_oxy = "perfluorodecalin" - treatment_brute = "styptic_powder" - treatment_fire = "silver_sulfadiazine" + treatment_brute = "bicaridine" + treatment_fire = "kelotane" treatment_tox = "charcoal" req_one_access =list(access_syndicate) + med_bot_skin = "bezerk" + syndicate_aligned = TRUE /obj/item/storage/firstaid/tactical/New() ..() diff --git a/code/game/objects/items/weapons/twohanded.dm b/code/game/objects/items/weapons/twohanded.dm index 009b14f0722..8de83f6344a 100644 --- a/code/game/objects/items/weapons/twohanded.dm +++ b/code/game/objects/items/weapons/twohanded.dm @@ -178,14 +178,13 @@ /obj/item/twohanded/fireaxe/afterattack(atom/A, mob/user, proximity) if(!proximity) return - ..() - if(A && wielded && (istype(A,/obj/structure/window) || istype(A,/obj/structure/grille))) //destroys windows and grilles in one hit - - if(istype(A,/obj/structure/window)) + if(wielded) //destroys windows and grilles in one hit + if(istype(A, /obj/structure/window)) var/obj/structure/window/W = A - W.destroy() - else - qdel(A) + W.take_damage(200, BRUTE, "melee", 0) + else if(istype(A, /obj/structure/grille)) + var/obj/structure/grille/G = A + G.take_damage(40, BRUTE, "melee", 0) /* * Double-Bladed Energy Swords - Cheridan @@ -251,6 +250,11 @@ return ..() return FALSE +/obj/item/twohanded/dualsaber/attack_hulk(mob/living/carbon/human/user, does_attack_animation = FALSE) //In case thats just so happens that it is still activated on the groud, prevents hulk from picking it up + if(wielded) + to_chat(user, "You can't pick up such a dangerous item with your meaty hands without losing fingers, better not to!") + return TRUE + /obj/item/twohanded/dualsaber/green blade_color = "green" @@ -750,7 +754,7 @@ if(A && wielded && (istype(A, /obj/structure/window) || istype(A, /obj/structure/grille))) if(istype(A, /obj/structure/window)) var/obj/structure/window/W = A - W.destroy() + W.deconstruct(FALSE) if(prob(4)) charged++ user.visible_message("The axe starts to emit an electric buzz!") diff --git a/code/game/objects/obj_defense.dm b/code/game/objects/obj_defense.dm index fcd233318d5..d31338dfe06 100644 --- a/code/game/objects/obj_defense.dm +++ b/code/game/objects/obj_defense.dm @@ -71,6 +71,22 @@ visible_message("[src] is hit by \a [P]!") take_damage(P.damage, P.damage_type, P.flag, 0, turn(P.dir, 180), P.armour_penetration) +/obj/proc/hulk_damage() + return 150 //the damage hulks do on punches to this object, is affected by melee armor + +/obj/attack_hulk(mob/living/carbon/human/user, does_attack_animation = FALSE) + if(user.a_intent == INTENT_HARM) + ..(user, TRUE) + visible_message("[user] smashes [src]!") + if(density) + playsound(src, 'sound/effects/meteorimpact.ogg', 100, 1) + user.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" )) + else + playsound(src, 'sound/effects/bang.ogg', 50, 1) + take_damage(hulk_damage(), BRUTE, "melee", 0, get_dir(src, user)) + return TRUE + return FALSE + /obj/blob_act(obj/structure/blob/B) if(isturf(loc)) var/turf/T = loc diff --git a/code/game/objects/structures/aliens.dm b/code/game/objects/structures/aliens.dm index 76deeac93e8..1738344ae60 100644 --- a/code/game/objects/structures/aliens.dm +++ b/code/game/objects/structures/aliens.dm @@ -13,6 +13,27 @@ /obj/structure/alien icon = 'icons/mob/alien.dmi' + max_integrity = 100 + +/obj/structure/alien/run_obj_armor(damage_amount, damage_type, damage_flag = 0, attack_dir) + if(damage_flag == "melee") + switch(damage_type) + if(BRUTE) + damage_amount *= 0.25 + if(BURN) + damage_amount *= 2 + . = ..() + +/obj/structure/alien/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0) + switch(damage_type) + if(BRUTE) + if(damage_amount) + playsound(loc, 'sound/effects/attackblob.ogg', 100, 1) + else + playsound(src, 'sound/weapons/tap.ogg', 50, 1) + if(BURN) + if(damage_amount) + playsound(loc, 'sound/items/welder.ogg', 100, 1) /* * Resin @@ -22,13 +43,13 @@ desc = "Looks like some kind of thick resin." icon = 'icons/obj/smooth_structures/alien/resin_wall.dmi' icon_state = "resin" - density = 1 - opacity = 1 - anchored = 1 + density = TRUE + opacity = TRUE + anchored = TRUE canSmoothWith = list(/obj/structure/alien/resin) - var/health = 200 - var/resintype = null + max_integrity = 200 smooth = SMOOTH_TRUE + var/resintype = null /obj/structure/alien/resin/Initialize() air_update_turf(1) @@ -60,7 +81,7 @@ /obj/structure/alien/resin/wall/shadowling //For chrysalis name = "chrysalis wall" desc = "Some sort of purple substance in an egglike shape. It pulses and throbs from within and seems impenetrable." - health = INFINITY + max_integrity = INFINITY /obj/structure/alien/resin/membrane name = "resin membrane" @@ -68,80 +89,11 @@ icon = 'icons/obj/smooth_structures/alien/resin_membrane.dmi' icon_state = "membrane0" opacity = 0 - health = 120 + max_integrity = 160 resintype = "membrane" canSmoothWith = list(/obj/structure/alien/resin/wall, /obj/structure/alien/resin/membrane) -/obj/structure/alien/resin/proc/healthcheck() - if(health <=0) - qdel(src) - - -/obj/structure/alien/resin/bullet_act(obj/item/projectile/Proj) - if(Proj.damage_type == BRUTE || Proj.damage_type == BURN) - health -= Proj.damage - ..() - healthcheck() - - -/obj/structure/alien/resin/ex_act(severity) - switch(severity) - if(1) - health -= 150 - if(2) - health -= 100 - if(3) - health -= 50 - healthcheck() - - -/obj/structure/alien/resin/blob_act() - health -= 50 - healthcheck() - - -/obj/structure/alien/resin/hitby(atom/movable/AM) - ..() - var/tforce = 0 - if(ismob(AM)) - tforce = 10 - else if(isobj(AM)) - var/obj/O = AM - tforce = O.throwforce - playsound(loc, 'sound/effects/attackblob.ogg', 100, 1) - health -= tforce - healthcheck() - -/obj/structure/alien/resin/attack_hand(mob/living/user) - if(HULK in user.mutations) - user.do_attack_animation(src) - user.visible_message("[user] destroys [src]!") - health = 0 - healthcheck() - - -/obj/structure/alien/resin/attack_alien(mob/living/user) - user.changeNext_move(CLICK_CD_MELEE) - user.do_attack_animation(src) - if(islarva(user)) - return - user.visible_message("[user] claws at the resin!") - playsound(loc, 'sound/effects/attackblob.ogg', 100, 1) - health -= 50 - if(health <= 0) - user.visible_message("[user] slices the [name] apart!") - healthcheck() - - -/obj/structure/alien/resin/attackby(obj/item/I, mob/living/user, params) - user.changeNext_move(CLICK_CD_MELEE) - health -= I.force - playsound(loc, 'sound/effects/attackblob.ogg', 100, 1) - healthcheck() - ..() - - -/obj/structure/alien/resin/CanPass(atom/movable/mover, turf/target, height=0) +/obj/structure/alien/resin/CanPass(atom/movable/mover, turf/target) if(istype(mover) && mover.checkpass(PASSGLASS)) return !opacity return !density @@ -157,11 +109,11 @@ gender = PLURAL name = "resin floor" desc = "A thick resin surface covers the floor." + anchored = TRUE + density = FALSE + layer = TURF_LAYER icon_state = "weeds" - anchored = 1 - density = 0 - layer = 2 - var/health = 15 + max_integrity = 15 var/obj/structure/alien/weeds/node/linked_node = null var/static/list/weedImageCache @@ -204,39 +156,9 @@ new /obj/structure/alien/weeds(T, linked_node) - -/obj/structure/alien/weeds/ex_act(severity) - qdel(src) - - -/obj/structure/alien/weeds/attackby(obj/item/I, mob/user, params) - user.changeNext_move(CLICK_CD_MELEE) - if(I.attack_verb.len) - visible_message("[user] has [pick(I.attack_verb)] [src] with [I]!") - else - visible_message("[user] has attacked [src] with [I]!") - - var/damage = I.force / 4 - if(istype(I, /obj/item/weldingtool)) - var/obj/item/weldingtool/WT = I - if(WT.remove_fuel(0, user)) - damage = 15 - playsound(loc, WT.usesound, 100, 1) - - health -= damage - healthcheck() - - -/obj/structure/alien/weeds/proc/healthcheck() - if(health <= 0) - qdel(src) - - /obj/structure/alien/weeds/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) if(exposed_temperature > 300) - health -= 5 - healthcheck() - + take_damage(5, BURN, 0, 0) /obj/structure/alien/weeds/proc/updateWeedOverlays() @@ -303,9 +225,10 @@ name = "egg" desc = "A large mottled egg." icon_state = "egg_growing" - density = 0 - anchored = 1 - var/health = 100 + density = FALSE + anchored = TRUE + max_integrity = 100 + integrity_failure = 5 var/status = GROWING //can be GROWING, GROWN or BURST; all mutually exclusive layer = MOB_LAYER @@ -315,6 +238,8 @@ ..() spawn(rand(MIN_GROWTH_TIME, MAX_GROWTH_TIME)) Grow() + if(status == BURST) + obj_integrity = integrity_failure /obj/structure/alien/egg/attack_alien(mob/living/carbon/alien/user) return attack_hand(user) @@ -346,7 +271,7 @@ icon_state = "egg" status = GROWN -/obj/structure/alien/egg/proc/Burst(kill = 1) //drops and kills the hugger if any is remaining +/obj/structure/alien/egg/proc/Burst(kill = TRUE) //drops and kills the hugger if any is remaining if(status == GROWN || status == GROWING) icon_state = "egg_hatched" flick("egg_opening", src) @@ -364,45 +289,13 @@ child.Attach(M) break -/obj/structure/alien/egg/bullet_act(obj/item/projectile/Proj) - if((Proj.damage_type == BRUTE || Proj.damage_type == BURN)) - health -= Proj.damage - ..() - healthcheck() - - -/obj/structure/alien/egg/attackby(obj/item/I, mob/user, params) - if(I.attack_verb.len) - visible_message("[user] has [pick(I.attack_verb)] [src] with [I]!") - else - visible_message("[user] has attacked [src] with [I]!") - - var/damage = I.force / 4 - if(istype(I, /obj/item/weldingtool)) - var/obj/item/weldingtool/WT = I - - if(WT.remove_fuel(0, user)) - damage = 15 - playsound(loc, WT.usesound, 100, 1) - - health -= damage - user.changeNext_move(CLICK_CD_MELEE) - healthcheck() - - -/obj/structure/alien/egg/proc/healthcheck() - if(health <= 0) - if(status != BURST && status != BURSTING) - Burst() - else if(status == BURST && prob(50)) - qdel(src) //Remove the egg after it has been hit after bursting. - +/obj/structure/alien/egg/obj_break(damage_flag) + if(status != BURST) + Burst(kill = TRUE) /obj/structure/alien/egg/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) if(exposed_temperature > 500) - health -= 5 - healthcheck() - + take_damage(5, BURN, 0, 0) /obj/structure/alien/egg/HasProximity(atom/movable/AM) if(status == GROWN) 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 e5c7c2b27fb..551a8b30d9d 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/medical.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/medical.dm @@ -262,6 +262,7 @@ new /obj/item/sensor_device(src) new /obj/item/key/ambulance(src) new /obj/item/pinpointer/crew(src) + new /obj/item/clothing/shoes/magboots(src) /obj/structure/closet/secure_closet/reagents name = "chemical storage closet" diff --git a/code/game/objects/structures/fullwindow.dm b/code/game/objects/structures/fullwindow.dm deleted file mode 100644 index eec957c2d52..00000000000 --- a/code/game/objects/structures/fullwindow.dm +++ /dev/null @@ -1,116 +0,0 @@ -/obj/structure/window/full - sheets = 2 - dir=SOUTHWEST - level = 3 - -/obj/structure/window/full/CheckExit(atom/movable/O as mob|obj, target as turf) - return 1 - -/obj/structure/window/full/CanPass(atom/movable/mover, turf/target, height=0) - if(istype(mover) && mover.checkpass(PASSGLASS)) - return 1 - return 0 - -/obj/structure/window/full/is_fulltile() - return 1 - -//merges adjacent full-tile windows into one (blatant ripoff from game/smoothwall.dm) -/obj/structure/window/full/update_icon() - //A little cludge here, since I don't know how it will work with slim windows. Most likely VERY wrong. - //this way it will only update full-tile ones - //This spawn is here so windows get properly updated when one gets deleted. - spawn(2) - if(!src) return - if(!is_fulltile()) - return - var/junction = 0 //will be used to determine from which side the window is connected to other windows - if(anchored) - for(var/obj/structure/window/full/W in orange(src,1)) - if(W.anchored && W.density) //Only counts anchored, not-destroyed full-tile windows. - if(abs(x-W.x)-abs(y-W.y) ) //doesn't count windows, placed diagonally to src - junction |= get_dir(src,W) - icon_state = "[basestate][junction]" - return - -/obj/structure/window/full/basic - desc = "It looks thin and flimsy. A few knocks with... anything, really should shatter it." - icon_state = "window" - basestate = "window" - -/obj/structure/window/full/plasmabasic - name = "plasma window" - desc = "A plasma-glass alloy window. It looks insanely tough to break. It appears it's also insanely tough to burn through." - basestate = "plasmawindow" - icon_state = "plasmawindow" - shardtype = /obj/item/shard/plasma - glasstype = /obj/item/stack/sheet/plasmaglass - health = 240 - -/obj/structure/window/full/plasmabasic/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) - if(exposed_temperature > T0C + 32000) - hit(round(exposed_volume / 1000), 0) - ..() - -/obj/structure/window/full/plasmareinforced - name = "reinforced plasma window" - desc = "A plasma-glass alloy window, with rods supporting it. It looks hopelessly tough to break. It also looks completely fireproof, considering how basic plasma windows are insanely fireproof." - basestate = "plasmarwindow" - icon_state = "plasmarwindow" - shardtype = /obj/item/shard/plasma - glasstype = /obj/item/stack/sheet/plasmaglass - reinf = 1 - health = 320 - -/obj/structure/window/full/plasmareinforced/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) - return - -/obj/structure/window/full/reinforced - name = "reinforced window" - desc = "It looks rather strong. Might take a few good hits to shatter it." - icon_state = "rwindow" - basestate = "rwindow" - health = 80 - reinf = 1 - -/obj/structure/window/full/reinforced/tinted - name = "tinted window" - desc = "It looks rather strong and opaque. Might take a few good hits to shatter it." - icon_state = "twindow" - basestate = "twindow" - opacity = 1 - -/obj/structure/window/full/reinforced/tinted/frosted - name = "frosted window" - desc = "It looks rather strong and frosted over. Looks like it might take a few less hits then a normal reinforced window." - icon_state = "fwindow" - basestate = "fwindow" - health = 60 - -/obj/structure/window/full/shuttle - name = "shuttle window" - desc = "It looks rather strong. Might take a few good hits to shatter it." - icon = 'icons/obj/podwindows.dmi' - icon_state = "window" - basestate = "window" - health = 160 - reinf = 1 - explosion_block = 3 - armor = list("melee" = 50, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 50, "bio" = 100, "rad" = 100) - -/obj/structure/window/full/shuttle/New() - ..() - color = null - -/obj/structure/window/full/shuttle/update_icon() //icon_state has to be set manually - return - -/obj/structure/window/full/shuttle/shuttleRotate(rotation) - ..() - var/matrix/M = transform - M.Turn(rotation) - transform = M - -/obj/structure/window/full/shuttle/dark - icon = 'icons/turf/shuttle.dmi' - icon_state = "window5" - basestate = "window5" \ No newline at end of file diff --git a/code/game/objects/structures/grille.dm b/code/game/objects/structures/grille.dm index 0c0c3c1aa0c..b8ef71bd9c8 100644 --- a/code/game/objects/structures/grille.dm +++ b/code/game/objects/structures/grille.dm @@ -69,18 +69,23 @@ if(ismob(user)) shock(user, 70) +/obj/structure/grille/hulk_damage() + return 60 + +/obj/structure/grille/attack_hulk(mob/living/carbon/human/user, does_attack_animation = FALSE) + if(user.a_intent == INTENT_HARM) + if(!shock(user, 70)) + ..(user, TRUE) + return TRUE + /obj/structure/grille/attack_hand(mob/living/user) + . = ..() + if(.) + return user.changeNext_move(CLICK_CD_MELEE) user.do_attack_animation(src, ATTACK_EFFECT_KICK) - user.visible_message("[user] kicks [src].", \ - "You kick [src].", \ - "You hear twisting metal.") - - if(shock(user, 70)) - return - if(HULK in user.mutations) - take_damage(60, BRUTE, "melee", 1) - else + user.visible_message("[user] hits [src].") + if(!shock(user, 70)) take_damage(rand(5,10), BRUTE, "melee", 1) /obj/structure/grille/attack_alien(mob/living/user) @@ -137,7 +142,7 @@ return //window placing begin - else if(istype(W,/obj/item/stack/sheet/rglass) || istype(W,/obj/item/stack/sheet/glass) || istype(W,/obj/item/stack/sheet/plasmaglass) || istype(W,/obj/item/stack/sheet/plasmarglass)) + else if(is_glass_sheet(W)) build_window(W, user) return //window placing end @@ -190,10 +195,10 @@ S.use(1) W.setDir(dir_to_set) W.ini_dir = dir_to_set - W.anchored = 0 - W.state = 0 + W.anchored = FALSE + W.state = WINDOW_OUT_OF_FRAME to_chat(user, "You place the [W] on [src].") - W.update_icon() + W.update_nearby_icons() return /obj/structure/grille/attacked_by(obj/item/I, mob/living/user) diff --git a/code/game/objects/structures/tables_racks.dm b/code/game/objects/structures/tables_racks.dm index 4fedc99f0c5..91f348d0106 100644 --- a/code/game/objects/structures/tables_racks.dm +++ b/code/game/objects/structures/tables_racks.dm @@ -83,14 +83,7 @@ qdel(src) /obj/structure/table/attack_hand(mob/living/user) - if(HULK in user.mutations) - user.do_attack_animation(src) - visible_message("[user] smashes [src] apart!") - playsound(loc, 'sound/effects/bang.ogg', 50, 1) - user.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" )) - deconstruct(FALSE) - else - ..() + ..() if(climber) climber.Weaken(2) climber.visible_message("[climber.name] has been knocked off the table", "You've been knocked off the table", "You see [climber.name] get knocked off the table") diff --git a/code/game/objects/structures/windoor_assembly.dm b/code/game/objects/structures/windoor_assembly.dm index dcf89008416..72469e2ebfb 100644 --- a/code/game/objects/structures/windoor_assembly.dm +++ b/code/game/objects/structures/windoor_assembly.dm @@ -27,6 +27,10 @@ var/secure = FALSE //Whether or not this creates a secure windoor var/state = "01" //How far the door assembly has progressed +/obj/structure/windoor_assembly/examine(mob/user) + ..() + to_chat(user, "Alt-click to rotate it clockwise.") + obj/structure/windoor_assembly/New(loc, set_dir) ..() if(set_dir) @@ -42,7 +46,7 @@ obj/structure/windoor_assembly/Destroy() /obj/structure/windoor_assembly/Move() var/turf/T = loc - . = ..() + ..() setDir(ini_dir) move_update_air(T) @@ -54,8 +58,17 @@ obj/structure/windoor_assembly/Destroy() return 1 if(get_dir(loc, target) == dir) //Make sure looking at appropriate border return !density - else - return 1 + if(istype(mover, /obj/structure/window)) + var/obj/structure/window/W = mover + if(!valid_window_location(loc, W.ini_dir)) + return FALSE + else if(istype(mover, /obj/structure/windoor_assembly)) + var/obj/structure/windoor_assembly/W = mover + if(!valid_window_location(loc, W.ini_dir)) + return FALSE + else if(istype(mover, /obj/machinery/door/window) && !valid_window_location(loc, mover.dir)) + return FALSE + return 1 /obj/structure/windoor_assembly/CanAtmosPass(turf/T) if(get_dir(loc, T) == dir) @@ -317,9 +330,16 @@ obj/structure/windoor_assembly/Destroy() if(usr.stat || !usr.canmove || usr.restrained()) return if(anchored) - to_chat(usr, "It is fastened to the floor; therefore, you can't rotate it!") - return 0 - setDir(turn(dir, 270)) + to_chat(usr, "[src] cannot be rotated while it is fastened to the floor!") + return FALSE + var/target_dir = turn(dir, 270) + + if(!valid_window_location(loc, target_dir)) + to_chat(usr, "[src] cannot be rotated in that direction!") + return FALSE + + setDir(target_dir) + ini_dir = dir update_icon() return TRUE diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm index aebd111ad26..8a30f18f7bd 100644 --- a/code/game/objects/structures/window.dm +++ b/code/game/objects/structures/window.dm @@ -2,13 +2,14 @@ var/global/wcBar = pick(list("#0d8395", "#58b5c3", "#58c366", "#90d79a", "#fffff var/global/wcBrig = pick(list("#aa0808", "#7f0606", "#ff0000")) var/global/wcCommon = pick(list("#379963", "#0d8395", "#58b5c3", "#49e46e", "#8fcf44", "#ffffff")) -/obj/proc/color_windows(var/obj/W as obj) +/obj/proc/color_windows(obj/W) var/list/wcBarAreas = list(/area/crew_quarters/bar) var/list/wcBrigAreas = list(/area/security,/area/prison,/area/shuttle/gamma) var/newcolor var/turf/T = get_turf(W) - if(!istype(T)) return + if(!istype(T)) + return var/area/A = T.loc if(is_type_in_list(A,wcBarAreas)) @@ -23,168 +24,207 @@ var/global/wcCommon = pick(list("#379963", "#0d8395", "#58b5c3", "#49e46e", "#8f /obj/structure/window name = "window" desc = "A window." - icon = 'icons/obj/structures.dmi' - density = 1 - layer = 3.2//Just above doors + icon_state = "window" + density = TRUE + layer = ABOVE_OBJ_LAYER //Just above doors pressure_resistance = 4*ONE_ATMOSPHERE - anchored = 1.0 + anchored = TRUE flags = ON_BORDER - var/health = 14.0 + can_be_unanchored = TRUE + max_integrity = 25 var/ini_dir = null - var/state = 2 - var/reinf = 0 - var/basestate + var/state = WINDOW_OUT_OF_FRAME + var/reinf = FALSE + var/heat_resistance = 800 + var/decon_speed = null + var/fulltile = FALSE var/shardtype = /obj/item/shard - var/glasstype = /obj/item/stack/sheet/glass - var/disassembled = 0 - var/sheets = 1 // Number of sheets needed to build this window (determines how much shit is spawned by destroy()) -// var/silicate = 0 // number of units of silicate -// var/icon/silicateIcon = null // the silicated icon + var/glass_type = /obj/item/stack/sheet/glass + var/glass_amount = 1 + var/cancolor = FALSE + var/image/crack_overlay + var/list/debris = list() + var/real_explosion_block //ignore this, just use explosion_block + var/breaksound = "shatter" + var/hitsound = 'sound/effects/Glasshit.ogg' -/obj/structure/window/bullet_act(var/obj/item/projectile/Proj) - if((Proj.damage_type == BRUTE || Proj.damage_type == BURN)) - health -= Proj.damage - air_update_turf(1) +/obj/structure/window/examine(mob/user) ..() - if(health <= 0) - destroy() - return + if(reinf) + if(anchored && state == WINDOW_SCREWED_TO_FRAME) + to_chat(user, "The window is screwed to the frame.") + else if(anchored && state == WINDOW_IN_FRAME) + to_chat(user, "The window is unscrewed but pried into the frame.") + else if(anchored && state == WINDOW_OUT_OF_FRAME) + to_chat(user, "The window is out of the frame, but could be pried in. It is screwed to the floor.") + else if(!anchored) + to_chat(user, "The window is unscrewed from the floor, and could be deconstructed by wrenching.") + else + if(anchored) + to_chat(user, "The window is screwed to the floor.") + else + to_chat(user, "The window is unscrewed from the floor, and could be deconstructed by wrenching.") + if(!anchored && !fulltile) + to_chat(user, "Alt-click to rotate it clockwise.") -// This should result in the same materials used to make the window. -/obj/structure/window/proc/destroy() - for(var/i=0;i= STAGE_FIVE) - destroy() + deconstruct(FALSE) -/obj/structure/window/CheckExit(var/atom/movable/O, var/turf/target) - if(istype(O) && O.checkpass(PASSGLASS)) - return 1 - if(get_dir(O.loc, target) == dir) - return !density - return 1 +/obj/structure/window/setDir(direct) + if(!fulltile) + ..() + else + ..(FULLTILE_WINDOW_DIR) /obj/structure/window/CanPass(atom/movable/mover, turf/target, height=0) if(istype(mover) && mover.checkpass(PASSGLASS)) return 1 - if(dir == SOUTHWEST || dir == SOUTHEAST || dir == NORTHWEST || dir == NORTHEAST) + if(dir == FULLTILE_WINDOW_DIR) return 0 //full tile window, you can't move into it! if(get_dir(loc, target) == dir) return !density - else + if(istype(mover, /obj/structure/window)) + var/obj/structure/window/W = mover + if(!valid_window_location(loc, W.ini_dir)) + return FALSE + else if(istype(mover, /obj/structure/windoor_assembly)) + var/obj/structure/windoor_assembly/W = mover + if(!valid_window_location(loc, W.ini_dir)) + return FALSE + else if(istype(mover, /obj/machinery/door/window) && !valid_window_location(loc, mover.dir)) + return FALSE + return 1 + +/obj/structure/window/CheckExit(atom/movable/O, target) + if(istype(O) && O.checkpass(PASSGLASS)) return 1 + if(get_dir(O.loc, target) == dir) + return 0 + return 1 /obj/structure/window/CanAStarPass(ID, to_dir) if(!density) return 1 - if((dir == SOUTHWEST) || (dir == to_dir)) + if((dir == FULLTILE_WINDOW_DIR) || (dir == to_dir)) return 0 return 1 -/obj/structure/window/hitby(atom/movable/AM) - ..() - var/tforce = 0 - if(ismob(AM)) - tforce = 10 - else if(isobj(AM)) - var/obj/O = AM - tforce = O.throwforce - if(reinf) - tforce *= 0.25 - playsound(loc, 'sound/effects/Glasshit.ogg', 100, 1) - health = max(0, health - tforce) - if(health <= 7 && !reinf) - anchored = 0 - update_nearby_icons() - step(src, get_dir(AM, src)) - if(health <= 0) - destroy() +/obj/structure/window/attack_tk(mob/user) + user.changeNext_move(CLICK_CD_MELEE) + user.visible_message("Something knocks on [src].") + add_fingerprint(user) + playsound(src, 'sound/effects/Glassknock.ogg', 50, 1) +/obj/structure/window/attack_hulk(mob/living/carbon/human/user, does_attack_animation = 0) + if(!can_be_reached(user)) + return 1 + . = ..() -/obj/structure/window/attack_hand(mob/user as mob) - if(HULK in user.mutations) - user.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!")) - user.visible_message("[user] smashes through [src]!") - destroy() - else if(user.a_intent == INTENT_HARM) +/obj/structure/window/attack_hand(mob/user) + if(!can_be_reached(user)) + return + if(user.a_intent == INTENT_HARM) user.changeNext_move(CLICK_CD_MELEE) - playsound(get_turf(src), 'sound/effects/glassknock.ogg', 80, 1) - user.visible_message("[user.name] bangs against the [src.name]!", \ - "You bang against the [src.name]!", \ + playsound(src, 'sound/effects/glassknock.ogg', 80, 1) + user.visible_message("[user] bangs against [src]!", \ + "You bang against [src]!", \ "You hear a banging sound.") + add_fingerprint(user) else user.changeNext_move(CLICK_CD_MELEE) - playsound(src.loc, 'sound/effects/glassknock.ogg', 80, 1) - user.visible_message("[user.name] knocks on the [src.name].", \ - "You knock on the [src.name].", \ + playsound(src, 'sound/effects/glassknock.ogg', 80, 1) + user.visible_message("[user] knocks on [src].", \ + "You knock on [src].", \ "You hear a knocking sound.") - return + add_fingerprint(user) - -/obj/structure/window/attack_generic(mob/living/user, damage = 0) //used by attack_alien, attack_animal, and attack_slime - user.changeNext_move(CLICK_CD_MELEE) - user.do_attack_animation(src) - health -= damage - if(health <= 0) - user.visible_message("[user] smashes through [src]!") - destroy() - else //for nicer text~ - user.visible_message("[user] smashes into [src]!") - playsound(loc, 'sound/effects/Glasshit.ogg', 100, 1) - - -/obj/structure/window/attack_alien(mob/living/user as mob) - if(islarva(user)) return - attack_generic(user, 15) - -/obj/structure/window/attack_animal(mob/living/user as mob) - if(!isanimal(user)) return - var/mob/living/simple_animal/M = user - if(M.melee_damage_upper <= 0 || (M.melee_damage_type != BRUTE && M.melee_damage_type != BURN)) +/obj/structure/window/attack_generic(mob/user, damage_amount = 0, damage_type = BRUTE, damage_flag = 0, sound_effect = 1) //used by attack_alien, attack_animal, and attack_slime + if(!can_be_reached(user)) return - attack_generic(M, M.melee_damage_upper) + ..() +/obj/structure/window/attackby(obj/item/I, mob/living/user, params) + if(!can_be_reached(user)) + return 1 //skip the afterattack -/obj/structure/window/attack_slime(mob/living/user as mob) - var/mob/living/carbon/slime/S = user - if(!S.is_adult) + add_fingerprint(user) + + if(iswelder(I) && user.a_intent == INTENT_HELP) + var/obj/item/weldingtool/WT = I + if(obj_integrity < max_integrity) + if(WT.remove_fuel(0,user)) + to_chat(user, "You begin repairing [src]...") + playsound(src, WT.usesound, 40, 1) + if(do_after(user, 40*I.toolspeed, target = src)) + obj_integrity = max_integrity + playsound(src, 'sound/items/Welder2.ogg', 50, 1) + update_nearby_icons() + to_chat(user, "You repair [src].") + else + to_chat(user, "[src] is already in good condition!") return - attack_generic(user, rand(10, 15)) - -/obj/structure/window/attackby(obj/item/I as obj, mob/living/user as mob, params) - if(!istype(I)) - return//I really wish I did not need this - if(istype(I, /obj/item/grab) && get_dist(src,user)<2) + if(istype(I, /obj/item/grab) && get_dist(src, user) < 2) var/obj/item/grab/G = I - if(istype(G.affecting,/mob/living)) + if(isliving(G.affecting)) var/mob/living/M = G.affecting var/state = G.state qdel(I) //gotta delete it here because if window breaks, it won't get deleted @@ -192,129 +232,120 @@ var/global/wcCommon = pick(list("#379963", "#0d8395", "#58b5c3", "#49e46e", "#8f if(1) M.visible_message("[user] slams [M] against \the [src]!") M.apply_damage(7) - hit(10) + take_damage(10) if(2) M.visible_message("[user] bashes [M] against \the [src]!") if(prob(50)) M.Weaken(1) M.apply_damage(10) - hit(25) + take_damage(25) if(3) M.visible_message("[user] crushes [M] against \the [src]!") M.Weaken(5) M.apply_damage(20) - hit(50) + take_damage(50) if(4) visible_message("[user] smashes [M] against \the [src]!") M.Weaken(5) M.apply_damage(30) - hit(75) + take_damage(75) return - if(I.flags & NOBLUDGEON) - return - - if(handle_decon(I, user, is_fulltile())) - return - - if(I.damtype == BRUTE || I.damtype == BURN) - user.changeNext_move(CLICK_CD_MELEE) - hit(I.force) - if(health <= 7) - anchored = 0 - update_nearby_icons() - step(src, get_dir(user, src)) - else - playsound(loc, 'sound/effects/Glasshit.ogg', 75, 1) - ..() - -/obj/structure/window/proc/handle_decon(obj/item/W, mob/user, var/takes_time = FALSE) - //screwdriver - if(isscrewdriver(W)) - playsound(loc, W.usesound, 75, 1) - if(reinf) - if(state == 0) - if(takes_time) - to_chat(user, "You begin to [anchored ? "unfasten the frame from" : "fasten the frame to"] the floor.") - if(!do_after(user, 20 * W.toolspeed, target = src)) - return 1 - anchored = !anchored - to_chat(user, "You have [anchored? "fastened the frame to" : "unfastened the frame from"] the floor.") - if(state >= 1) - if(takes_time) - to_chat(user, "You begin to [(state == 1) ? "fasten the window to" : "unfasten the window from"] the frame.") - if(!do_after(user, 20 * W.toolspeed, target = src)) - return 1 - state = 3 - state - to_chat(user, "You have [(state == 1) ? "unfastened the window from" : "fastened the window to"] the frame.") - else - if(takes_time) - to_chat(user, "You begin to [anchored ? "unfasten the frame from" : "fasten the frame to"] the floor.") - if(!do_after(user, 20 * W.toolspeed, target = src)) - return 1 - anchored = !anchored - update_nearby_icons() - to_chat(user, "You have [anchored ? "fastened the window to" : "unfastened the window from"] the floor.") - return 1 - //crowbar - if(iscrowbar(W)) - if(!reinf || state > 1) - return 0 - playsound(loc, W.usesound, 75, 1) - if(takes_time) - to_chat(user, "You begin to pry the window [state ? "out of" : "in to"] the frame.") - if(!do_after(user, 20 * W.toolspeed, target = src)) - return 1 - state = 1 - state - to_chat(user, "You have pried the window [state ? "into" : "out of"] the frame.") - return 1 - //wrench - if(iswrench(W)) - if(anchored) - return 0 - playsound(loc, W.usesound, 50, 1) - if(takes_time) - to_chat(user, "You begin to disassemble [src]...") - if(!do_after(user, 20 * W.toolspeed, target = src)) - return 1 - for(var/i=0; i= S.max_amount) - continue - S.attackby(NS, user) + if(can_deconstruct) + if(isscrewdriver(I)) + playsound(src, I.usesound, 75, 1) if(reinf) - var/obj/item/stack/rods/NR = new (get_turf(src)) - for(var/obj/item/stack/rods/R in loc) - if(R == NR) - continue - if(R.amount >= R.max_amount) - continue - R.attackby(NR, user) + if(state == WINDOW_SCREWED_TO_FRAME || state == WINDOW_IN_FRAME) + to_chat(user, "You begin to [state == WINDOW_SCREWED_TO_FRAME ? "unscrew the window from":"screw the window to"] the frame...") + if(do_after(user, decon_speed*I.toolspeed, target = src, extra_checks = CALLBACK(src, .proc/check_state_and_anchored, state, anchored))) + state = (state == WINDOW_IN_FRAME ? WINDOW_SCREWED_TO_FRAME : WINDOW_IN_FRAME) + to_chat(user, "You [state == WINDOW_IN_FRAME ? "unfasten the window from":"fasten the window to"] the frame.") + else if(state == WINDOW_OUT_OF_FRAME) + to_chat(user, "You begin to [anchored ? "unscrew the frame from":"screw the frame to"] the floor...") + if(do_after(user, decon_speed*I.toolspeed, target = src, extra_checks = CALLBACK(src, .proc/check_state_and_anchored, state, anchored))) + anchored = !anchored + update_nearby_icons() + to_chat(user, "You [anchored ? "fasten the frame to":"unfasten the frame from"] the floor.") + else //if we're not reinforced, we don't need to check or update state + to_chat(user, "You begin to [anchored ? "unscrew the window from":"screw the window to"] the floor...") + if(do_after(user, decon_speed*I.toolspeed, target = src, extra_checks = CALLBACK(src, .proc/check_anchored, anchored))) + anchored = !anchored + air_update_turf(TRUE) + update_nearby_icons() + to_chat(user, "You [anchored ? "fasten the window to":"unfasten the window from"] the floor.") + return - to_chat(user, "You have disassembled [src].") - disassembled = 1 - density = 0 - air_update_turf(1) - update_nearby_icons() - qdel(src) - return 1 + else if(iscrowbar(I) && reinf && (state == WINDOW_OUT_OF_FRAME || state == WINDOW_IN_FRAME)) + to_chat(user, "You begin to lever the window [state == WINDOW_OUT_OF_FRAME ? "into":"out of"] the frame...") + playsound(src, I.usesound, 75, 1) + if(do_after(user, decon_speed*I.toolspeed, target = src, extra_checks = CALLBACK(src, .proc/check_state_and_anchored, state, anchored))) + state = (state == WINDOW_OUT_OF_FRAME ? WINDOW_IN_FRAME : WINDOW_OUT_OF_FRAME) + to_chat(user, "You pry the window [state == WINDOW_IN_FRAME ? "into":"out of"] the frame.") + return + + else if(iswrench(I) && !anchored) + playsound(src, I.usesound, 75, 1) + to_chat(user, " You begin to disassemble [src]...") + if(do_after(user, decon_speed*I.toolspeed, target = src, extra_checks = CALLBACK(src, .proc/check_state_and_anchored, state, anchored))) + var/obj/item/stack/sheet/G = new glass_type(user.loc, glass_amount) + G.add_fingerprint(user) + playsound(src, 'sound/items/Deconstruct.ogg', 50, 1) + to_chat(user, "You successfully disassemble [src].") + qdel(src) + return + return ..() + +/obj/structure/window/proc/check_state(checked_state) + if(state == checked_state) + return TRUE + +/obj/structure/window/proc/check_anchored(checked_anchored) + if(anchored == checked_anchored) + return TRUE + +/obj/structure/window/proc/check_state_and_anchored(checked_state, checked_anchored) + return check_state(checked_state) && check_anchored(checked_anchored) /obj/structure/window/mech_melee_attack(obj/mecha/M) - if(..()) - hit(M.force, 1) - -/obj/structure/window/proc/hit(var/damage, var/sound_effect = 1) - if(reinf) damage *= 0.5 - health = max(0, health - damage) - if(sound_effect) - playsound(loc, 'sound/effects/Glasshit.ogg', 75, 1) - if(health <= 0) - destroy() + if(!can_be_reached()) return + ..() +/obj/structure/window/proc/can_be_reached(mob/user) + if(!fulltile) + if(get_dir(user, src) & dir) + for(var/obj/O in loc) + if(!O.CanPass(user, user.loc, 1)) + return 0 + return 1 + +/obj/structure/window/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1) + . = ..() + if(.) //received damage + update_nearby_icons() + +/obj/structure/window/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0) + switch(damage_type) + if(BRUTE) + if(damage_amount) + playsound(src, hitsound, 75, 1) + else + playsound(src, 'sound/weapons/tap.ogg', 50, 1) + if(BURN) + playsound(src, 'sound/items/Welder.ogg', 100, 1) + +/obj/structure/window/deconstruct(disassembled = TRUE) + if(QDELETED(src)) + return + if(!disassembled) + playsound(src, breaksound, 70, 1) + if(can_deconstruct) + for(var/i in debris) + var/obj/item/I = i + I.forceMove(loc) + transfer_fingerprints_to(I) + qdel(src) + update_nearby_icons() /obj/structure/window/verb/rotate() set name = "Rotate Window Counter-Clockwise" @@ -325,15 +356,19 @@ var/global/wcCommon = pick(list("#379963", "#0d8395", "#58b5c3", "#49e46e", "#8f return if(anchored) - to_chat(usr, "It is fastened to the floor therefore you can't rotate it!") - return 0 + to_chat(usr, "[src] cannot be rotated while it is fastened to the floor!") + return FALSE - dir = turn(dir, 90) -// updateSilicate() + var/target_dir = turn(dir, 90) + if(!valid_window_location(loc, target_dir)) + to_chat(usr, "[src] cannot be rotated in that direction!") + return FALSE + + setDir(target_dir) air_update_turf(1) ini_dir = dir add_fingerprint(usr) - return + return TRUE /obj/structure/window/verb/revrotate() set name = "Rotate Window Clockwise" @@ -344,16 +379,19 @@ var/global/wcCommon = pick(list("#379963", "#0d8395", "#58b5c3", "#49e46e", "#8f return if(anchored) - to_chat(usr, "It is fastened to the floor therefore you can't rotate it!") - return 0 + to_chat(usr, "[src] cannot be rotated while it is fastened to the floor!") + return FALSE - dir = turn(dir, 270) -// updateSilicate() - air_update_turf(1) + var/target_dir = turn(dir, 270) + + if(!valid_window_location(loc, target_dir)) + to_chat(usr, "[src] cannot be rotated in that direction!") + return FALSE + + setDir(target_dir) ini_dir = dir add_fingerprint(usr) - return - + return TRUE /obj/structure/window/AltClick(mob/user) if(user.incapacitated()) @@ -363,158 +401,77 @@ var/global/wcCommon = pick(list("#379963", "#0d8395", "#58b5c3", "#49e46e", "#8f return revrotate() -/* -/obj/structure/window/proc/updateSilicate() - if(silicateIcon && silicate) - icon = initial(icon) - - var/icon/I = icon(icon,icon_state,dir) - - var/r = (silicate / 100) + 1 - var/g = (silicate / 70) + 1 - var/b = (silicate / 50) + 1 - I.SetIntensity(r,g,b) - icon = I - silicateIcon = I -*/ - -/obj/structure/window/New(Loc,re=0) - ..() - ini_dir = dir - if(!color && !istype(src,/obj/structure/window/plasmabasic) && !istype(src,/obj/structure/window/plasmareinforced)) - color = color_windows(src) - update_nearby_icons() - return - -/obj/structure/window/Initialize() - air_update_turf(1) - return ..() - /obj/structure/window/Destroy() - density = 0 + density = FALSE air_update_turf(1) - if(loc && !disassembled) - playsound(get_turf(src), "shatter", 70, 1) + update_nearby_icons() return ..() - /obj/structure/window/Move() var/turf/T = loc ..() - dir = ini_dir + setDir(ini_dir) move_update_air(T) -//checks if this window is full-tile one -/obj/structure/window/proc/is_fulltile() - if(dir & (dir - 1)) - return 1 - return 0 - /obj/structure/window/CanAtmosPass(turf/T) - if(get_dir(loc, T) == dir) - return !density - if(dir == SOUTHWEST || dir == SOUTHEAST || dir == NORTHWEST || dir == NORTHEAST) - return !density - return 1 + if(!anchored || !density) + return TRUE + return !(FULLTILE_WINDOW_DIR == dir || dir == get_dir(loc, T)) //This proc is used to update the icons of nearby windows. /obj/structure/window/proc/update_nearby_icons() - if(!loc) return 0 update_icon() - for(var/direction in cardinal) - for(var/obj/structure/window/W in get_step(src,direction) ) - W.update_icon() + if(smooth) + smooth_icon_neighbors(src) /obj/structure/window/update_icon() - return + if(!QDELETED(src)) + if(!fulltile) + return + var/ratio = obj_integrity / max_integrity + ratio = CEILING(ratio*4, 1) * 25 + if(smooth) + smooth_icon(src) + overlays -= crack_overlay + if(ratio > 75) + return + crack_overlay = image('icons/obj/structures.dmi',"damage[ratio]",-(layer+0.1)) + overlays += crack_overlay /obj/structure/window/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) - if(exposed_temperature > T0C + 800) - hit(round(exposed_volume / 100), 0) + if(exposed_temperature > (T0C + heat_resistance)) + take_damage(round(exposed_volume / 100), BURN, 0, 0) ..() +/obj/structure/window/GetExplosionBlock() + return reinf && fulltile ? real_explosion_block : 0 + /obj/structure/window/basic - icon_state = "window" desc = "It looks thin and flimsy. A few knocks with... anything, really should shatter it." - basestate = "window" - -/obj/structure/window/plasmabasic - name = "plasma window" - desc = "A plasma-glass alloy window. It looks insanely tough to break. It appears it's also insanely tough to burn through." - basestate = "plasmawindow" - icon_state = "plasmawindow" - shardtype = /obj/item/shard/plasma - glasstype = /obj/item/stack/sheet/plasmaglass - health = 120 - armor = list("melee" = 75, "bullet" = 5, "laser" = 0, "energy" = 0, "bomb" = 45, "bio" = 100, "rad" = 100) - -/obj/structure/window/plasmabasic/New(Loc,re=0) - ..() - ini_dir = dir - update_nearby_icons() - return - -/obj/structure/window/plasmabasic/Initialize() - ..() - air_update_turf(1) - -/obj/structure/window/plasmabasic/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) - if(exposed_temperature > T0C + 32000) - hit(round(exposed_volume / 1000), 0) - ..() - -/obj/structure/window/plasmabasic/BlockSuperconductivity() - return 1 - -/obj/structure/window/plasmareinforced - name = "reinforced plasma window" - desc = "A plasma-glass alloy window, with rods supporting it. It looks hopelessly tough to break. It also looks completely fireproof, considering how basic plasma windows are insanely fireproof." - basestate = "plasmarwindow" - icon_state = "plasmarwindow" - shardtype = /obj/item/shard/plasma - glasstype = /obj/item/stack/sheet/plasmaglass - reinf = 1 - health = 160 - armor = list("melee" = 85, "bullet" = 20, "laser" = 0, "energy" = 0, "bomb" = 60, "bio" = 100, "rad" = 100) - -/obj/structure/window/plasmareinforced/New(Loc,re=0) - ..() - ini_dir = dir - update_nearby_icons() - return - -/obj/structure/window/plasmareinforced/Initialize() - ..() - air_update_turf(1) - -/obj/structure/window/plasmareinforced/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) - return - -/obj/structure/window/plasmareinforced/BlockSuperconductivity() - return 1 //okay this SHOULD MAKE THE TOXINS CHAMBER WORK /obj/structure/window/reinforced name = "reinforced window" desc = "It looks rather strong. Might take a few good hits to shatter it." icon_state = "rwindow" - reinf = 1 - basestate = "rwindow" - health = 40 + reinf = TRUE + cancolor = TRUE + heat_resistance = 1600 armor = list("melee" = 50, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 25, "bio" = 100, "rad" = 100) + max_integrity = 50 + explosion_block = 1 + glass_type = /obj/item/stack/sheet/rglass /obj/structure/window/reinforced/tinted name = "tinted window" desc = "It looks rather strong and opaque. Might take a few good hits to shatter it." icon_state = "twindow" - basestate = "twindow" opacity = 1 /obj/structure/window/reinforced/tinted/frosted name = "frosted window" desc = "It looks rather strong and frosted over. Looks like it might take a few less hits then a normal reinforced window." icon_state = "fwindow" - basestate = "fwindow" - health = 30 + max_integrity = 30 /obj/structure/window/reinforced/polarized name = "electrochromic window" @@ -529,8 +486,6 @@ var/global/wcCommon = pick(list("#379963", "#0d8395", "#58b5c3", "#49e46e", "#8f animate(src, color="#222222", time=5) set_opacity(1) - - /obj/machinery/button/windowtint name = "window tint control" icon = 'icons/obj/power.dmi' @@ -540,7 +495,7 @@ var/global/wcCommon = pick(list("#379963", "#0d8395", "#58b5c3", "#49e46e", "#8f var/id = 0 var/active = 0 -/obj/machinery/button/windowtint/attack_hand(mob/user as mob) +/obj/machinery/button/windowtint/attack_hand(mob/user) if(..()) return 1 @@ -565,3 +520,195 @@ var/global/wcCommon = pick(list("#379963", "#0d8395", "#58b5c3", "#49e46e", "#8f /obj/machinery/button/windowtint/update_icon() icon_state = "light[active]" + +/obj/structure/window/plasmabasic + name = "plasma window" + desc = "A window made out of a plasma-silicate alloy. It looks insanely tough to break and burn through." + icon_state = "plasmawindow" + shardtype = /obj/item/shard/plasma + glass_type = /obj/item/stack/sheet/plasmaglass + heat_resistance = 32000 + max_integrity = 120 + explosion_block = 1 + armor = list("melee" = 75, "bullet" = 5, "laser" = 0, "energy" = 0, "bomb" = 45, "bio" = 100, "rad" = 100) + +/obj/structure/window/plasmabasic/BlockSuperconductivity() + return 1 + +/obj/structure/window/plasmareinforced + name = "reinforced plasma window" + desc = "A plasma-glass alloy window, with rods supporting it. It looks hopelessly tough to break. It also looks completely fireproof, considering how basic plasma windows are insanely fireproof." + icon_state = "plasmarwindow" + shardtype = /obj/item/shard/plasma + glass_type = /obj/item/stack/sheet/plasmaglass + reinf = TRUE + max_integrity = 160 + explosion_block = 2 + armor = list("melee" = 85, "bullet" = 20, "laser" = 0, "energy" = 0, "bomb" = 60, "bio" = 100, "rad" = 100) + +/obj/structure/window/plasmareinforced/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) + return + +/obj/structure/window/plasmareinforced/BlockSuperconductivity() + return 1 //okay this SHOULD MAKE THE TOXINS CHAMBER WORK + +/obj/structure/window/full + glass_amount = 2 + dir = FULLTILE_WINDOW_DIR + level = 3 + fulltile = TRUE + +/obj/structure/window/full/basic + desc = "It looks thin and flimsy. A few knocks with... anything, really should shatter it." + icon = 'icons/obj/smooth_structures/window.dmi' + icon_state = "window" + max_integrity = 50 + smooth = SMOOTH_TRUE + cancolor = TRUE + canSmoothWith = list(/obj/structure/window/full/basic, /obj/structure/window/full/reinforced, /obj/structure/window/full/reinforced/tinted, /obj/structure/window/full/plasmabasic, /obj/structure/window/full/plasmareinforced) + +/obj/structure/window/full/plasmabasic + name = "plasma window" + desc = "A plasma-glass alloy window. It looks insanely tough to break. It appears it's also insanely tough to burn through." + icon = 'icons/obj/smooth_structures/plasma_window.dmi' + icon_state = "plasmawindow" + shardtype = /obj/item/shard/plasma + glass_type = /obj/item/stack/sheet/plasmaglass + heat_resistance = 32000 + max_integrity = 240 + smooth = SMOOTH_TRUE + canSmoothWith = list(/obj/structure/window/full/basic, /obj/structure/window/full/reinforced, /obj/structure/window/full/reinforced/tinted, /obj/structure/window/full/plasmabasic, /obj/structure/window/full/plasmareinforced) + +/obj/structure/window/full/plasmareinforced + name = "reinforced plasma window" + desc = "A plasma-glass alloy window, with rods supporting it. It looks hopelessly tough to break. It also looks completely fireproof, considering how basic plasma windows are insanely fireproof." + icon = 'icons/obj/smooth_structures/rplasma_window.dmi' + icon_state = "rplasmawindow" + shardtype = /obj/item/shard/plasma + glass_type = /obj/item/stack/sheet/plasmaglass + smooth = SMOOTH_TRUE + reinf = TRUE + max_integrity = 320 + +/obj/structure/window/full/plasmareinforced/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) + return + +/obj/structure/window/full/reinforced + name = "reinforced window" + desc = "It looks rather strong. Might take a few good hits to shatter it." + icon = 'icons/obj/smooth_structures/reinforced_window.dmi' + icon_state = "r_window" + smooth = SMOOTH_TRUE + canSmoothWith = list(/obj/structure/window/full/basic, /obj/structure/window/full/reinforced, /obj/structure/window/full/reinforced/tinted, /obj/structure/window/full/plasmabasic, /obj/structure/window/full/plasmareinforced) + max_integrity = 100 + reinf = TRUE + heat_resistance = 1600 + armor = list("melee" = 50, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 25, "bio" = 100, "rad" = 100) + explosion_block = 1 + glass_type = /obj/item/stack/sheet/rglass + cancolor = TRUE + +/obj/structure/window/full/reinforced/tinted + name = "tinted window" + desc = "It looks rather strong and opaque. Might take a few good hits to shatter it." + icon = 'icons/obj/smooth_structures/tinted_window.dmi' + icon_state = "tinted_window" + opacity = 1 + +obj/structure/window/full/reinforced/ice + icon = 'icons/obj/smooth_structures/rice_window.dmi' + icon_state = "ice_window" + max_integrity = 150 + cancolor = FALSE + +/obj/structure/window/full/shuttle + name = "shuttle window" + desc = "A reinforced, air-locked pod window." + icon = 'icons/obj/smooth_structures/shuttle_window.dmi' + icon_state = "shuttle_window" + max_integrity = 160 + reinf = TRUE + heat_resistance = 1600 + explosion_block = 3 + armor = list("melee" = 50, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 50, "bio" = 100, "rad" = 100) + smooth = SMOOTH_TRUE + canSmoothWith = null + glass_type = /obj/item/stack/sheet/titaniumglass + +/obj/structure/window/full/shuttle/narsie_act() + color = "#3C3434" + +/obj/structure/window/full/shuttle/tinted + opacity = TRUE + +/obj/structure/window/plastitanium + name = "plastitanium window" + desc = "An evil looking window of plasma and titanium." + icon = 'icons/obj/smooth_structures/plastitanium_window.dmi' + icon_state = "plastitanium_window" + dir = FULLTILE_WINDOW_DIR + max_integrity = 100 + fulltile = TRUE + reinf = TRUE + heat_resistance = 1600 + armor = list("melee" = 50, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 50, "bio" = 100, "rad" = 100) + smooth = SMOOTH_TRUE + canSmoothWith = null + explosion_block = 3 + level = 3 + glass_type = /obj/item/stack/sheet/plastitaniumglass + glass_amount = 2 + +/obj/structure/window/reinforced/clockwork + name = "brass window" + desc = "A paper-thin pane of translucent yet reinforced brass." + icon = 'icons/obj/smooth_structures/clockwork_window.dmi' + icon_state = "clockwork_window_single" + burn_state = FIRE_PROOF + unacidable = 1 + max_integrity = 80 + armor = list("melee" = 60, "bullet" = 25, "laser" = 0, "energy" = 0, "bomb" = 25, "bio" = 100, "rad" = 100) + explosion_block = 2 //fancy AND hard to destroy. the most useful combination. + glass_type = /obj/item/stack/tile/brass + reinf = FALSE + cancolor = FALSE + var/made_glow = FALSE + +/obj/structure/window/reinforced/clockwork/New(loc, direct) + if(fulltile) + made_glow = TRUE + ..() + QDEL_LIST(debris) + if(fulltile) + new /obj/effect/temp_visual/ratvar/window(get_turf(src)) + debris += new/obj/item/stack/tile/brass(src, 2) + else + debris += new/obj/item/stack/tile/brass(src, 1) + +/obj/structure/window/reinforced/clockwork/setDir(direct) + if(!made_glow) + var/obj/effect/E = new /obj/effect/temp_visual/ratvar/window/single(get_turf(src)) + E.setDir(direct) + made_glow = TRUE + ..() + +/obj/structure/window/reinforced/clockwork/ratvar_act() + obj_integrity = max_integrity + update_icon() + +/obj/structure/window/reinforced/clockwork/narsie_act() + take_damage(rand(25, 75), BRUTE) + if(src) + var/previouscolor = color + color = "#960000" + animate(src, color = previouscolor, time = 8) + +/obj/structure/window/reinforced/clockwork/fulltile + icon_state = "clockwork_window" + smooth = SMOOTH_TRUE + canSmoothWith = null + fulltile = TRUE + dir = FULLTILE_WINDOW_DIR + max_integrity = 120 + level = 3 + glass_amount = 2 \ No newline at end of file diff --git a/code/game/response_team.dm b/code/game/response_team.dm index a865e4a5ad9..c59dd7bd78f 100644 --- a/code/game/response_team.dm +++ b/code/game/response_team.dm @@ -203,13 +203,13 @@ var/ert_request_answered = 0 var/cyborg_unlock = 0 /datum/response_team/proc/setSlots(com, sec, med, eng, jan, par, cyb) - command_slots = com || command_slots - security_slots = sec || security_slots - medical_slots = med || medical_slots - engineer_slots = eng || engineer_slots - janitor_slots = jan || janitor_slots - paranormal_slots = par || paranormal_slots - cyborg_slots = cyb || cyborg_slots + command_slots = com == null ? command_slots : com + security_slots = sec == null ? security_slots : sec + medical_slots = med == null ? medical_slots : med + engineer_slots = eng == null ? engineer_slots : eng + janitor_slots = jan == null ? janitor_slots : jan + paranormal_slots = par == null ? paranormal_slots : par + cyborg_slots = cyb == null ? cyborg_slots : cyb /datum/response_team/proc/reduceCyborgSlots() cyborg_slots-- diff --git a/code/game/turfs/simulated/walls.dm b/code/game/turfs/simulated/walls.dm index b1cbf84493f..db85329f8c1 100644 --- a/code/game/turfs/simulated/walls.dm +++ b/code/game/turfs/simulated/walls.dm @@ -214,7 +214,7 @@ //Interactions -/turf/simulated/wall/attack_animal(var/mob/living/simple_animal/M) +/turf/simulated/wall/attack_animal(mob/living/simple_animal/M) M.changeNext_move(CLICK_CD_MELEE) M.do_attack_animation(src) if((M.environment_smash & ENVIRONMENT_SMASH_WALLS) || (M.environment_smash & ENVIRONMENT_SMASH_RWALLS)) @@ -229,20 +229,19 @@ to_chat(M, "You push the wall but nothing happens!") return -/turf/simulated/wall/attack_hand(mob/user as mob) - user.changeNext_move(CLICK_CD_MELEE) - if(HULK in user.mutations) - if(prob(hardness) || rotting) - playsound(src, 'sound/effects/meteorimpact.ogg', 100, 1) - to_chat(user, text("You smash through the wall.")) - user.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" )) - dismantle_wall(1) - return - else - playsound(src, 'sound/effects/bang.ogg', 50, 1) - to_chat(user, text("You punch the wall.")) - return +/turf/simulated/wall/attack_hulk(mob/user, does_attack_animation = FALSE) + ..(user, TRUE) + if(prob(hardness) || rotting) + playsound(src, 'sound/effects/meteorimpact.ogg', 100, 1) + user.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" )) + dismantle_wall(TRUE) + else + playsound(src, 'sound/effects/bang.ogg', 50, 1) + to_chat(user, text("You punch the wall.")) + return TRUE +/turf/simulated/wall/attack_hand(mob/user) + user.changeNext_move(CLICK_CD_MELEE) if(rotting) if(hardness <= 10) to_chat(user, "This wall feels rather unstable.") @@ -254,183 +253,169 @@ to_chat(user, "You push the wall but nothing happens!") playsound(src, 'sound/weapons/Genhit.ogg', 25, 1) - src.add_fingerprint(user) - ..() - return + add_fingerprint(user) + return ..() -/turf/simulated/wall/attackby(obj/item/W as obj, mob/user as mob, params) +/turf/simulated/wall/attackby(obj/item/I, mob/user, params) user.changeNext_move(CLICK_CD_MELEE) - if(!user.IsAdvancedToolUser()) - to_chat(user, "You don't have the dexterity to do this!") + + if(!isturf(user.loc)) + return // No touching walls unless you're on a turf (pretty sure attackby can't be called anyways but whatever) + + if(rotting && try_rot(I, user, params)) return - //get the user's location - if(!istype(user.loc, /turf)) - return //can't do this stuff whilst inside objects and such + if(thermite && try_thermite(I, user, params)) + return - if(rotting) - if(istype(W, /obj/item/weldingtool) ) - var/obj/item/weldingtool/WT = W - if(WT.remove_fuel(0,user)) - to_chat(user, "You burn away the fungi with \the [WT].") - playsound(src, WT.usesound, 10, 1) - for(var/obj/effect/overlay/wall_rot/WR in src) - qdel(WR) - rotting = 0 - return - else if(!is_sharp(W) && W.force >= 10 || W.force >= 20) - to_chat(user, "\The [src] crumbles away under the force of your [W.name].") - src.dismantle_wall(1) - return + if(try_decon(I, user, params)) + return - //THERMITE related stuff. Calls src.thermitemelt() which handles melting simulated walls and the relevant effects - if(thermite) - if(istype(W, /obj/item/weldingtool)) - var/obj/item/weldingtool/WT = W - if(WT.remove_fuel(0,user)) - thermitemelt(user) - return + if(try_destroy(I, user, params)) + return - else if(istype(W, /obj/item/gun/energy/plasmacutter)) + 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 + + return ..() + +/turf/simulated/wall/proc/try_rot(obj/item/I, mob/user, params) + if(iswelder(I)) + var/obj/item/weldingtool/WT = I + if(WT.remove_fuel(0, user)) + to_chat(user, "You burn away the fungi with [WT].") + playsound(src, WT.usesound, 10, 1) + for(var/obj/effect/overlay/wall_rot/WR in src) + qdel(WR) + rotting = 0 + return TRUE + else if((!is_sharp(I) && I.force >= 10) || I.force >= 20) + to_chat(user, "[src] crumbles away under the force of your [I.name].") + dismantle_wall(1) + return TRUE + return FALSE + +/turf/simulated/wall/proc/try_thermite(obj/item/I, mob/user, params) + if(iswelder(I)) + var/obj/item/weldingtool/WT = I + if(WT.remove_fuel(0, user)) thermitemelt(user) - return + return TRUE - else if(istype(W, /obj/item/melee/energy/blade)) - var/obj/item/melee/energy/blade/EB = W + else if(istype(I, /obj/item/gun/energy/plasmacutter)) + thermitemelt(user) + return TRUE - EB.spark_system.start() - to_chat(user, "You slash \the [src] with \the [EB]; the thermite ignites!") - playsound(src, "sparks", 50, 1) - playsound(src, EB.usesound, 50, 1) - thermitemelt(user) - return + return FALSE - //DECONSTRUCTION - if(istype(W, /obj/item/weldingtool)) +/turf/simulated/wall/proc/try_decon(obj/item/I, mob/user, params) + if(iswelder(I)) + var/obj/item/weldingtool/WT = I + if(!WT.remove_fuel(0, user)) + to_chat(user, "You need more welding fuel to complete this task.") + return TRUE // this means "don't continue trying to find alternative uses in attackby", not "decon succeeded" var/response = "Dismantle" if(damage) response = alert(user, "Would you like to repair or dismantle [src]?", "[src]", "Repair", "Dismantle") - var/obj/item/weldingtool/WT = W - - if(WT.remove_fuel(0,user)) - if(response == "Repair") + switch(response) + if("Repair") to_chat(user, "You start repairing the damage to [src].") 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].") take_damage(-damage) - - else if(response == "Dismantle") + else to_chat(user, "You begin slicing through the outer plating.") playsound(src, WT.usesound, 100, 1) if(do_after(user, 100 * WT.toolspeed, target = src) && WT && WT.isOn()) to_chat(user, "You remove the outer plating.") dismantle_wall() - else to_chat(user, "You stop slicing through [src].") - return - - else - to_chat(user, "You need more welding fuel to complete this task.") - return - - else if(istype(W, /obj/item/gun/energy/plasmacutter)) + return TRUE + else if(istype(I, /obj/item/gun/energy/plasmacutter)) to_chat(user, "You begin slicing through the outer plating.") - playsound(src, W.usesound, 100, 1) + playsound(src, I.usesound, 100, 1) - if(do_after(user, istype(sheet_type, /obj/item/stack/sheet/mineral/diamond) ? 120 * W.toolspeed : 60 * W.toolspeed, target = src)) + if(do_after(user, istype(sheet_type, /obj/item/stack/sheet/mineral/diamond) ? 120 * I.toolspeed : 60 * I.toolspeed, target = src)) to_chat(user, "You remove the outer plating.") dismantle_wall() - visible_message("[user] slices apart \the [src]!","You hear metal being sliced apart.") + visible_message("[user] slices apart [src]!", "You hear metal being sliced apart.") + return TRUE - //DRILLING - else if(istype(W, /obj/item/pickaxe/drill/diamonddrill)) + return FALSE +/turf/simulated/wall/proc/try_destroy(obj/item/I, mob/user, params) + var/isdiamond = istype(sheet_type, /obj/item/stack/sheet/mineral/diamond) // snowflake bullshit + + if(istype(I, /obj/item/pickaxe/drill/diamonddrill)) to_chat(user, "You begin to drill though the wall.") - if(do_after(user, istype(sheet_type, /obj/item/stack/sheet/mineral/diamond) ? 480 * W.toolspeed : 240 * W.toolspeed, target = src)) // Diamond pickaxe has 0.25 toolspeed, so 120/60 - to_chat(user, "Your drill tears though the last of the reinforced plating.") + if(do_after(user, isdiamond ? 480 * I.toolspeed : 240 * I.toolspeed, target = src)) // Diamond pickaxe has 0.25 toolspeed, so 120/60 + to_chat(user, "Your [I.name] tears though the last of the reinforced plating.") dismantle_wall() - visible_message("[user] drills through \the [src]!","You hear the grinding of metal.") - - else if(istype(W, /obj/item/pickaxe/drill/jackhammer)) + visible_message("[user] drills through [src]!", "You hear the grinding of metal.") + return TRUE + else if(istype(I, /obj/item/pickaxe/drill/jackhammer)) to_chat(user, "You begin to disintegrates the wall.") - if(do_after(user, istype(sheet_type, /obj/item/stack/sheet/mineral/diamond) ? 600 * W.toolspeed : 300 * W.toolspeed, target = src)) // Jackhammer has 0.1 toolspeed, so 60/30 - to_chat(user, "Your sonic jackhammer disintegrate the reinforced plating.") + if(do_after(user, isdiamond ? 600 * I.toolspeed : 300 * I.toolspeed, target = src)) // Jackhammer has 0.1 toolspeed, so 60/30 + to_chat(user, "Your [I.name] disintegrates the reinforced plating.") dismantle_wall() - visible_message("[user] disintegrates \the [src]!","You hear the grinding of metal.") + visible_message("[user] disintegrates [src]!","You hear the grinding of metal.") + return TRUE - else if(istype(W, /obj/item/melee/energy/blade)) - var/obj/item/melee/energy/blade/EB = W + return FALSE - EB.spark_system.start() - to_chat(user, "You stab \the [EB] into the wall and begin to slice it apart.") - playsound(src, "sparks", 50, 1) +/turf/simulated/wall/proc/try_wallmount(obj/item/I, mob/user, params) + if(istype(I, /obj/item/mounted)) + return TRUE // We don't want attack_hand running and doing stupid shit with this - if(do_after(user, istype(sheet_type, /obj/item/stack/sheet/mineral/diamond) ? 140 * EB.toolspeed : 70 * EB.toolspeed, target = src)) - EB.spark_system.start() - playsound(src, "sparks", 50, 1) - playsound(src, EB.usesound, 50, 1) - dismantle_wall(1) - visible_message("[user] slices apart \the [src]!","You hear metal being sliced apart and sparks flying.") - - else if(istype(W,/obj/item/mounted)) //if we place it, we don't want to have a silly message - return - - //Poster stuff - else if(istype(W, /obj/item/poster)) - place_poster(W, user) - return - - //Bone White - Place pipes on walls - else if(istype(W,/obj/item/pipe)) - var/obj/item/pipe/V = W - if(V.pipe_type != -1) // ANY PIPE - var/obj/item/pipe/P = W + if(istype(I, /obj/item/poster)) + place_poster(I, user) + return TRUE + //Bone White - Place pipes on walls // I fucking hate your code with a passion bone + if(istype(I, /obj/item/pipe)) + var/obj/item/pipe/P = I + if(P.pipe_type != -1) // ANY PIPE playsound(get_turf(src), 'sound/weapons/circsawhit.ogg', 50, 1) - user.visible_message( \ - "[user] starts drilling a hole in \the [src].", \ - "You start drilling a hole in \the [src].", \ - "You hear ratchet.") - if(do_after(user, 80 * W.toolspeed, target = src)) - user.visible_message( \ - "[user] drills a hole in \the [src] and pushes \a [P] into the void", \ - "You have finished drilling in \the [src] and push the [P] into the void.", \ - "You hear ratchet.") + user.visible_message( + "[user] starts drilling a hole in [src].", + "You start drilling a hole in [src].", + "You hear a drill.") + + if(do_after(user, 80 * P.toolspeed, target = src)) + user.visible_message( + "[user] drills a hole in [src] and pushes [P] into the void.", + "You finish drilling [src] and push [P] into the void.", + "You hear a ratchet.") user.drop_item() if(P.is_bent_pipe()) // bent pipe rotation fix see construction.dm - P.dir = 5 + P.setDir(5) if(user.dir == 1) - P.dir = 6 + P.setDir(6) else if(user.dir == 2) - P.dir = 9 + P.setDir(9) else if(user.dir == 4) - P.dir = 10 + P.setDir(10) else - P.dir = user.dir - P.x = src.x - P.y = src.y - P.z = src.z - P.loc = src + P.setDir(user.dir) + P.forceMove(src) P.level = 2 - return - // The magnetic gripper does a separate attackby, so bail from this one - else if(istype(W, /obj/item/gripper)) - return - - else - return attack_hand(user) - return + return TRUE + return FALSE /turf/simulated/wall/singularity_pull(S, current_size) if(current_size >= STAGE_FIVE) diff --git a/code/game/turfs/simulated/walls_reinforced.dm b/code/game/turfs/simulated/walls_reinforced.dm index 827791be76d..eb054ba19ed 100644 --- a/code/game/turfs/simulated/walls_reinforced.dm +++ b/code/game/turfs/simulated/walls_reinforced.dm @@ -33,333 +33,256 @@ if(RWALL_SHEATH) to_chat(user, "The support rods have been sliced through, and the outer sheath is connected loosely to the girder.") -/turf/simulated/wall/r_wall/attackby(obj/item/W, mob/user, params) - user.changeNext_move(CLICK_CD_MELEE) - if(!user.IsAdvancedToolUser()) - to_chat(user, "You don't have the dexterity to do this!") +/turf/simulated/wall/r_wall/attackby(obj/item/I, mob/user, params) + if(try_repair(I, user, params)) return + return ..() - //get the user's location - if(!isturf(user.loc)) - return //can't do this stuff whilst inside objects and such - - if(rotting) - if(iswelder(W)) - var/obj/item/weldingtool/WT = W - if(WT.remove_fuel(0,user)) - to_chat(user, "You burn away the fungi with \the [WT].") - playsound(src, WT.usesound, 10, 1) - for(var/obj/effect/overlay/wall_rot/WR in src) - qdel(WR) - rotting = 0 - return - else if(!is_sharp(W) && W.force >= 10 || W.force >= 20) - to_chat(user, "\The [src] crumbles away under the force of your [W.name].") - dismantle_wall() - return - - //THERMITE related stuff. Calls src.thermitemelt() which handles melting simulated walls and the relevant effects - if(thermite) - if(iswelder(W)) - var/obj/item/weldingtool/WT = W - if(WT.remove_fuel(0,user)) - thermitemelt(user) - return - - else if(istype(W, /obj/item/gun/energy/plasmacutter)) - thermitemelt(user) - return - - else if(istype(W, /obj/item/melee/energy/blade)) - var/obj/item/melee/energy/blade/EB = W - - EB.spark_system.start() - to_chat(user, "You slash \the [src] with \the [EB]; the thermite ignites!") - playsound(src, "sparks", 50, 1) - playsound(src, EB.usesound, 50, 1) - - thermitemelt(user) - return - - else if(istype(W, /obj/item/melee/energy/blade)) - to_chat(user, "This wall is too thick to slice through. You will need to find a different path.") - return - - if(damage && iswelder(W)) - var/obj/item/weldingtool/WT = W - if(WT.remove_fuel(0,user)) - to_chat(user, "You start repairing the damage to [src].") - 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].") - take_damage(-damage) - return - else +/turf/simulated/wall/r_wall/proc/try_repair(obj/item/I, mob/user, params) + if(damage && iswelder(I)) + var/obj/item/weldingtool/WT = I + if(!WT.remove_fuel(0, user)) to_chat(user, "You need more welding fuel to complete this task.") - return + return TRUE + to_chat(user, "You start repairing the damage to [src].") + 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].") + take_damage(-damage) + return TRUE - //DECONSTRUCTION - switch(d_state) - if(RWALL_INTACT) - if(iswirecutter(W)) - playsound(src, W.usesound, 100, 1) - d_state = RWALL_SUPPORT_LINES + if(d_state) + // Repairing + if(istype(I, /obj/item/stack/sheet/metal)) + var/obj/item/stack/sheet/metal/MS = I + + to_chat(user, "You begin patching-up the wall with [MS]...") + if(do_after(user, max(20 * d_state, 100) * MS.toolspeed, target = src) && d_state) + if(!MS.use(1)) + to_chat(user, "You don't have enough [MS.name] for that!") + return TRUE + + d_state = RWALL_INTACT update_icon() - new /obj/item/stack/rods(src) - to_chat(user, "You cut the outer grille.") - return + smooth_icon_neighbors(src) + to_chat(user, "You repair the last of the damage.") - if(RWALL_SUPPORT_LINES) - if(isscrewdriver(W)) - to_chat(user, "You begin unsecuring the support lines...") - playsound(src, W.usesound, 100, 1) + return TRUE - if(do_after(user, 40 * W.toolspeed, target = src) && d_state == RWALL_SUPPORT_LINES) - d_state = RWALL_COVER - update_icon() - to_chat(user, "You unsecure the support lines.") - return - - //REPAIRING (replacing the outer grille for cosmetic damage) - else if(istype(W, /obj/item/stack/rods)) - var/obj/item/stack/O = W - if(O.use(1)) - d_state = RWALL_INTACT - update_icon() - icon_state = "r_wall" - update_icon() - to_chat(user, "You replace the outer grille.") - else - to_chat(user, "You don't have enough rods for that!") - - if(RWALL_COVER) - if(iswelder(W)) - var/obj/item/weldingtool/WT = W - if(WT.remove_fuel(0,user)) - to_chat(user, "You begin slicing through the metal cover...") - playsound(src, WT.usesound, 100, 1) - - if(do_after(user, 60 * WT.toolspeed, target = src) && d_state == RWALL_COVER) - d_state = RWALL_CUT_COVER - update_icon() - to_chat(user, "You press firmly on the cover, dislodging it.") - - else - to_chat(user, "You need more welding fuel to complete this task.") - return - - if(istype(W, /obj/item/gun/energy/plasmacutter)) - to_chat(user, "You begin slicing through the metal cover...") - playsound(src, W.usesound, 100, 1) - - if(do_after(user, 40 * W.toolspeed, target = src) && d_state == RWALL_COVER) - d_state = RWALL_CUT_COVER - update_icon() - to_chat(user, "You press firmly on the cover, dislodging it.") - return - - if(isscrewdriver(W)) - to_chat(user, "You begin securing the support lines...") - playsound(src, W.usesound, 100, 1) - if(do_after(user, 40*W.toolspeed, target = src)) - if(!istype(src, /turf/simulated/wall/r_wall) || !W || d_state != RWALL_COVER) - return 1 - d_state = RWALL_SUPPORT_LINES - update_icon() - to_chat(user, "The support lines have been secured.") - return 1 - - if(RWALL_CUT_COVER) - if(iscrowbar(W)) - to_chat(user, "You struggle to pry off the cover...") - playsound(src, W.usesound, 100, 1) - - if(do_after(user, 100 * W.toolspeed, target = src) && d_state == RWALL_CUT_COVER) - d_state = RWALL_BOLTS - update_icon() - to_chat(user, "You pry off the cover.") - return - - if(iswelder(W)) - var/obj/item/weldingtool/WT = W - if(WT.remove_fuel(0,user)) - to_chat(user, "You begin welding the metal cover back to the frame...") - playsound(src, WT.usesound, 100, 1) - if(do_after(user, 60*WT.toolspeed, target = src)) - if(!istype(src, /turf/simulated/wall/r_wall) || !WT || !WT.isOn() || d_state != RWALL_CUT_COVER) - return 1 - d_state = RWALL_COVER - update_icon() - to_chat(user, "The metal cover has been welded securely to the frame.") - return 1 - - if(RWALL_BOLTS) - if(iswrench(W)) - to_chat(user, "You start loosening the anchoring bolts which secure the support rods to their frame...") - playsound(src, W.usesound, 100, 1) - - if(do_after(user, 40 * W.toolspeed, target = src) && d_state == RWALL_BOLTS) - d_state = RWALL_SUPPORT_RODS - update_icon() - to_chat(user, "You remove the bolts anchoring the support rods.") - return - - if(iscrowbar(W)) - to_chat(user, "You start to pry the cover back into place...") - playsound(src, W.usesound, 100, 1) - if(do_after(user, 20*W.toolspeed, target = src)) - if(!istype(src, /turf/simulated/wall/r_wall) || !W || d_state != RWALL_BOLTS) - return 1 - d_state = RWALL_CUT_COVER - update_icon() - to_chat(user, "The metal cover has been pried back into place.") - return 1 - - if(RWALL_SUPPORT_RODS) - if(iswelder(W)) - var/obj/item/weldingtool/WT = W - if(WT.remove_fuel(0,user)) - to_chat(user, "You begin slicing through the support rods...") - playsound(src, WT.usesound, 100, 1) - - if(do_after(user, 100 * WT.toolspeed, target = src) && d_state == RWALL_SUPPORT_RODS) - d_state = RWALL_SHEATH - update_icon() - else - to_chat(user, "You need more welding fuel to complete this task.") - return - - if(istype(W, /obj/item/gun/energy/plasmacutter)) - to_chat(user, "You begin slicing through the support rods...") - playsound(src, W.usesound, 100, 1) - - if(do_after(user, 70 * W.toolspeed, target = src) && d_state == RWALL_SUPPORT_RODS) - d_state = RWALL_SHEATH - update_icon() - return - - if(iswrench(W)) - to_chat(user, "You start tightening the bolts which secure the support rods to their frame...") - playsound(src, W.usesound, 100, 1) - if(do_after(user, 40*W.toolspeed, target = src)) - if(!istype(src, /turf/simulated/wall/r_wall) || !W || d_state != RWALL_SUPPORT_RODS) - return 1 - d_state = RWALL_BOLTS - update_icon() - to_chat(user, "You tighten the bolts anchoring the support rods.") - return 1 - - if(RWALL_SHEATH) - if(iscrowbar(W)) - to_chat(user, "You struggle to pry off the outer sheath...") - playsound(src, W.usesound, 100, 1) - - if(do_after(user, 100 * W.toolspeed, target = src) && d_state == RWALL_SHEATH) - to_chat(user, "You pry off the outer sheath.") - dismantle_wall() - return - -//vv OK, we weren't performing a valid deconstruction step or igniting thermite,let's check the other possibilities vv - - //DRILLING - if(istype(W, /obj/item/pickaxe/drill/diamonddrill)) - to_chat(user, "You begin to drill though the wall...") - - if(do_after(user, 800 * W.toolspeed, target = src)) // Diamond drill has 0.25 toolspeed, so 200 - to_chat(user, "Your drill tears through the last of the reinforced plating.") - dismantle_wall() - - if(istype(W,/obj/item/pickaxe/drill/jackhammer)) - to_chat(user, "You begin to disintegrate the wall...") - - if(do_after(user, 1000 * W.toolspeed, target = src)) // Jackhammer has 0.1 toolspeed, so 100 - to_chat(user, "Your sonic jackhammer disintegrates the reinforced plating.") - dismantle_wall() - - //REPAIRING - else if(istype(W, /obj/item/stack/sheet/metal) && d_state) - var/obj/item/stack/sheet/metal/MS = W - - to_chat(user, "You begin patching-up the wall with \a [MS]...") - - if(do_after(user, max(20 * d_state, 100) * MS.toolspeed, target = src) && d_state) - if(!MS.use(1)) - to_chat(user, "You don't have enough metal for that!") - return - - d_state = RWALL_INTACT - update_icon() - smooth_icon_neighbors(src) - to_chat(user, "You repair the last of the damage.") - - //UPGRADING TO COATED - else if(istype(W, /obj/item/stack/sheet/plasteel) && !d_state) - var/obj/item/stack/sheet/plasteel/MS = W + else if(istype(I, /obj/item/stack/sheet/plasteel)) + var/obj/item/stack/sheet/plasteel/PS = I if(!can_be_reinforced) to_chat(user, "The wall is already coated!") - return - to_chat(user, "You begin adding an additional layer of coating to the wall with \a [MS]...") + return FALSE - if(do_after(user, 40 * MS.toolspeed, target = src) && !d_state) - if(!MS.use(2)) - to_chat(user, "You don't have enough plasteel for that!") + to_chat(user, "You begin adding an additional layer of coating to the wall with [PS]...") + if(do_after(user, 40 * PS.toolspeed, target = src) && !d_state) + if(!PS.use(2)) + to_chat(user, "You don't have enough [PS.name] for that!") return to_chat(user, "You add an additional layer of coating to the wall.") ChangeTurf(/turf/simulated/wall/r_wall/coated) update_icon() smooth_icon_neighbors(src) - can_be_reinforced = 0 - return + can_be_reinforced = FALSE + return TRUE + return FALSE - //APC - else if(istype(W,/obj/item/mounted)) - return - //Poster stuff - else if(istype(W, /obj/item/poster)) - place_poster(W, user) - return +/turf/simulated/wall/r_wall/try_decon(obj/item/I, mob/user, params) + switch(d_state) + if(RWALL_INTACT) + // RWALL_INTACT > RWALL_SUPPORT_LINES + if(iswirecutter(I)) + playsound(src, I.usesound, 100, 1) + d_state = RWALL_SUPPORT_LINES + update_icon() + new /obj/item/stack/rods(src) + to_chat(user, "You cut the outer grille.") + return TRUE - //Bone White - Place pipes on walls - else if(istype(W,/obj/item/pipe)) - var/obj/item/pipe/V = W - if(V.pipe_type != -1) // ANY PIPE - var/obj/item/pipe/P = W + if(RWALL_SUPPORT_LINES) + // RWALL_SUPPORT_LINES > RWALL_COVER + if(isscrewdriver(I)) + to_chat(user, "You begin unsecuring the support lines...") + playsound(src, I.usesound, 100, 1) - playsound(get_turf(src), 'sound/weapons/circsawhit.ogg', 50, 1) - user.visible_message( \ - "[user] starts drilling a hole in \the [src]...", \ - "You start drilling a hole in \the [src]. This is going to take a while.", \ - "You hear ratchet.") - if(do_after(user, 160 * V.toolspeed, target = src)) - user.visible_message( \ - "[user] drills a hole in \the [src] and pushes \a [P] into the void.", \ - "You have finished drilling in \the [src] and push the [P] into the void.", \ - "You hear ratchet.") + if(do_after(user, 40 * I.toolspeed, target = src) && d_state == RWALL_SUPPORT_LINES) + d_state = RWALL_COVER + update_icon() + to_chat(user, "You unsecure the support lines.") + return TRUE - user.drop_item() - if(P.is_bent_pipe()) // bent pipe rotation fix see construction.dm - P.dir = 5 - if(user.dir == 1) - P.dir = 6 - else if(user.dir == 2) - P.dir = 9 - else if(user.dir == 4) - P.dir = 10 + // RWALL_INTACT < RWALL_SUPPORT_LINES + if(istype(I, /obj/item/stack/rods)) + var/obj/item/stack/S = I + if(S.use(1)) + d_state = RWALL_INTACT + update_icon() + to_chat(user, "You replace the outer grille.") else - P.dir = user.dir - P.x = src.x - P.y = src.y - P.z = src.z - P.loc = src - P.level = 2 - return + to_chat(user, "You don't have enough rods for that!") + return TRUE + + if(RWALL_COVER) + // RWALL_COVER > RWALL_CUT_COVER + if(iswelder(I)) + var/obj/item/weldingtool/WT = I + if(!WT.remove_fuel(0, user)) + to_chat(user, "You need more welding fuel to complete this task.") + return TRUE + + to_chat(user, "You begin slicing through the metal cover...") + playsound(src, WT.usesound, 100, 1) + + if(do_after(user, 60 * WT.toolspeed, target = src) && d_state == RWALL_COVER) + d_state = RWALL_CUT_COVER + update_icon() + to_chat(user, "You press firmly on the cover, dislodging it.") + return TRUE + + // RWALL_COVER > RWALL_CUT_COVER + if(istype(I, /obj/item/gun/energy/plasmacutter)) + to_chat(user, "You begin slicing through the metal cover...") + playsound(src, I.usesound, 100, 1) + + if(do_after(user, 40 * I.toolspeed, target = src) && d_state == RWALL_COVER) + d_state = RWALL_CUT_COVER + update_icon() + to_chat(user, "You press firmly on the cover, dislodging it.") + return TRUE + + // RWALL_SUPPORT_LINES < RWALL_COVER + if(isscrewdriver(I)) + to_chat(user, "You begin securing the support lines...") + playsound(src, I.usesound, 100, 1) + if(do_after(user, 40 * I.toolspeed, target = src)) + if(!istype(src, /turf/simulated/wall/r_wall) || !I || d_state != RWALL_COVER) + return TRUE + d_state = RWALL_SUPPORT_LINES + update_icon() + to_chat(user, "The support lines have been secured.") + return TRUE + + if(RWALL_CUT_COVER) + // RWALL_CUT_COVER > RWALL_BOLTS + if(iscrowbar(I)) + to_chat(user, "You struggle to pry off the cover...") + playsound(src, I.usesound, 100, 1) + + if(do_after(user, 100 * I.toolspeed, target = src) && d_state == RWALL_CUT_COVER) + d_state = RWALL_BOLTS + update_icon() + to_chat(user, "You pry off the cover.") + return TRUE + + // RWALL_COVER < RWALL_CUT_COVER + if(iswelder(I)) + var/obj/item/weldingtool/WT = I + if(!WT.remove_fuel(0, user)) + return TRUE + + to_chat(user, "You begin welding the metal cover back to the frame...") + playsound(src, WT.usesound, 100, 1) + if(do_after(user, 60 * WT.toolspeed, target = src)) + if(!istype(src, /turf/simulated/wall/r_wall) || !WT || !WT.isOn() || d_state != RWALL_CUT_COVER) + return TRUE + d_state = RWALL_COVER + update_icon() + to_chat(user, "The metal cover has been welded securely to the frame.") + return TRUE + + if(RWALL_BOLTS) + // RWALL_BOLTS > RWALL_SUPPORT_RODS + if(iswrench(I)) + to_chat(user, "You start loosening the anchoring bolts which secure the support rods to their frame...") + playsound(src, I.usesound, 100, 1) + + if(do_after(user, 40 * I.toolspeed, target = src) && d_state == RWALL_BOLTS) + d_state = RWALL_SUPPORT_RODS + update_icon() + to_chat(user, "You remove the bolts anchoring the support rods.") + return TRUE + + // RWALL_CUT_COVER < RWALL_BOLTS + if(iscrowbar(I)) + to_chat(user, "You start to pry the cover back into place...") + playsound(src, I.usesound, 100, 1) + if(do_after(user, 20 * I.toolspeed, target = src)) + if(!istype(src, /turf/simulated/wall/r_wall) || !I || d_state != RWALL_BOLTS) + return TRUE + d_state = RWALL_CUT_COVER + update_icon() + to_chat(user, "The metal cover has been pried back into place.") + return TRUE + + if(RWALL_SUPPORT_RODS) + // RWALL_SUPPORT_RODS > RWALL_SHEATH + if(iswelder(I)) + var/obj/item/weldingtool/WT = I + if(!WT.remove_fuel(0, user)) + to_chat(user, "You need more welding fuel to complete this task.") + return TRUE + + to_chat(user, "You begin slicing through the support rods...") + playsound(src, WT.usesound, 100, 1) + + if(do_after(user, 100 * WT.toolspeed, target = src) && d_state == RWALL_SUPPORT_RODS) + d_state = RWALL_SHEATH + update_icon() + return TRUE + + // RWALL_SUPPORT_RODS > RWALL_SHEATH + if(istype(I, /obj/item/gun/energy/plasmacutter)) + to_chat(user, "You begin slicing through the support rods...") + playsound(src, I.usesound, 100, 1) + + if(do_after(user, 70 * I.toolspeed, target = src) && d_state == RWALL_SUPPORT_RODS) + d_state = RWALL_SHEATH + update_icon() + return TRUE + + // RWALL_BOLTS < RWALL_SUPPORT_RODS + if(iswrench(I)) + to_chat(user, "You start tightening the bolts which secure the support rods to their frame...") + playsound(src, I.usesound, 100, 1) + if(do_after(user, 40 * I.toolspeed, target = src)) + if(!istype(src, /turf/simulated/wall/r_wall) || !I || d_state != RWALL_SUPPORT_RODS) + return TRUE + d_state = RWALL_BOLTS + update_icon() + to_chat(user, "You tighten the bolts anchoring the support rods.") + return TRUE + + if(RWALL_SHEATH) + // RWALL_SHEATH > deconstructed + if(iscrowbar(I)) + to_chat(user, "You struggle to pry off the outer sheath...") + playsound(src, I.usesound, 100, 1) + + if(do_after(user, 100 * I.toolspeed, target = src) && d_state == RWALL_SHEATH) + to_chat(user, "You pry off the outer sheath.") + dismantle_wall() + return TRUE + +/turf/simulated/wall/r_wall/try_destroy(obj/item/I, mob/user, params) + if(istype(I, /obj/item/pickaxe/drill/diamonddrill)) + to_chat(user, "You begin to drill though the wall...") + + if(do_after(user, 800 * I.toolspeed, target = src)) // Diamond drill has 0.25 toolspeed, so 200 + to_chat(user, "Your drill tears through the last of the reinforced plating.") + dismantle_wall() + return TRUE + + if(istype(I, /obj/item/pickaxe/drill/jackhammer)) + to_chat(user, "You begin to disintegrate the wall...") + + if(do_after(user, 1000 * I.toolspeed, target = src)) // Jackhammer has 0.1 toolspeed, so 100 + to_chat(user, "Your sonic jackhammer disintegrates the reinforced plating.") + dismantle_wall() + return TRUE - //Finally, CHECKING FOR FALSE WALLS if it isn't damaged - else if(!d_state) - return attack_hand(user) - return /turf/simulated/wall/r_wall/singularity_pull(S, current_size) if(current_size >= STAGE_FIVE) diff --git a/code/modules/admin/verbs/mapping.dm b/code/modules/admin/verbs/mapping.dm index 9b6c4363008..a87308bb9b1 100644 --- a/code/modules/admin/verbs/mapping.dm +++ b/code/modules/admin/verbs/mapping.dm @@ -92,7 +92,7 @@ var/intercom_range_display_status = 0 if(!(locate(/obj/structure/grille,T))) var/window_check = 0 for(var/obj/structure/window/W in T) - if(W.dir == turn(C1.dir,180) || W.is_fulltile() ) + if(W.dir == turn(C1.dir,180) || W.fulltile) window_check = 1 break if(!window_check) diff --git a/code/modules/admin/verbs/modifyvariables.dm b/code/modules/admin/verbs/modifyvariables.dm index dfca07426c5..c1e28a48f8d 100644 --- a/code/modules/admin/verbs/modifyvariables.dm +++ b/code/modules/admin/verbs/modifyvariables.dm @@ -46,6 +46,8 @@ var/list/VVpixelmovement = list("step_x", "step_y", "step_size", "bound_height", else if(isfile(var_value)) . = VV_FILE + else if(istype(var_value, /regex)) + . = VV_REGEX else . = VV_NULL @@ -66,6 +68,7 @@ var/list/VVpixelmovement = list("step_x", "step_y", "step_size", "bound_height", VV_DATUM_TYPE, VV_TYPE, VV_MATRIX, + VV_REGEX, VV_FILE, VV_NEW_ATOM, VV_NEW_DATUM, @@ -141,6 +144,14 @@ var/list/VVpixelmovement = list("step_x", "step_y", "step_size", "bound_height", .["class"] = null return + if(VV_REGEX) + var/reg = input("Enter regex", "Regex", "") as null|text + if(!reg) + return + .["value"] = regex(reg) + if(.["value"] == null) + .["class"] = null + if(VV_ATOM_REFERENCE) var/type = pick_closest_path(FALSE) diff --git a/code/modules/admin/verbs/possess.dm b/code/modules/admin/verbs/possess.dm index 54d39d5a5fa..5cf4c34ffe2 100644 --- a/code/modules/admin/verbs/possess.dm +++ b/code/modules/admin/verbs/possess.dm @@ -9,6 +9,10 @@ var/turf/T = get_turf(O) + var/confirm = alert("Are you sure you want to possess [O]?", "Confirm posession", "Yes", "No") + + if(confirm != "Yes") + return if(T) log_admin("[key_name(usr)] has possessed [O] ([O.type]) at ([T.x], [T.y], [T.z])") message_admins("[key_name_admin(usr)] has possessed [O] ([O.type]) at ([T.x], [T.y], [T.z])", 1) @@ -42,4 +46,4 @@ usr.loc = O.loc // Appear where the object you were controlling is -- TLE usr.client.eye = usr usr.control_object = null - feedback_add_details("admin_verb","RO") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! \ No newline at end of file + feedback_add_details("admin_verb","RO") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! diff --git a/code/modules/admin/verbs/striketeam.dm b/code/modules/admin/verbs/striketeam.dm index 8eaede660e1..1e809bcd948 100644 --- a/code/modules/admin/verbs/striketeam.dm +++ b/code/modules/admin/verbs/striketeam.dm @@ -37,8 +37,8 @@ var/global/sent_strike_team = 0 break // Find ghosts willing to be DS - var/list/commando_ckeys = pollCandidatesByKeyWithVeto(src, usr, commandos_possible, "Join the DeathSquad?",, 21, 600, 1, role_playtime_requirements[ROLE_DEATHSQUAD], TRUE, FALSE) - if(!commando_ckeys.len) + var/list/commando_ghosts = pollCandidatesWithVeto(src, usr, commandos_possible, "Join the DeathSquad?",, 21, 600, 1, role_playtime_requirements[ROLE_DEATHSQUAD], TRUE, FALSE) + if(!commando_ghosts.len) to_chat(usr, "Nobody volunteered to join the DeathSquad.") return @@ -47,53 +47,62 @@ var/global/sent_strike_team = 0 // Spawns commandos and equips them. var/commando_number = commandos_possible //for selecting a leader var/is_leader = TRUE // set to FALSE after leader is spawned + for(var/obj/effect/landmark/L in landmarks_list) - if(commando_number<=0) break + + if(commando_number <= 0) + break + if(L.name == "Commando") - spawn(0) - var/use_ds_borg = FALSE - var/ghost_key // Ghost ckey that we intend to put into the commando. Can remain undefined if we don't have one. - if(commando_ckeys.len) - ghost_key = pick(commando_ckeys) - commando_ckeys -= ghost_key - if(!is_leader) - var/new_gender = alert(src, "Select Deathsquad Type.", "DS Character Generation", "Organic", "Cyborg") - if(new_gender == "Cyborg") - use_ds_borg = TRUE + if(!commando_ghosts.len) + break - if(use_ds_borg) - var/mob/living/silicon/robot/deathsquad/R = new() - R.forceMove(get_turf(L)) - var/rnum = rand(1,1000) - var/borgname = "Epsilon [rnum]" - R.name = borgname - R.custom_name = borgname - R.real_name = R.name - R.mind = new - R.mind.current = R - R.mind.original = R - R.mind.assigned_role = SPECIAL_ROLE_DEATHSQUAD - R.mind.special_role = SPECIAL_ROLE_DEATHSQUAD - if(!(R.mind in ticker.minds)) - ticker.minds += R.mind - ticker.mode.traitors += R.mind - if(ghost_key) - R.key = ghost_key - if(nuke_code) - R.mind.store_memory("Nuke Code: [nuke_code].") - R.mind.store_memory("Mission: [input].") - to_chat(R, "You are a Special Operations cyborg, in the service of Central Command. \nYour current mission is: [input]") - else - var/mob/living/carbon/human/new_commando = create_death_commando(L, is_leader) - if(ghost_key) - new_commando.key = ghost_key - new_commando.internal = new_commando.s_store - new_commando.update_action_buttons_icon() - if(nuke_code) - new_commando.mind.store_memory("Nuke Code: [nuke_code].") - new_commando.mind.store_memory("Mission: [input].") - to_chat(new_commando, "You are a Special Ops [is_leader ? "TEAM LEADER" : "commando"] in the service of Central Command. Check the table ahead for detailed instructions.\nYour current mission is: [input]") + var/use_ds_borg = FALSE + var/mob/ghost_mob = pick(commando_ghosts) + commando_ghosts -= ghost_mob + if(!ghost_mob || !ghost_mob.key || !ghost_mob.client) + continue + + if(!is_leader) + var/new_dstype = alert(ghost_mob.client, "Select Deathsquad Type.", "DS Character Generation", "Organic", "Cyborg") + if(new_dstype == "Cyborg") + use_ds_borg = TRUE + + if(!ghost_mob || !ghost_mob.key || !ghost_mob.client) // Have to re-check this due to the above alert() call + continue + + if(use_ds_borg) + var/mob/living/silicon/robot/deathsquad/R = new() + R.forceMove(get_turf(L)) + var/rnum = rand(1,1000) + var/borgname = "Epsilon [rnum]" + R.name = borgname + R.custom_name = borgname + R.real_name = R.name + R.mind = new + R.mind.current = R + R.mind.original = R + R.mind.assigned_role = SPECIAL_ROLE_DEATHSQUAD + R.mind.special_role = SPECIAL_ROLE_DEATHSQUAD + if(!(R.mind in ticker.minds)) + ticker.minds += R.mind + ticker.mode.traitors += R.mind + R.key = ghost_mob.key + if(nuke_code) + R.mind.store_memory("Nuke Code: [nuke_code].") + R.mind.store_memory("Mission: [input].") + to_chat(R, "You are a Special Operations cyborg, in the service of Central Command. \nYour current mission is: [input]") + else + var/mob/living/carbon/human/new_commando = create_death_commando(L, is_leader) + new_commando.mind.key = ghost_mob.key + new_commando.key = ghost_mob.key + new_commando.internal = new_commando.s_store + new_commando.update_action_buttons_icon() + if(nuke_code) + new_commando.mind.store_memory("Nuke Code: [nuke_code].") + new_commando.mind.store_memory("Mission: [input].") + to_chat(new_commando, "You are a Special Ops [is_leader ? "TEAM LEADER" : "commando"] in the service of Central Command. Check the table ahead for detailed instructions.\nYour current mission is: [input]") is_leader = FALSE commando_number-- @@ -133,6 +142,7 @@ var/global/sent_strike_team = 0 A.real_name = "[commando_rank] [commando_name]" A.copy_to(new_commando) + new_commando.dna.ready_dna(new_commando)//Creates DNA. //Creates mind stuff. diff --git a/code/modules/admin/verbs/striketeam_syndicate.dm b/code/modules/admin/verbs/striketeam_syndicate.dm index ec31632208e..c5f46c98592 100644 --- a/code/modules/admin/verbs/striketeam_syndicate.dm +++ b/code/modules/admin/verbs/striketeam_syndicate.dm @@ -45,8 +45,8 @@ var/global/sent_syndicate_strike_team = 0 break // Find ghosts willing to be SST - var/list/commando_ckeys = pollCandidatesByKeyWithVeto(src, usr, syndicate_commandos_possible, "Join the Syndicate Strike Team?",, 21, 600, 1, role_playtime_requirements[ROLE_DEATHSQUAD], TRUE, FALSE) - if(!commando_ckeys.len) + var/list/commando_ghosts = pollCandidatesWithVeto(src, usr, syndicate_commandos_possible, "Join the Syndicate Strike Team?",, 21, 600, 1, role_playtime_requirements[ROLE_DEATHSQUAD], TRUE, FALSE) + if(!commando_ghosts.len) to_chat(usr, "Nobody volunteered to join the SST.") return @@ -54,15 +54,29 @@ var/global/sent_syndicate_strike_team = 0 //Spawns commandos and equips them. for(var/obj/effect/landmark/L in landmarks_list) - if(syndicate_commando_number<=0) break + + if(syndicate_commando_number <= 0) + break + if(L.name == "Syndicate-Commando") + + if(!commando_ghosts.len) + break + + var/mob/ghost_mob = pick(commando_ghosts) + commando_ghosts -= ghost_mob + + if(!ghost_mob || !ghost_mob.key || !ghost_mob.client) + continue + var/mob/living/carbon/human/new_syndicate_commando = create_syndicate_death_commando(L, is_leader) - if(commando_ckeys.len) - new_syndicate_commando.key = pick(commando_ckeys) - commando_ckeys -= new_syndicate_commando.key - new_syndicate_commando.internal = new_syndicate_commando.s_store - new_syndicate_commando.update_action_buttons_icon() + if(!new_syndicate_commando) + continue + + new_syndicate_commando.key = ghost_mob.key + new_syndicate_commando.internal = new_syndicate_commando.s_store + new_syndicate_commando.update_action_buttons_icon() //So they don't forget their code or mission. if(nuke_code) diff --git a/code/modules/alarm/alarm.dm b/code/modules/alarm/alarm.dm index ac8b65d9d82..1d4a570999a 100644 --- a/code/modules/alarm/alarm.dm +++ b/code/modules/alarm/alarm.dm @@ -134,5 +134,3 @@ /mob/living/silicon/robot/syndicate/get_alarm_cameras() return list() - -#undef ALARM_LOSS_DELAY diff --git a/code/modules/awaymissions/mission_code/spacehotel.dm b/code/modules/awaymissions/mission_code/spacehotel.dm index 4e4f2628736..81d21df5dcf 100644 --- a/code/modules/awaymissions/mission_code/spacehotel.dm +++ b/code/modules/awaymissions/mission_code/spacehotel.dm @@ -299,6 +299,4 @@ return S.retal_target = target - S.retal = 1 - -#undef CHECKOUT_TIME + S.retal = 1 \ No newline at end of file diff --git a/code/modules/client/preference/preferences.dm b/code/modules/client/preference/preferences.dm index ad25c8fdeb1..8fff84a4e69 100644 --- a/code/modules/client/preference/preferences.dm +++ b/code/modules/client/preference/preferences.dm @@ -54,15 +54,9 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts return max(0, days - C.player_age) return 0 -//used for alternate_option -#define GET_RANDOM_JOB 0 -#define BE_CIVILIAN 1 -#define RETURN_TO_LOBBY 2 - #define MAX_SAVE_SLOTS 20 // Save slots for regular players #define MAX_SAVE_SLOTS_MEMBER 20 // Save slots for BYOND members - #define TAB_CHAR 0 #define TAB_GAME 1 #define TAB_GEAR 2 @@ -209,6 +203,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts b_type = pick(4;"O-", 36;"O+", 3;"A-", 28;"A+", 1;"B-", 20;"B+", 1;"AB-", 5;"AB+") max_gear_slots = config.max_loadout_points + var/loaded_preferences_successfully = FALSE if(istype(C)) if(!IsGuestKey(C.key)) unlock_content = C.IsByondMember() @@ -217,16 +212,17 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts if(C.donator_level >= DONATOR_LEVEL_ONE) max_gear_slots += 5 - var/loaded_preferences_successfully = load_preferences(C) - if(loaded_preferences_successfully) - if(load_character(C)) - return + loaded_preferences_successfully = load_preferences(C) // Do not call this with no client/C, it generates a runtime / SQL error + if(loaded_preferences_successfully) + if(load_character(C)) + return //we couldn't load character data so just randomize the character appearance + name random_character() //let's create a random character then - rather than a fat, bald and naked man. real_name = random_name(gender) - if(!loaded_preferences_successfully) - save_preferences(C) - save_character(C) //let's save this new random character so it doesn't keep generating new ones. + if(istype(C)) + if(!loaded_preferences_successfully) + save_preferences(C) // Do not call this with no client/C, it generates a runtime / SQL error + save_character(C) // Do not call this with no client/C, it generates a runtime / SQL error /datum/preferences/proc/color_square(colour) return "___" @@ -699,7 +695,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts switch(alternate_option) if(GET_RANDOM_JOB) HTML += "

Get random job if preferences unavailable

" - if(BE_CIVILIAN) + if(BE_ASSISTANT) HTML += "

Be a civilian if preferences unavailable

" if(RETURN_TO_LOBBY) HTML += "

Return to lobby if preferences unavailable

" @@ -1051,7 +1047,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts ResetJobs() SetChoices(user) if("random") - if(alternate_option == GET_RANDOM_JOB || alternate_option == BE_CIVILIAN) + if(alternate_option == GET_RANDOM_JOB || alternate_option == BE_ASSISTANT) alternate_option += 1 else if(alternate_option == RETURN_TO_LOBBY) alternate_option = 0 diff --git a/code/modules/clothing/gloves/miscellaneous.dm b/code/modules/clothing/gloves/miscellaneous.dm index dc1504b80b6..40c29c1d991 100644 --- a/code/modules/clothing/gloves/miscellaneous.dm +++ b/code/modules/clothing/gloves/miscellaneous.dm @@ -134,7 +134,7 @@ update_icon() /obj/item/clothing/gloves/fingerless/rapid - name = "Gloves of the north star" + name = "Gloves of the North Star" desc = "Just looking at these fills you with an urge to beat the shit out of people." /obj/item/clothing/gloves/fingerless/rapid/Touch(mob/living/target, proximity = TRUE) diff --git a/code/modules/clothing/masks/miscellaneous.dm b/code/modules/clothing/masks/miscellaneous.dm index 4ee5182844d..22f293aedfc 100644 --- a/code/modules/clothing/masks/miscellaneous.dm +++ b/code/modules/clothing/masks/miscellaneous.dm @@ -8,7 +8,7 @@ gas_transfer_coefficient = 0.90 put_on_delay = 20 var/resist_time = 0 //deciseconds of how long you need to gnaw to get rid of the gag, 0 to make it impossible to remove - var/mute = MUTE_ALL + var/mute = MUZZLE_MUTE_ALL var/security_lock = FALSE // Requires brig access to remove 0 - Remove as normal var/locked = FALSE //Indicates if a mask is locked, should always start as 0. species_fit = list("Vox") @@ -93,7 +93,7 @@ item_state = null w_class = WEIGHT_CLASS_TINY resist_time = 150 - mute = MUTE_MUFFLE + mute = MUZZLE_MUTE_MUFFLE flags = DROPDEL species_fit = list("Vox", "Unathi", "Tajaran", "Vulpkanin", "Grey") sprite_sheets = list( @@ -117,7 +117,7 @@ name = "safety muzzle" desc = "A muzzle designed to prevent biting." resist_time = 600 - mute = MUTE_NONE + mute = MUZZLE_MUTE_NONE security_lock = TRUE locked = FALSE diff --git a/code/modules/customitems/item_defines.dm b/code/modules/customitems/item_defines.dm index 141d9ed0bf6..a229b72f745 100644 --- a/code/modules/customitems/item_defines.dm +++ b/code/modules/customitems/item_defines.dm @@ -1370,4 +1370,13 @@ /obj/item/clothing/suit/fluff/vetcoat/navy //Furasian: Fillmoore Grayson icon_state = "alchemistcoatnavy" - item_state = "alchemistcoatnavy" \ No newline at end of file + item_state = "alchemistcoatnavy" + +/obj/item/clothing/accessory/medal/fluff/panzermedal //PanzerSkull: GRN-DER + name = "Cross of Valor" + desc = "A medal from the bygone Asteroid Wars. Its Ruby shines with a strange intensity." + icon = 'icons/obj/custom_items.dmi' + icon_state = "panzermedal" + item_state = "panzermedal" + item_color = "panzermedal" + slot_flags = SLOT_TIE \ No newline at end of file diff --git a/code/modules/economy/Economy.dm b/code/modules/economy/Economy.dm index 028c2810ae7..57d76e98c5c 100644 --- a/code/modules/economy/Economy.dm +++ b/code/modules/economy/Economy.dm @@ -38,7 +38,7 @@ #define MINERALS 8 #define EMERGENCY 9 -#define GAS 10 +#define EGAS 10 #define MAINTENANCE 11 #define ELECTRICAL 12 #define ROBOTICS 13 diff --git a/code/modules/economy/Economy_Events.dm b/code/modules/economy/Economy_Events.dm index c1e5b95273e..10e0d574f98 100644 --- a/code/modules/economy/Economy_Events.dm +++ b/code/modules/economy/Economy_Events.dm @@ -29,16 +29,16 @@ if(INDUSTRIAL_ACCIDENT) dearer_goods = list(EMERGENCY, BIOMEDICAL, ROBOTICS) if(BIOHAZARD_OUTBREAK) - dearer_goods = list(BIOMEDICAL, GAS) + dearer_goods = list(BIOMEDICAL, EGAS) if(PIRATES) dearer_goods = list(SECURITY, MINERALS) if(CORPORATE_ATTACK) dearer_goods = list(SECURITY, MAINTENANCE) if(ALIEN_RAIDERS) dearer_goods = list(BIOMEDICAL, ANIMALS) - cheaper_goods = list(GAS, MINERALS) + cheaper_goods = list(EGAS, MINERALS) if(AI_LIBERATION) - dearer_goods = list(EMERGENCY, GAS, MAINTENANCE) + dearer_goods = list(EMERGENCY, EGAS, MAINTENANCE) if(MOURNING) cheaper_goods = list(MINERALS, MAINTENANCE) if(CULT_CELL_REVEALED) diff --git a/code/modules/events/disease_outbreak.dm b/code/modules/events/disease_outbreak.dm index b514924abfa..cf2e3621498 100644 --- a/code/modules/events/disease_outbreak.dm +++ b/code/modules/events/disease_outbreak.dm @@ -11,7 +11,7 @@ /datum/event/disease_outbreak/start() if(!virus_type) - virus_type = pick(/datum/disease/advance/flu, /datum/disease/advance/cold, /datum/disease/brainrot, /datum/disease/magnitis) + virus_type = pick(/datum/disease/advance/flu, /datum/disease/advance/cold, /datum/disease/brainrot, /datum/disease/magnitis, /datum/disease/beesease, /datum/disease/anxiety, /datum/disease/fake_gbs, /datum/disease/fluspanish, /datum/disease/pierrot_throat, /datum/disease/lycan) for(var/mob/living/carbon/human/H in shuffle(living_mob_list)) if(issmall(H)) //don't infect monkies; that's a waste diff --git a/code/modules/events/infestation.dm b/code/modules/events/infestation.dm index c5a5873afa0..d11a1227ddf 100644 --- a/code/modules/events/infestation.dm +++ b/code/modules/events/infestation.dm @@ -107,7 +107,6 @@ #undef LOC_HYDRO #undef LOC_VAULT #undef LOC_TECH -#undef LOC_TACTICAL #undef VERM_MICE #undef VERM_LIZARDS diff --git a/code/modules/fish/fishtank.dm b/code/modules/fish/fishtank.dm index 584fdd5b93c..412c5407ddc 100644 --- a/code/modules/fish/fishtank.dm +++ b/code/modules/fish/fishtank.dm @@ -1,6 +1,6 @@ ////////////////////////////// -// Fish Tanks! // +// Fish Tanks // ////////////////////////////// @@ -9,44 +9,41 @@ desc = "So generic, it might as well have no description at all." icon = 'icons/obj/fish_items.dmi' icon_state = "tank1" - density = 0 - anchored = 0 + density = FALSE + anchored = FALSE pass_flags = 0 var/tank_type = "" // Type of aquarium, used for icon updating var/water_capacity = 0 // Number of units the tank holds (varies with tank type) var/water_level = 0 // Number of units currently in the tank (new tanks start empty) var/light_switch = 0 // 0 = off, 1 = on (off by default) - var/filth_level = 0.0 // How dirty the tank is (max 10) + var/filth_level = 0 // How dirty the tank is (max 10) var/lid_switch = 0 // 0 = open, 1 = closed (open by default) var/max_fish = 0 // How many fish the tank can support (varies with tank type, 1 fish per 50 units sounds reasonable) var/food_level = 0 // Amount of fishfood floating in the tank (max 10) var/fish_count = 0 // Number of fish in the tank - var/list/fish_list = null // Tracks the current types of fish in the tank + var/list/fish_list = list() // Tracks the current types of fish in the tank var/egg_count = 0 // How many fish eggs can be harvested from the tank (capped at the max_fish value) - var/list/egg_list = null // Tracks the current types of harvestable eggs in the tank + var/list/egg_list = list() // Tracks the current types of harvestable eggs in the tank - var/has_lid = 0 // 0 if the tank doesn't have a lid/light, 1 if it does - var/max_health = 0 // Can handle a couple hits - var/cur_health = 0 // Current health, starts at max_health - var/leaking = 0 // 0 if not leaking, 1 if minor leak, 2 if major leak (not leaking by default) + var/has_lid = FALSE // 0 if the tank doesn't have a lid/light, 1 if it does + var/leaking = FALSE // 0 if not leaking, 1 if minor leak, 2 if major leak (not leaking by default) var/shard_count = 0 // Number of glass shards to salvage when broken (1 less than the number of sheets to build the tank) /obj/machinery/fishtank/bowl name = "fish bowl" desc = "A small bowl capable of housing a single fish, commonly found on desks. This one has a tiny treasure chest in it!" icon_state = "bowl1" - density = 0 // Small enough to not block stuff - anchored = 0 // Small enough to move even when filled + density = FALSE // Small enough to not block stuff + anchored = FALSE // Small enough to move even when filled pass_flags = PASSTABLE | LETPASSTHROW // Just like at the county fair, you can't seem to throw the ball in to win the goldfish, and it's small enough to pull onto a table tank_type = "bowl" water_capacity = 50 // Not very big, therefore it can't hold much max_fish = 1 // What a lonely fish - has_lid = 0 - max_health = 15 // Not very sturdy - cur_health = 15 + has_lid = FALSE + max_integrity = 15 // Not very sturdy shard_count = 0 // No salvageable shards /obj/machinery/fishtank/tank @@ -54,17 +51,16 @@ desc = "A large glass tank designed to house aquatic creatures. Contains an integrated water circulation system." icon = 'icons/obj/fish_items.dmi' icon_state = "tank1" - density = 1 - anchored = 1 + density = TRUE + anchored = TRUE pass_flags = LETPASSTHROW tank_type = "tank" water_capacity = 200 // Decent sized, holds almost 2 full buckets max_fish = 4 // Room for a few fish - has_lid = 1 - max_health = 50 // Average strength, will take a couple hits from a toolbox. - cur_health = 50 + has_lid = TRUE + max_integrity = 50 // Average strength, will take a couple hits from a toolbox. shard_count = 2 @@ -72,17 +68,16 @@ name = "wall aquarium" desc = "This aquarium is massive! It completely occupies the same space as a wall, and looks very sturdy too!" icon_state = "wall1" - density = 1 - anchored = 1 + density = TRUE + anchored = TRUE pass_flags = 0 // This thing is the size of a wall, you can't throw past it. tank_type = "wall" water_capacity = 500 // This thing fills an entire tile, it holds a lot. max_fish = 10 // Plenty of room for a lot of fish - has_lid = 1 - max_health = 100 // This thing is a freaking wall, it can handle abuse. - cur_health = 100 + has_lid = TRUE + max_integrity = 100 // This thing is a freaking wall, it can handle abuse. shard_count = 3 @@ -94,9 +89,10 @@ set name = "Toggle Tank Lid" set category = "Object" set src in view(1) - toggle_lid(usr) -/obj/machinery/fishtank/proc/toggle_lid(var/mob/living/user) + toggle_lid() + +/obj/machinery/fishtank/proc/toggle_lid() lid_switch = !lid_switch update_icon() @@ -104,12 +100,13 @@ set name = "Toggle Tank Light" set category = "Object" set src in view(1) - toggle_light(usr) -/obj/machinery/fishtank/proc/toggle_light(var/mob/living/user) + toggle_light() + +/obj/machinery/fishtank/proc/toggle_light() light_switch = !light_switch if(light_switch) - set_light(2,2,"#a0a080") + set_light(2, 2, "#a0a080") else adjust_tank_light() @@ -119,8 +116,6 @@ /obj/machinery/fishtank/New() ..() - fish_list = new/list() - egg_list = new/list() if(!has_lid) //Tank doesn't have a lid/light, remove the verbs for then verbs -= /obj/machinery/fishtank/verb/toggle_lid_verb verbs -= /obj/machinery/fishtank/verb/toggle_light_verb @@ -154,7 +149,8 @@ overlays += "over_leak_[leaking]" //Green if we aren't leaking, light blue and slow blink if minor link, dark blue and rapid flashing for major leak //Update water overlay - if(water_level == 0) return //Skip the rest of this if there is no water in the aquarium + if(!water_level) + return //Skip the rest of this if there is no water in the aquarium var/water_type = "_clean" //Default to clean water if(filth_level > 5) water_type = "_dirty" //Show dirty water above filth_level 5 (breeding threshold) if(water_level > (water_capacity * 0.85)) //Show full if the water_level is over 85% of water_capacity @@ -162,15 +158,13 @@ else if(water_level > (water_capacity * 0.35)) //Show half-full if the water_level is over 35% of water_capacity overlays += "over_[tank_type]_half[water_type]" - return - ////////////////////////////// // PROCESS PROC // ////////////////////////////// //Stops atmos from passing wall tanks, since they are effectively full-windows. -/obj/machinery/fishtank/wall/CanAtmosPass(var/turf/T) - return 0 +/obj/machinery/fishtank/wall/CanAtmosPass(turf/T) + return FALSE /obj/machinery/fishtank/process() //Start by counting fish in the tank @@ -238,9 +232,7 @@ adjust_tank_light() /obj/machinery/fishtank/proc/adjust_tank_light() - if(light_switch) //tank light overrides fish lights - return - else + if(!light_switch) //tank light overrides fish lights var/glo_light = 0 for(var/datum/fish/fish in fish_list) if(istype(fish, /datum/fish/glofish)) @@ -261,19 +253,13 @@ food_level = min(10, max(0, food_level + amount)) /obj/machinery/fishtank/proc/check_health() - //Max value check - if(cur_health > max_health) //Cur_health cannot exceed max_health, set it to max_health if it does - cur_health = max_health //Leaking status check - if(cur_health <= (max_health * 0.25)) //Major leak at or below 25% health (-10 water/cycle) + if(obj_integrity <= (max_integrity * 0.25)) //Major leak at or below 25% health (-10 water/cycle) leaking = 2 - else if(cur_health <= (max_health * 0.5)) //Minor leak at or below 50% health (-1 water/cycle) + else if(obj_integrity <= (max_integrity * 0.5)) //Minor leak at or below 50% health (-1 water/cycle) leaking = 1 else //Not leaking above 50% health leaking = 0 - //Destruction check - if(cur_health <= 0) //The tank is broken, destroy it - destroy() /obj/machinery/fishtank/proc/kill_fish(datum/fish/fish_type = null) //Check if we were passed a fish to kill, otherwise kill a random one @@ -292,12 +278,12 @@ fish_list.Add(fish_type) //Add a fish of the specified type fish_count++ //Increase fish_count to reflect the introduction of a fish, so the everything else works fine //Announce the new fish - visible_message("A new [fish_type.fish_name] has hatched in \the [src]!") + visible_message("A new [fish_type.fish_name] has hatched in [src]!") //Null type fish are dud eggs, give a message to inform the player else to_chat(usr, "The eggs disolve in the water. They were duds!") -/obj/machinery/fishtank/proc/harvest_eggs(var/mob/user) +/obj/machinery/fishtank/proc/harvest_eggs(mob/user) if(!egg_count) //Can't harvest non-existant eggs return @@ -312,62 +298,39 @@ egg_list.Cut() //Destroy any excess eggs, clearing the egg_list -/obj/machinery/fishtank/proc/harvest_fish(var/mob/user) - if(fish_count <= 0) //Can't catch non-existant fish! - to_chat(usr, "There are no fish in \the [src] to catch!") +/obj/machinery/fishtank/proc/harvest_fish(mob/user) + if(fish_count <= 0) //Can't catch non-existant fish! + to_chat(user, "There are no fish in [src] to catch!") return var/list/fish_names_list = list() for(var/datum/fish/fish_type in fish_list) fish_names_list += list("[fish_type.fish_name]" = fish_type) var/caught_fish = input("Select a fish to catch.", "Fishing") as null|anything in fish_names_list //Select a fish from the tank if(fish_count <= 0) - to_chat(usr, "There are no fish in \the [src] to catch!") + to_chat(user, "There are no fish in [src] to catch!") return else if(caught_fish) - user.visible_message("[user.name] harvests \a [caught_fish] from \the [src].", "You scoop \a [caught_fish] out of \the [src].") + user.visible_message("[user.name] harvests \a [caught_fish] from [src].", "You scoop \a [caught_fish] out of [src].") var/datum/fish/fish_type = fish_names_list[caught_fish] var/fish_item = fish_type.fish_item if(fish_item) new fish_item(get_turf(user)) //Spawn the appropriate fish_item at the user's feet. kill_fish(fish_type) //Kill the caught fish from the tank - -/obj/machinery/fishtank/proc/destroy(var/deconstruct = 0) - var/turf/T = get_turf(src) //Store the tank's turf for atmos updating after deletion of tank - if(!deconstruct) //Check if we are deconstructing or breaking the tank - var/shards_left = shard_count - while(shards_left > 0) //Produce the appropriate number of glass shards - new /obj/item/shard(get_turf(src)) - shards_left -- - if(water_level) //Spill any water that was left in the tank when it broke - spill_water() - else //We are deconstructing, make glass sheets instead of shards - var/sheets = shard_count + 1 //Deconstructing it salvages all the glass used to build the tank - new /obj/item/stack/sheet/glass(get_turf(src), sheets) //Produce the appropriate number of glass sheets, in a single stack - qdel(src) //qdel the tank and it's contents - T.air_update_turf(1) //Update the air for the turf, to avoid permanent atmos sealing with wall tanks - + //Update the air for the turf, to avoid permanent atmos sealing with wall tanks /obj/machinery/fishtank/proc/spill_water() + var/turf/simulated/T = get_turf(src) switch(tank_type) if("bowl") //Fishbowl: Wets it's own tile - var/turf/T = get_turf(src) - if(!istype(T, /turf/simulated)) return - var/turf/simulated/S = T - S.MakeSlippery() + if(istype(T)) + T.MakeSlippery() if("tank") //Fishtank: Wets it's own tile and the 4 adjacent tiles (cardinal directions) - var/turf/ST = get_turf(src) - if(istype(ST, /turf/simulated)) - var/turf/simulated/ST2 = ST - ST2.MakeSlippery() - var/list/L = ST.CardinalTurfs() - for(var/turf/T in L) - if(!istype(T, /turf/simulated)) continue - var/turf/simulated/S = T - S.MakeSlippery() + if(istype(T)) + T.MakeSlippery() + for(var/turf/simulated/ST in T.CardinalTurfs()) + ST.MakeSlippery() if("wall") //Wall-tank: Wets it's own tile and the surrounding 8 tiles (3x3 square) - for(var/turf/T in spiral_range_turfs(1, src.loc)) - if(!istype(T, /turf/simulated)) continue - var/turf/simulated/S = T - S.MakeSlippery() + for(var/turf/simulated/ST in spiral_range_turfs(1, loc)) + ST.MakeSlippery() /obj/machinery/fishtank/proc/breed_fish() var/list/breed_candidates = fish_list.Copy() @@ -412,20 +375,20 @@ examine_message += "Water level: " - if(water_level == 0) - examine_message += "\The [src] is empty! " + if(!water_level) + examine_message += "[src] is empty! " else if(water_level < water_capacity * 0.1) - examine_message += "\The [src] is nearly empty! " + examine_message += "[src] is nearly empty! " else if(water_level <= water_capacity * 0.25) - examine_message += "\The [src] is about one-quarter filled. " + examine_message += "[src] is about one-quarter filled. " else if(water_level <= water_capacity * 0.5) - examine_message += "\The [src] is about half filled. " + examine_message += "[src] is about half filled. " else if(water_level <= water_capacity * 0.75) - examine_message += "\The [src] is about three-quarters filled. " + examine_message += "[src] is about three-quarters filled. " else if(water_level < water_capacity) - examine_message += "\The [src] is nearly full! " + examine_message += "[src] is nearly full! " else if(water_level == water_capacity) - examine_message += "\The [src] is full! " + examine_message += "[src] is full! " examine_message += "
Cleanliness level: " @@ -467,7 +430,7 @@ //Report the number and types of live fish if there is water in the tank if(fish_count == 0) - examine_message += "\The [src] doesn't contain any live fish. " + examine_message += "[src] doesn't contain any live fish. " else //Build a message reporting the types of fish var/fish_num = fish_count @@ -483,7 +446,7 @@ message +=", " message +="." //No more fish, end the message with a period //Display the number of fish and previously constructed message - examine_message += "\The [src] contains [fish_count] live fish. [message] " + examine_message += "[src] contains [fish_count] live fish. [message] " examine_message += "
" @@ -498,12 +461,16 @@ examine_message += "
" //Report if the tank is leaking/cracked - if(water_level > 0) //Tank has water, so it's actually leaking - if(leaking == 1) examine_message += "\The [src] is leaking." - if(leaking == 2) examine_message += "\The [src] is leaking profusely!" + if(water_level) //Tank has water, so it's actually leaking + if(leaking == 1) + examine_message += "[src] is leaking." + if(leaking == 2) + examine_message += "[src] is leaking profusely!" else //No water, report the cracks instead - if(leaking == 1) examine_message += "\The [src] is cracked." - if(leaking == 2) examine_message += "\The [src] is nearly shattered!" + if(leaking == 1) + examine_message += "[src] is cracked." + if(leaking == 2) + examine_message += "[src] is nearly shattered!" //Finally, report the full examine_message constructed from the above reports @@ -514,127 +481,113 @@ // ATACK PROCS // ////////////////////////////// -/obj/machinery/fishtank/attack_animal(mob/living/simple_animal/M as mob) +/obj/machinery/fishtank/attack_animal(mob/living/simple_animal/M) if(istype(M, /mob/living/simple_animal/pet/cat)) if(M.a_intent == INTENT_HELP) //Cats can try to fish in open tanks on help intent if(lid_switch) //Can't fish in a closed tank. Fishbowls are ALWAYS open. - M.visible_message("[M.name] stares at into \the [src] while sitting perfectly still.", "The lid is closed, so you stare into \the [src] intently.") + M.visible_message("[M.name] stares at into [src] while sitting perfectly still.", "The lid is closed, so you stare into [src] intently.") else if(fish_count) //Tank must actually have fish to try catching one - M.visible_message("[M.name] leaps up onto \the[src] and attempts to fish through the opening!", "You jump up onto \the [src] and begin fishing through the opening!") - spawn(10) - if(water_level && prob(45)) //If there is water, there is a chance the cat will slip, Syndicat will spark like E-N when this happens - M.visible_message("[M.name] slipped and got soaked!", "You slipped and got soaked!") - if(istype(M, /mob/living/simple_animal/pet/cat/Syndi)) - var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread - s.set_up(3, 1, src) - s.start() - else //No water or didn't slip, get that fish! - M.visible_message("[M.name] catches and devours a live fish!", "You catch and devour a live fish, yum!") - kill_fish() //Kill a random fish - M.health = M.maxHealth //Eating fish heals the predator + M.visible_message("[M.name] leaps up onto [src] and attempts to fish through the opening!", "You jump up onto [src] and begin fishing through the opening!") + if(water_level && prob(45)) //If there is water, there is a chance the cat will slip, Syndicat will spark like E-N when this happens + M.visible_message("[M.name] slipped and got soaked!", "You slipped and got soaked!") + if(istype(M, /mob/living/simple_animal/pet/cat/Syndi)) + var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread + s.set_up(3, 1, src) + s.start() + else //No water or didn't slip, get that fish! + M.visible_message("[M.name] catches and devours a live fish!", "You catch and devour a live fish, yum!") + kill_fish() //Kill a random fish + M.health = M.maxHealth //Eating fish heals the predator else - to_chat(usr, "There are no fish in [src]!") + to_chat(M, "There are no fish in [src]!") else - attack_generic(M, M.harm_intent_damage) + return ..() else if(istype(M, /mob/living/simple_animal/hostile/bear)) if(M.a_intent == INTENT_HELP) //Bears can try to fish in open tanks on help intent if(lid_switch) //Can't fish in a closed tank. Fishbowls are ALWAYS open. - M.visible_message("[M.name] scrapes it's claws along \the [src]'s lid.", "The lid is closed, so you scrape your claws against \the [src]'s lid.") + M.visible_message("[M.name] scrapes it's claws along [src]'s lid.", "The lid is closed, so you scrape your claws against [src]'s lid.") else if(fish_count) //Tank must actually have fish to try catching one - M.visible_message("[M.name] reaches into \the[src] and attempts to fish through the opening!", "You reach into \the [src] and begin fishing through the opening!") - spawn(5) - if(water_level && prob(5)) //Bears are good at catching fish, only a 5% chance to fail - M.visible_message("[M.name] swipes at the water!", "You just barely missed that fish!") - else //No water or didn't slip, get that fish! - M.visible_message("[M.name] catches and devours a live fish!", "You catch and devour a live fish, yum!") - kill_fish() //Kill a random fish - M.health = M.maxHealth //Eating fish heals the predator + M.visible_message("[M.name] reaches into [src] and attempts to fish through the opening!", "You reach into [src] and begin fishing through the opening!") + if(water_level && prob(5)) //Bears are good at catching fish, only a 5% chance to fail + M.visible_message("[M.name] swipes at the water!", "You just barely missed that fish!") + else //No water or didn't slip, get that fish! + M.visible_message("[M.name] catches and devours a live fish!", "You catch and devour a live fish, yum!") + kill_fish() //Kill a random fish + M.health = M.maxHealth //Eating fish heals the predator else - to_chat(usr, "There are no fish in [src]!") + to_chat(M, "There are no fish in [src]!") else - attack_generic(M, M.harm_intent_damage) + return ..() else - if(M.melee_damage_upper > 0) //If the simple_animal has a melee_damage_upper defined, use that for the damage - attack_generic(M, M.melee_damage_upper) - else if(M.a_intent == INTENT_HARM) //Let any simple_animal try to break tanks when on harm intent - if(M.harm_intent_damage <= 0) return //If it doesn't do damage, don't bother with the attack - attack_generic(M, M.harm_intent_damage) - check_health() + return ..() -/obj/machinery/fishtank/attack_alien(mob/living/user as mob) - if(islarva(user)) return - attack_generic(user, 15) - -/obj/machinery/fishtank/attack_slime(mob/living/user as mob) - var/mob/living/carbon/slime/S = user - if(!S.is_adult) - return - attack_generic(user, rand(10, 15)) - -/obj/machinery/fishtank/attack_hand(mob/user as mob) - if(HULK in user.mutations) - user.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!")) - user.visible_message("[user] smashes through [src]!") - destroy() - else if(usr.a_intent == INTENT_HARM) - user.changeNext_move(CLICK_CD_MELEE) +/obj/machinery/fishtank/attack_hand(mob/user) + user.changeNext_move(CLICK_CD_MELEE) + if(user.a_intent == INTENT_HARM) playsound(get_turf(src), 'sound/effects/glassknock.ogg', 80, 1) - usr.visible_message("[usr.name] bangs against the [src.name]!", \ - "You bang against the [src.name]!", \ + user.visible_message("[user.name] bangs against the [name]!", \ + "You bang against the [name]!", \ "You hear a banging sound.") else - user.changeNext_move(CLICK_CD_MELEE) - playsound(src.loc, 'sound/effects/glassknock.ogg', 80, 1) - usr.visible_message("[usr.name] taps on the [src.name].", \ - "You tap on the [src.name].", \ + playsound(loc, 'sound/effects/glassknock.ogg', 80, 1) + user.visible_message("[user.name] taps on the [name].", \ + "You tap on the [name].", \ "You hear a knocking sound.") - return -/obj/machinery/fishtank/proc/hit(var/damage, var/sound_effect = 1) - cur_health = max(0, cur_health - damage) - if(sound_effect) - playsound(loc, 'sound/effects/Glasshit.ogg', 75, 1) - check_health() - -/obj/machinery/fishtank/attack_generic(mob/living/user, damage = 0) //used by attack_alien, attack_animal, and attack_slime - user.changeNext_move(CLICK_CD_MELEE) - user.do_attack_animation(src) - cur_health -= damage - if(cur_health <= 0) - user.visible_message("[user] smashes through \the [src]!") - destroy() - else //for nicer text~ - user.visible_message("[user] smashes into \the [src]!") - playsound(loc, 'sound/effects/Glasshit.ogg', 100, 1) +/obj/machinery/fishtank/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1) + . = ..() + if(.) //received damage check_health() -/obj/machinery/fishtank/attackby(var/obj/item/O, var/mob/user as mob) +/obj/machinery/fishtank/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0) + switch(damage_type) + if(BRUTE) + if(damage_amount) + playsound(src, 'sound/effects/Glasshit.ogg', 75, 1) + else + playsound(src, 'sound/weapons/tap.ogg', 50, 1) + if(BURN) + playsound(src, 'sound/items/Welder.ogg', 100, 1) + +/obj/machinery/fishtank/deconstruct(disassembled = TRUE) + if(QDELETED(src)) + return + if(!disassembled) + playsound(src, "shatter", 70, 1) + for(var/i in 1 to shard_count) //Produce the appropriate number of glass shards + var/obj/item/shard/S = new /obj/item/shard(get_turf(src)) + transfer_fingerprints_to(S) + if(water_level) //Spill any water that was left in the tank when it broke + spill_water() + else //We are deconstructing, make glass sheets instead of shards + new /obj/item/stack/sheet/glass(get_turf(src), shard_count + 1) //Produce the appropriate number of glass sheets, in a single stack + qdel(src) + +/obj/machinery/fishtank/attackby(obj/item/O, mob/user) //Welders repair damaged tanks on help intent, damage on all others - if(istype(O, /obj/item/weldingtool)) + if(iswelder(O)) var/obj/item/weldingtool/W = O if(user.a_intent == INTENT_HELP) if(W.isOn()) - if(cur_health < max_health) + if(obj_integrity < max_integrity) playsound(loc, W.usesound, 50, 1) - to_chat(usr, "You repair some of the cracks on \the [src].") - cur_health += 20 + to_chat(user, "You repair some of the cracks on [src].") + obj_integrity = min(obj_integrity + 20, max_integrity) check_health() else - to_chat(usr, "There is no damage to fix!") + to_chat(user, "There is no damage to fix!") else - if(cur_health < max_health) - to_chat(usr, "[W.name] must be on to repair this damage.") + if(obj_integrity < max_integrity) + to_chat(user, "[W] must be on to repair this damage.") else - user.changeNext_move(CLICK_CD_MELEE) - hit(W.force) - return + return ..() //Open reagent containers add and remove water - if(O.is_open_container()) + else if(O.is_open_container()) if(istype(O, /obj/item/reagent_containers/glass)) if(lid_switch) - to_chat(usr, "Open the lid on \the [src] first!") + to_chat(user, "Open the lid on [src] first!") return var/obj/item/reagent_containers/glass/C = O //Containers with any reagents will get dumped in @@ -652,57 +605,52 @@ C.reagents.clear_reagents() else if(water_level == water_capacity) - to_chat(usr, "[src] is already full!") - return + to_chat(user, "[src] is already full!") else message = "The filtration process purifies the water, raising the water level." if((water_level + water_value) == water_capacity) - message += " You filled \the [src] to the brim!" + message += " You filled [src] to the brim!" if((water_level + water_value) > water_capacity) - message += " You overfilled \the [src] and some water runs down the side, wasted." + message += " You overfilled [src] and some water runs down the side, wasted." C.reagents.clear_reagents() adjust_water_level(water_value) - user.visible_message("[user.name] pours the contents of [C.name] into \the [src].", "[message]") - return + user.visible_message("[user.name] pours the contents of [C.name] into [src].", "[message]") //Empty containers will scoop out water, filling the container as much as possible from the water_level else - if(water_level == 0) - to_chat(usr, "[src] is empty!") + if(!water_level) + to_chat(user, "[src] is empty!") else if(water_level >= C.volume) //Enough to fill the container completely C.reagents.add_reagent("fishwater", C.volume) adjust_water_level(-C.volume) - user.visible_message("[user.name] scoops out some water from \the [src].", "You completely fill [C.name] from \the [src].") + user.visible_message("[user.name] scoops out some water from [src].", "You completely fill [C.name] from [src].") else //Fill the container as much as possible with the water_level C.reagents.add_reagent("fishwater", water_level) adjust_water_level(-water_level) - user.visible_message("[user.name] scoops out some water from \the [src].", "You fill [C.name] with the last of the water in \the [src].") - return + user.visible_message("[user.name] scoops out some water from [src].", "You fill [C.name] with the last of the water in [src].") //Wrenches can deconstruct empty tanks, but not tanks with any water. Kills any fish left inside and destroys any unharvested eggs in the process - if(istype(O, /obj/item/wrench)) - if(water_level == 0) - to_chat(usr, "Now disassembling [src].") - playsound(src.loc, O.usesound, 50, 1) + else if(iswrench(O)) + if(!water_level) + to_chat(user, "Now disassembling [src].") + playsound(loc, O.usesound, 50, 1) if(do_after(user, 50 * O.toolspeed, target = src)) - destroy(1) + deconstruct(TRUE) else - to_chat(usr, "[src] must be empty before you disassemble it!") - return + to_chat(user, "[src] must be empty before you disassemble it!") //Fish eggs else if(istype(O, /obj/item/fish_eggs)) var/obj/item/fish_eggs/egg = O //Don't add eggs if there is no water (they kinda need that to live) - if(water_level == 0) - to_chat(usr, "[src] has no water; [egg.name] won't hatch without water!") + if(!water_level) + to_chat(user, "[src] has no water; [egg.name] won't hatch without water!") else //Don't add eggs if the tank already has the max number of fish if(fish_count >= max_fish) - to_chat(usr, "[src] can't hold any more fish.") + to_chat(user, "[src] can't hold any more fish.") else add_fish(egg.fish_type) qdel(egg) - return //Fish food else if(istype(O, /obj/item/fishfood)) //Only add food if there is water and it isn't already full of food @@ -711,33 +659,28 @@ if(fish_count == 0) user.visible_message("[user.name] shakes some fish food into the empty [src]... How sad.", "You shake some fish food into the empty [src]... If only it had fish.") else - user.visible_message("[user.name] feeds the fish in \the [src]. The fish look excited!", "You feed the fish in \the [src]. They look excited!") + user.visible_message("[user.name] feeds the fish in [src]. The fish look excited!", "You feed the fish in [src]. They look excited!") adjust_food_level(10) else - to_chat(usr, "[src] already has plenty of food in it. You decide to not add more.") + to_chat(user, "[src] already has plenty of food in it. You decide to not add more.") else - to_chat(usr, "[src] doesn't have any water in it. You should fill it with water first.") - return + to_chat(user, "[src] doesn't have any water in it. You should fill it with water first.") //Fish egg scoop else if(istype(O, /obj/item/egg_scoop)) if(egg_count) - user.visible_message("[user.name] harvests some fish eggs from \the [src].", "You scoop the fish eggs out of \the [src].") + user.visible_message("[user.name] harvests some fish eggs from [src].", "You scoop the fish eggs out of [src].") harvest_eggs(user) else - user.visible_message("[user.name] fails to harvest any fish eggs from \the [src].", "There are no fish eggs in \the [src] to scoop out.") - return + user.visible_message("[user.name] fails to harvest any fish eggs from [src].", "There are no fish eggs in [src] to scoop out.") //Fish net - if(istype(O, /obj/item/fish_net)) + else if(istype(O, /obj/item/fish_net)) harvest_fish(user) - return //Tank brush - if(istype(O, /obj/item/tank_brush)) + else if(istype(O, /obj/item/tank_brush)) if(filth_level == 0) - to_chat(usr, "[src] is already spotless!") + to_chat(user, "[src] is already spotless!") else adjust_filth_level(-filth_level) - user.visible_message("[user.name] scrubs the inside of \the [src], cleaning the filth.", "You scrub the inside of \the [src], cleaning the filth.") - else if(O && O.force) - user.visible_message("\The [src] has been attacked by [user.name] with \the [O]!") - hit(O.force) - return + user.visible_message("[user.name] scrubs the inside of [src], cleaning the filth.", "You scrub the inside of [src], cleaning the filth.") + else + return ..() \ No newline at end of file diff --git a/code/modules/food_and_drinks/food/snacks.dm b/code/modules/food_and_drinks/food/snacks.dm index bc442486d5c..5dc010bfae9 100644 --- a/code/modules/food_and_drinks/food/snacks.dm +++ b/code/modules/food_and_drinks/food/snacks.dm @@ -99,6 +99,7 @@ U.overlays += I var/obj/item/reagent_containers/food/snacks/collected = new type + collected.name = name collected.loc = U collected.reagents.remove_any(collected.reagents.total_volume) collected.trash = null diff --git a/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm b/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm index b4a787ea4c8..6f6d9132fdf 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm @@ -58,7 +58,7 @@ C.emote("scream") user.changeNext_move(CLICK_CD_MELEE) C.apply_damage(25, BURN, "head") //25 fire damage and disfigurement because your face was just deep fried! - head.disfigure("burn") + head.disfigure() add_attack_logs(user, G.affecting, "Deep-fried with [src]") qdel(G) //Removes the grip so the person MIGHT have a small chance to run the fuck away and to prevent rapid dunks. return 0 diff --git a/code/modules/mining/mine_items.dm b/code/modules/mining/mine_items.dm index 1ef887c2527..0a151babe67 100644 --- a/code/modules/mining/mine_items.dm +++ b/code/modules/mining/mine_items.dm @@ -341,20 +341,28 @@ //Pod turfs and objects //Window +/obj/structure/window/shuttle/survival_pod + name = "pod window" + icon = 'icons/obj/smooth_structures/pod_window.dmi' + icon_state = "smooth" + dir = FULLTILE_WINDOW_DIR + max_integrity = 100 + fulltile = TRUE + reinf = TRUE + heat_resistance = 1600 + armor = list("melee" = 50, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 50, "bio" = 100, "rad" = 100) + smooth = SMOOTH_MORE + canSmoothWith = list(/turf/simulated/wall/mineral/titanium/survival, /obj/machinery/door/airlock/survival_pod, /obj/structure/window/shuttle/survival_pod) + explosion_block = 3 + level = 3 + glass_type = /obj/item/stack/sheet/titaniumglass + glass_amount = 2 + /obj/structure/window/reinforced/survival_pod name = "pod window" icon = 'icons/obj/lavaland/survival_pod.dmi' icon_state = "pwindow" -// This override can be removed whenever we get rid of the stupid fucking `dir = 9` = full tile!!!! shit -/obj/structure/window/reinforced/survival_pod/CanPass(atom/movable/mover, turf/target, height=0) - if(istype(mover) && mover.checkpass(PASSGLASS)) - return 1 - if(get_dir(loc, target) == dir) - return !density - else - return 1 - //Floors /turf/simulated/floor/pod name = "pod floor" diff --git a/code/modules/mob/living/carbon/alien/alien.dm b/code/modules/mob/living/carbon/alien/alien.dm index e706b89ca85..8f74fbce413 100644 --- a/code/modules/mob/living/carbon/alien/alien.dm +++ b/code/modules/mob/living/carbon/alien/alien.dm @@ -1,7 +1,3 @@ -#define HEAT_DAMAGE_LEVEL_1 2 //Amount of damage applied when your body temperature just passes the 360.15k safety point -#define HEAT_DAMAGE_LEVEL_2 3 //Amount of damage applied when your body temperature passes the 400K point -#define HEAT_DAMAGE_LEVEL_3 8 //Amount of damage applied when your body temperature passes the 1000K point - /mob/living/carbon/alien name = "alien" voice_name = "alien" @@ -229,10 +225,6 @@ Des: Removes all infected images from the alien. /mob/living/carbon/alien/can_use_vents() return -#undef HEAT_DAMAGE_LEVEL_1 -#undef HEAT_DAMAGE_LEVEL_2 -#undef HEAT_DAMAGE_LEVEL_3 - /mob/living/carbon/alien/handle_footstep(turf/T) if(..()) if(T.footstep_sounds["xeno"]) diff --git a/code/modules/mob/living/carbon/alien/humanoid/humanoid_defense.dm b/code/modules/mob/living/carbon/alien/humanoid/humanoid_defense.dm index 41ebc8d8247..3fa08702605 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/humanoid_defense.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/humanoid_defense.dm @@ -1,16 +1,25 @@ +/mob/living/carbon/alien/humanoid/attack_hulk(mob/living/carbon/human/user, does_attack_animation = FALSE) + if(user.a_intent == INTENT_HARM) + ..(user, TRUE) + adjustBruteLoss(15) + var/hitverb = "punched" + if(mob_size < MOB_SIZE_LARGE) + Paralyse(1) + spawn(0) + step_away(src, user, 15) + sleep(1) + step_away(src, user, 15) + hitverb = "slammed" + playsound(loc, "punch", 25, 1, -1) + visible_message("[user] has [hitverb] [src]!", "[user] has [hitverb] [src]!") + return TRUE + /mob/living/carbon/alien/humanoid/attack_hand(mob/living/carbon/human/M) if(..()) switch(M.a_intent) if(INTENT_HARM) var/damage = rand(1, 9) if(prob(90)) - if(HULK in M.mutations)//HULK SMASH - damage = 15 - spawn(0) - Paralyse(1) - step_away(src, M, 15) - sleep(3) - step_away(src, M, 15) playsound(loc, "punch", 25, 1, -1) visible_message("[M] has punched [src]!", \ "[M] has punched [src]!") diff --git a/code/modules/mob/living/carbon/alien/humanoid/update_icons.dm b/code/modules/mob/living/carbon/alien/humanoid/update_icons.dm index f1bcfc0eeaf..44287493718 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/update_icons.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/update_icons.dm @@ -3,7 +3,7 @@ #define X_SUIT_LAYER 2 #define X_L_HAND_LAYER 3 #define X_R_HAND_LAYER 4 -#define TARGETED_LAYER 5 +#define X_TARGETED_LAYER 5 #define X_FIRE_LAYER 6 #define X_TOTAL_LAYERS 6 ///////////////////////////////// @@ -161,6 +161,6 @@ #undef X_SUIT_LAYER #undef X_L_HAND_LAYER #undef X_R_HAND_LAYER -#undef TARGETED_LAYER +#undef X_TARGETED_LAYER #undef X_FIRE_LAYER #undef X_TOTAL_LAYERS diff --git a/code/modules/mob/living/carbon/alien/larva/larva_defense.dm b/code/modules/mob/living/carbon/alien/larva/larva_defense.dm index ef38327b5ee..919eecee8d8 100644 --- a/code/modules/mob/living/carbon/alien/larva/larva_defense.dm +++ b/code/modules/mob/living/carbon/alien/larva/larva_defense.dm @@ -2,13 +2,6 @@ if(..()) var/damage = rand(1, 9) if(prob(90)) - if(HULK in M.mutations) - damage += 5 - spawn(0) - Paralyse(1) - step_away(src, M, 15) - sleep(3) - step_away(src, M, 15) playsound(loc, "punch", 25, 1, -1) add_attack_logs(M, src, "Melee attacked with fists") visible_message("[M] has kicked [src]!", \ @@ -23,6 +16,18 @@ visible_message("[M] has attempted to kick [src]!", \ "[M] has attempted to kick [src]!") + +/mob/living/carbon/alien/larva/attack_hulk(mob/living/carbon/human/user, does_attack_animation = FALSE) + if(user.a_intent == INTENT_HARM) + ..(user, TRUE) + adjustBruteLoss(5 + rand(1, 9)) + spawn(0) + Paralyse(1) + step_away(src, user, 15) + sleep(3) + step_away(src, user, 15) + return TRUE + /mob/living/carbon/alien/larva/do_attack_animation(atom/A, visual_effect_icon, obj/item/used_item, no_effect, end_pixel_y) if(!no_effect && !visual_effect_icon) visual_effect_icon = ATTACK_EFFECT_BITE diff --git a/code/modules/mob/living/carbon/brain/brain_item.dm b/code/modules/mob/living/carbon/brain/brain_item.dm index 2abc612f758..8c02bac91d1 100644 --- a/code/modules/mob/living/carbon/brain/brain_item.dm +++ b/code/modules/mob/living/carbon/brain/brain_item.dm @@ -15,6 +15,7 @@ parent_organ = "head" slot = "brain" vital = 1 + hidden_pain = TRUE //the brain has no pain receptors, and brain damage is meant to be a stealthy damage type. var/mmi_icon = 'icons/obj/assemblies.dmi' var/mmi_icon_state = "mmi_full" diff --git a/code/modules/mob/living/carbon/human/death.dm b/code/modules/mob/living/carbon/human/death.dm index 84b4608b233..37749c0dd76 100644 --- a/code/modules/mob/living/carbon/human/death.dm +++ b/code/modules/mob/living/carbon/human/death.dm @@ -139,9 +139,11 @@ /mob/living/carbon/human/proc/makeSkeleton() var/obj/item/organ/external/head/H = get_organ("head") - if(SKELETON in src.mutations) return + if(SKELETON in src.mutations) + return if(istype(H)) + H.disfigured = TRUE if(H.f_style) H.f_style = initial(H.f_style) if(H.h_style) @@ -159,16 +161,17 @@ mutations.Add(SKELETON) mutations.Add(NOCLONE) - status_flags |= DISFIGURED update_body(0) update_mutantrace() return /mob/living/carbon/human/proc/ChangeToHusk() var/obj/item/organ/external/head/H = bodyparts_by_name["head"] - if(HUSK in mutations) return + if(HUSK in mutations) + return if(istype(H)) + H.disfigured = TRUE //makes them unknown without fucking up other stuff like admintools if(H.f_style) H.f_style = "Shaved" //we only change the icon_state of the hair datum, so it doesn't mess up their UI/UE if(H.h_style) @@ -177,7 +180,6 @@ update_hair(0) mutations.Add(HUSK) - status_flags |= DISFIGURED //makes them unknown without fucking up other stuff like admintools update_body(0) update_mutantrace() return diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index fcb0e3d8b25..0a7b781cf03 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -513,7 +513,7 @@ //Returns "Unknown" if facially disfigured and real_name if not. Useful for setting name when polyacided or when updating a human's name variable /mob/living/carbon/human/proc/get_face_name() var/obj/item/organ/external/head = get_organ("head") - if( !head || head.disfigured || !real_name || (HUSK in mutations) ) //disfigured. use id-name if possible + if(!head || head.disfigured || cloneloss > 50 || !real_name || (HUSK in mutations)) //disfigured. use id-name if possible return "Unknown" return real_name @@ -1203,7 +1203,7 @@ return 0 if(!L.is_bruised()) - src.custom_pain("You feel a stabbing pain in your chest!", 1) + custom_pain("You feel a stabbing pain in your chest!") L.damage = L.min_bruised_damage //returns 1 if made bloody, returns 0 otherwise diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index c45154e4931..5b78b450357 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -348,6 +348,18 @@ emp_act if(penetrated_dam) SS.create_breaches(damtype, penetrated_dam) +/mob/living/carbon/human/attack_hulk(mob/living/carbon/human/user, does_attack_animation = FALSE) + if(user.a_intent == INTENT_HARM) + var/hulk_verb = pick("smash", "pummel") + if(check_shields(user, 15, "the [hulk_verb]ing")) + return + ..(user, TRUE) + playsound(loc, user.species.unarmed.attack_sound, 25, 1, -1) + var/message = "[user] has [hulk_verb]ed [src]!" + visible_message("[message]", "[message]") + adjustBruteLoss(15) + return TRUE + /mob/living/carbon/human/attack_hand(mob/user) if(..()) //to allow surgery to return properly. return diff --git a/code/modules/mob/living/carbon/human/human_organs.dm b/code/modules/mob/living/carbon/human/human_organs.dm index 3af9130fa7d..9a78eafadd8 100644 --- a/code/modules/mob/living/carbon/human/human_organs.dm +++ b/code/modules/mob/living/carbon/human/human_organs.dm @@ -20,7 +20,7 @@ //Moving around with fractured ribs won't do you any good if(E.is_broken() && E.internal_organs && E.internal_organs.len && prob(15)) var/obj/item/organ/internal/I = pick(E.internal_organs) - custom_pain("You feel broken bones moving in your [E.name]!", 1) + custom_pain("You feel broken bones moving in your [E.name]!") I.receive_damage(rand(3,5)) //handle_stance() diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index a8deeff60a6..22e2e0ffe25 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -832,7 +832,8 @@ /mob/living/carbon/human/handle_vision() if(machine) - if(!machine.check_eye(src)) reset_perspective(null) + if(!machine.check_eye(src)) + reset_perspective(null) else var/isRemoteObserve = 0 if((REMOTE_VIEW in mutations) && remoteview_target) diff --git a/code/modules/mob/living/carbon/human/species/species.dm b/code/modules/mob/living/carbon/human/species/species.dm index 25d3fd342c5..4de74d63e5a 100644 --- a/code/modules/mob/living/carbon/human/species/species.dm +++ b/code/modules/mob/living/carbon/human/species/species.dm @@ -21,7 +21,7 @@ var/primitive_form // Lesser form, if any (ie. monkey for humans) var/greater_form // Greater form, if any, ie. human for monkeys. var/tail // Name of tail image in species effects icon file. - var/unarmed //For empty hand harm-intent attack + var/datum/unarmed_attack/unarmed //For empty hand harm-intent attack var/unarmed_type = /datum/unarmed_attack var/slowdown = 0 // Passive movement speed malus (or boost, if negative) var/silent_steps = 0 // Stops step noises @@ -375,9 +375,6 @@ var/obj/item/organ/external/affecting = target.get_organ(ran_zone(user.zone_sel.selecting)) var/armor_block = target.run_armor_check(affecting, "melee") - if(HULK in user.mutations) - target.adjustBruteLoss(15) - playsound(target.loc, attack.attack_sound, 25, 1, -1) target.visible_message("[user] [pick(attack.attack_verb)]ed [target]!") diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index ec7592d4d3f..328e4c14ab8 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -205,7 +205,7 @@ var/global/list/damage_icon_parts = list() DI = damage_icon_parts[cache_index] standing_image.overlays += DI - overlays_standing[DAMAGE_LAYER] = standing_image + overlays_standing[H_DAMAGE_LAYER] = standing_image if(update_icons) update_icons() diff --git a/code/modules/mob/living/carbon/slime/slime.dm b/code/modules/mob/living/carbon/slime/slime.dm index 79bcd54775b..506cc804bd3 100644 --- a/code/modules/mob/living/carbon/slime/slime.dm +++ b/code/modules/mob/living/carbon/slime/slime.dm @@ -234,6 +234,24 @@ adjustBruteLoss(damage) updatehealth() +/mob/living/carbon/slime/attack_hulk(mob/living/carbon/human/user, does_attack_animation = FALSE) + if(user.a_intent == INTENT_HARM) + if(Victim || Target) + Victim = null + Target = null + anchored = 0 + if(prob(80) && !client) + Discipline++ + spawn(0) + step_away(src, user, 15) + sleep(3) + step_away(src, user, 15) + ..(user, TRUE) + playsound(loc, "punch", 25, 1, -1) + visible_message("[user] has punched [src]!", "[user] has punched [src]!") + adjustBruteLoss(15) + return TRUE + /mob/living/carbon/slime/attack_hand(mob/living/carbon/human/M) if(Victim) M.do_attack_animation(src, ATTACK_EFFECT_DISARM) @@ -301,20 +319,6 @@ var/damage = rand(1, 9) attacked += 10 if(prob(90)) - if(HULK in M.mutations) - damage += 15 - if(Victim || Target) - Victim = null - Target = null - anchored = 0 - if(prob(80) && !client) - Discipline++ - spawn(0) - step_away(src,M,15) - sleep(3) - step_away(src,M,15) - - playsound(loc, "punch", 25, 1, -1) add_attack_logs(M, src, "Melee attacked with fists") visible_message("[M] has punched [src]!", \ diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 2f0d341f697..d008bf060c4 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -137,10 +137,12 @@ if(!AM.anchored) now_pushing = 1 var/t = get_dir(src, AM) - if(istype(AM, /obj/structure/window/full)) - for(var/obj/structure/window/win in get_step(AM, t)) - now_pushing = 0 - return + if(istype(AM, /obj/structure/window)) + var/obj/structure/window/W = AM + if(W.fulltile) + for(var/obj/structure/window/win in get_step(W, t)) + now_pushing = 0 + return if(pulling == AM) stop_pulling() var/current_dir diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm index b2755e2b7d8..55e8536cd10 100644 --- a/code/modules/mob/living/say.dm +++ b/code/modules/mob/living/say.dm @@ -164,10 +164,10 @@ proc/get_radio_key_from_channel(var/channel) if(is_muzzled()) var/obj/item/clothing/mask/muzzle/G = wear_mask - if(G.mute == MUTE_ALL) //if the mask is supposed to mute you completely or just muffle you + if(G.mute == MUZZLE_MUTE_ALL) //if the mask is supposed to mute you completely or just muffle you to_chat(src, "You're muzzled and cannot speak!") return - else if(G.mute == MUTE_MUFFLE) + else if(G.mute == MUZZLE_MUTE_MUFFLE) message = muffledspeech(message) verb = "mumbles" diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index 09b62f1c89c..bf11356b3a5 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -87,11 +87,12 @@ var/list/ai_verbs_default = list( var/mob/living/simple_animal/bot/Bot var/turf/waypoint //Holds the turf of the currently selected waypoint. var/waypoint_mode = 0 //Waypoint mode is for selecting a turf via clicking. + var/apc_override = FALSE //hack for letting the AI use its APC even when visionless var/nuking = 0 var/obj/machinery/doomsday_device/doomsday_device var/obj/machinery/hologram/holopad/holo = null - var/mob/camera/aiEye/eyeobj = new() + var/mob/camera/aiEye/eyeobj var/sprint = 10 var/cooldown = 0 var/acceleration = 1 @@ -191,9 +192,7 @@ var/list/ai_verbs_default = list( spawn(5) new /obj/machinery/ai_powersupply(src) - eyeobj.ai = src - eyeobj.name = "[src.name] (AI Eye)" // Give it a name - eyeobj.loc = src.loc + create_eye() builtInCamera = new /obj/machinery/camera/portable(src) builtInCamera.c_tag = name @@ -1163,6 +1162,17 @@ var/list/ai_verbs_default = list( client.eye = eyeobj return TRUE + +/mob/living/silicon/ai/proc/can_see(atom/A) + if(isturf(loc)) //AI in core, check if on cameras + //get_turf_pixel() is because APCs in maint aren't actually in view of the inner camera + //apc_override is needed here because AIs use their own APC when depowered + return (cameranet && cameranet.checkTurfVis(get_turf_pixel(A))) || apc_override + //AI is carded/shunted + //view(src) returns nothing for carded/shunted AIs and they have x-ray vision so just use get_dist + var/list/viewscale = getviewsize(client.view) + return get_dist(src, A) <= max(viewscale[1]*0.5,viewscale[2]*0.5) + /mob/living/silicon/ai/proc/relay_speech(mob/living/M, text, verb, datum/language/speaking) if(!say_understands(M, speaking))//The AI will be able to understand most mobs talking through the holopad. if(speaking) diff --git a/code/modules/mob/living/silicon/ai/freelook/chunk.dm b/code/modules/mob/living/silicon/ai/freelook/chunk.dm index eeeeed8e8bb..6737be463d6 100644 --- a/code/modules/mob/living/silicon/ai/freelook/chunk.dm +++ b/code/modules/mob/living/silicon/ai/freelook/chunk.dm @@ -28,7 +28,7 @@ eye.visibleCameraChunks += src visible++ seenby += eye - if(changed && !updating) + if(changed) update() // Remove an AI eye from the chunk, then update if changed. diff --git a/code/modules/mob/living/silicon/ai/freelook/eye.dm b/code/modules/mob/living/silicon/ai/freelook/eye.dm index 71a2e6cba36..2728a1af55e 100644 --- a/code/modules/mob/living/silicon/ai/freelook/eye.dm +++ b/code/modules/mob/living/silicon/ai/freelook/eye.dm @@ -20,7 +20,6 @@ // It will also stream the chunk that the new loc is in. /mob/camera/aiEye/setLoc(T) - if(ai) if(!isturf(ai.loc)) return @@ -30,8 +29,9 @@ if(ai.client) ai.client.eye = src //Holopad - if(ai.holo) - ai.holo.move_hologram() + if(istype(ai.current, /obj/machinery/hologram/holopad)) + var/obj/machinery/hologram/holopad/H = ai.current + H.move_hologram(ai, T) /mob/camera/aiEye/Move() return 0 @@ -41,8 +41,22 @@ return ai.client return null + +/mob/camera/aiEye/proc/RemoveImages() + var/client/C = GetViewerClient() + if(C) + for(var/V in visibleCameraChunks) + var/datum/camerachunk/chunk = V + C.images -= chunk.obscured + + /mob/camera/aiEye/Destroy() - ai = null + if(ai) + //ai.all_eyes -= src + ai = null + for(var/V in visibleCameraChunks) + var/datum/camerachunk/chunk = V + chunk.remove(src) return ..() /atom/proc/move_camera_by_click() @@ -102,12 +116,18 @@ src.eyeobj.loc = src.loc else to_chat(src, "ERROR: Eyeobj not found. Creating new eye...") - src.eyeobj = new(src.loc) - src.eyeobj.ai = src - src.eyeobj.name = "[src.name] (AI Eye)" // Give it a name + create_eye() eyeobj.setLoc(loc) +/mob/living/silicon/ai/proc/create_eye() + if(eyeobj) + return + eyeobj = new /mob/camera/aiEye() + eyeobj.ai = src + eyeobj.setLoc(loc) + eyeobj.name = "[name] (AI Eye)" + /mob/living/silicon/ai/proc/toggle_acceleration() set category = "AI Commands" set name = "Toggle Camera Acceleration" diff --git a/code/modules/mob/living/silicon/ai/life.dm b/code/modules/mob/living/silicon/ai/life.dm index 1755674b4f6..42f132e39d4 100644 --- a/code/modules/mob/living/silicon/ai/life.dm +++ b/code/modules/mob/living/silicon/ai/life.dm @@ -129,8 +129,10 @@ to_chat(src, "Receiving control information from APC.") sleep(2) //bring up APC dialog - aiRestorePowerRoutine = 3 + apc_override = 1 theAPC.attack_ai(src) + apc_override = 0 + aiRestorePowerRoutine = 3 to_chat(src, "Here are your current laws:") src.show_laws() //WHY THE FUCK IS THIS HERE sleep(50) diff --git a/code/modules/mob/living/silicon/say.dm b/code/modules/mob/living/silicon/say.dm index 0de811224dc..0a3ed47b933 100644 --- a/code/modules/mob/living/silicon/say.dm +++ b/code/modules/mob/living/silicon/say.dm @@ -74,8 +74,8 @@ if(!message) return - var/obj/machinery/hologram/holopad/T = src.holo - if(T && T.hologram && T.master == src)//If there is a hologram and its master is the user. + var/obj/machinery/hologram/holopad/T = current + if(istype(T) && T.masters[src]) //Human-like, sorta, heard by those who understand humans. var/rendered_a @@ -112,8 +112,8 @@ if(!message) return - var/obj/machinery/hologram/holopad/T = src.holo - if(T && T.hologram && T.master == src) + var/obj/machinery/hologram/holopad/T = current + if(istype(T) && T.masters[src]) var/rendered = "[name] [message]" to_chat(src, "Holopad action relayed, [real_name] [message]") @@ -127,8 +127,8 @@ return 1 /mob/living/silicon/ai/emote(var/act, var/type, var/message) - var/obj/machinery/hologram/holopad/T = src.holo - if(T && T.hologram && T.master == src) //Is the AI using a holopad? + var/obj/machinery/hologram/holopad/T = current + if(istype(T) && T.masters[src])//Is the AI using a holopad? src.holopad_emote(message) else //Emote normally, then. ..() diff --git a/code/modules/mob/living/silicon/silicon_defense.dm b/code/modules/mob/living/silicon/silicon_defense.dm index 070ed327163..a903b6999dc 100644 --- a/code/modules/mob/living/silicon/silicon_defense.dm +++ b/code/modules/mob/living/silicon/silicon_defense.dm @@ -41,6 +41,15 @@ if(L.a_intent == INTENT_HELP) visible_message("[L.name] rubs its head against [src].") +/mob/living/silicon/attack_hulk(mob/living/carbon/human/user, does_attack_animation = FALSE) + if(user.a_intent == INTENT_HARM) + ..(user, TRUE) + adjustBruteLoss(rand(10, 15)) + playsound(loc, "punch", 25, 1, -1) + visible_message("[user] has punched [src]!", "[user] has punched [src]!") + return TRUE + return FALSE + /mob/living/silicon/attack_hand(mob/living/carbon/human/M) switch(M.a_intent) if(INTENT_HELP) @@ -51,15 +60,6 @@ else M.do_attack_animation(src, ATTACK_EFFECT_PUNCH) playsound(loc, 'sound/effects/bang.ogg', 10, 1) - if(HULK in M.mutations) - var/damage = rand(10,15) - adjustBruteLoss(damage) - add_attack_logs(M, src, "Melee attacked with fists") - playsound(loc, "punch", 25, 1, -1) - visible_message("[M] has punched [src]!", \ - "[M] has punched [src]!") - return 1 - else - visible_message("[M] punches [src], but doesn't leave a dent.", \ + visible_message("[M] punches [src], but doesn't leave a dent.", \ "[M] punches [src], but doesn't leave a dent.!") - return 0 + return FALSE diff --git a/code/modules/mob/living/simple_animal/animal_defense.dm b/code/modules/mob/living/simple_animal/animal_defense.dm index 972759812b4..309a13468a3 100644 --- a/code/modules/mob/living/simple_animal/animal_defense.dm +++ b/code/modules/mob/living/simple_animal/animal_defense.dm @@ -19,6 +19,14 @@ updatehealth() return 1 +/mob/living/simple_animal/attack_hulk(mob/living/carbon/human/user, does_attack_animation = FALSE) + if(user.a_intent == INTENT_HARM) + ..(user, TRUE) + playsound(loc, "punch", 25, 1, -1) + visible_message("[user] has punched [src]!", "[user] has punched [src]!") + adjustBruteLoss(15) + return TRUE + /mob/living/simple_animal/attack_alien(mob/living/carbon/alien/humanoid/M) if(..()) //if harm or disarm intent. var/damage = rand(15, 30) diff --git a/code/modules/mob/living/simple_animal/bot/construction.dm b/code/modules/mob/living/simple_animal/bot/construction.dm index 9e96a16fb0f..90c44f19286 100644 --- a/code/modules/mob/living/simple_animal/bot/construction.dm +++ b/code/modules/mob/living/simple_animal/bot/construction.dm @@ -282,73 +282,66 @@ log_game("[key_name(user)] has renamed a robot to [t]") //Medbot Assembly -/obj/item/firstaid_arm_assembly - name = "incomplete medibot assembly." - desc = "A first aid kit with a robot arm permanently grafted to it." - icon = 'icons/obj/aibots.dmi' - icon_state = "firstaid_arm" - var/build_step = 0 - var/created_name = "Medibot" //To preserve the name if it's a unique medbot I guess - var/skin = null //Same as medbot, set to tox or ointment for the respective kits. - w_class = WEIGHT_CLASS_NORMAL - var/treatment_brute = "salglu_solution" - var/treatment_oxy = "salbutamol" - var/treatment_fire = "salglu_solution" - var/treatment_tox = "charcoal" - var/treatment_virus = "spaceacillin" - req_one_access = list(access_medical, access_robotics) - - /obj/item/firstaid_arm_assembly/New() - ..() - spawn(5) - if(skin) - overlays += image('icons/obj/aibots.dmi', "kit_skin_[skin]") - -/obj/item/storage/firstaid/attackby(obj/item/robot_parts/S, mob/user, params) - - if((!istype(S, /obj/item/robot_parts/l_arm)) && (!istype(S, /obj/item/robot_parts/r_arm))) - ..() - return +/obj/item/storage/firstaid/attackby(obj/item/I, mob/user, params) + if(!istype(I, /obj/item/robot_parts/l_arm) && !istype(I, /obj/item/robot_parts/r_arm)) + return ..() //Making a medibot! - if(contents.len >= 1) + if(contents.len) to_chat(user, "You need to empty [src] out first!") return - var/obj/item/firstaid_arm_assembly/A = new /obj/item/firstaid_arm_assembly - if(istype(src,/obj/item/storage/firstaid/fire)) - A.skin = "ointment" - else if(istype(src,/obj/item/storage/firstaid/toxin)) - A.skin = "tox" - else if(istype(src,/obj/item/storage/firstaid/o2)) - A.skin = "o2" - else if(istype(src,/obj/item/storage/firstaid/brute)) - A.skin = "brute" - else if(istype(src,/obj/item/storage/firstaid/adv)) - A.skin = "adv" - else if(istype(src,/obj/item/storage/firstaid/tactical)) - A.skin = "bezerk" - else if(istype(src,/obj/item/storage/firstaid/aquatic_kit)) - A.skin = "fish" + var/obj/item/firstaid_arm_assembly/A = new /obj/item/firstaid_arm_assembly(loc, med_bot_skin) A.req_one_access = req_one_access + A.syndicate_aligned = syndicate_aligned A.treatment_oxy = treatment_oxy A.treatment_brute = treatment_brute A.treatment_fire = treatment_fire A.treatment_tox = treatment_tox A.treatment_virus = treatment_virus - qdel(S) + qdel(I) user.put_in_hands(A) to_chat(user, "You add the robot arm to the first aid kit.") user.unEquip(src, 1) qdel(src) +/obj/item/firstaid_arm_assembly + name = "incomplete medibot assembly." + desc = "A first aid kit with a robot arm permanently grafted to it." + icon = 'icons/obj/aibots.dmi' + icon_state = "firstaid_arm" + w_class = WEIGHT_CLASS_NORMAL + req_one_access = list(access_medical, access_robotics) + var/build_step = 0 + var/created_name = "Medibot" //To preserve the name if it's a unique medbot I guess + var/skin = null //Same as medbot, set to tox or ointment for the respective kits. + var/syndicate_aligned = FALSE + var/treatment_brute = "salglu_solution" + var/treatment_oxy = "salbutamol" + var/treatment_fire = "salglu_solution" + var/treatment_tox = "charcoal" + var/treatment_virus = "spaceacillin" -/obj/item/firstaid_arm_assembly/attackby(obj/item/W, mob/user, params) +/obj/item/firstaid_arm_assembly/New(loc, new_skin) ..() - if(istype(W, /obj/item/pen)) - var/t = stripped_input(user, "Enter new robot name", name, created_name,MAX_NAME_LEN) + if(new_skin) + skin = new_skin + update_icon() + +/obj/item/firstaid_arm_assembly/update_icon() + overlays.Cut() + if(skin) + overlays += image('icons/obj/aibots.dmi', "kit_skin_[skin]") + if(build_step > 0) + overlays += image('icons/obj/aibots.dmi', "na_scanner") + + +/obj/item/firstaid_arm_assembly/attackby(obj/item/I, mob/user, params) + ..() + if(istype(I, /obj/item/pen)) + var/t = stripped_input(user, "Enter new robot name", name, created_name, MAX_NAME_LEN) if(!t) return if(!in_range(src, user) && loc != user) @@ -358,32 +351,34 @@ else switch(build_step) if(0) - if(istype(W, /obj/item/healthanalyzer)) - if(!user.unEquip(W)) + if(istype(I, /obj/item/healthanalyzer)) + if(!user.drop_item()) return - qdel(W) + qdel(I) build_step++ to_chat(user, "You add the health sensor to [src].") name = "First aid/robot arm/health analyzer assembly" - overlays += image('icons/obj/aibots.dmi', "na_scanner") + update_icon() if(1) - if(isprox(W)) - if(!user.unEquip(W)) + if(isprox(I)) + if(!user.drop_item()) return - qdel(W) + qdel(I) build_step++ to_chat(user, "You complete the Medibot. Beep boop!") var/turf/T = get_turf(src) - var/mob/living/simple_animal/bot/medbot/S = new /mob/living/simple_animal/bot/medbot(T) - S.skin = skin - S.name = created_name - S.bot_core.req_one_access = req_one_access - S.treatment_oxy = treatment_oxy - S.treatment_brute = treatment_brute - S.treatment_fire = treatment_fire - S.treatment_tox = treatment_tox - S.treatment_virus = treatment_virus + if(!syndicate_aligned) + var/mob/living/simple_animal/bot/medbot/S = new /mob/living/simple_animal/bot/medbot(T, skin) + S.name = created_name + S.bot_core.req_one_access = req_one_access + S.treatment_oxy = treatment_oxy + S.treatment_brute = treatment_brute + S.treatment_fire = treatment_fire + S.treatment_tox = treatment_tox + S.treatment_virus = treatment_virus + else + new /mob/living/simple_animal/bot/medbot/syndicate(T) //Syndicate medibots are a special case that have so many unique vars on them, it's not worth passing them through construction phases user.unEquip(src, 1) qdel(src) diff --git a/code/modules/mob/living/simple_animal/bot/ed209bot.dm b/code/modules/mob/living/simple_animal/bot/ed209bot.dm index 1d9c13b54fc..9d7fa39ed87 100644 --- a/code/modules/mob/living/simple_animal/bot/ed209bot.dm +++ b/code/modules/mob/living/simple_animal/bot/ed209bot.dm @@ -17,7 +17,7 @@ bot_filter = RADIO_SECBOT model = "ED-209" bot_purpose = "seek out criminals, handcuff them, and report their location to security" - bot_core = /obj/machinery/bot_core/secbot + bot_core_type = /obj/machinery/bot_core/secbot window_id = "autoed209" window_name = "Automatic Security Unit v2.6" path_image_color = "#FF0000" @@ -61,12 +61,14 @@ shot_delay = 6//Longer shot delay because JESUS CHRIST check_records = 0//Don't actively target people set to arrest arrest_type = 1//Don't even try to cuff - bot_core.req_access = list(access_maint_tunnels, access_theatre) - arrest_type = 1 - if((lasercolor == "b") && (name == "\improper ED-209 Security Robot"))//Picks a name if there isn't already a custome one - name = pick("BLUE BALLER","SANIC","BLUE KILLDEATH MURDERBOT") - if((lasercolor == "r") && (name == "\improper ED-209 Security Robot")) - name = pick("RED RAMPAGE","RED ROVER","RED KILLDEATH MURDERBOT") + declare_arrests = 0 // Don't spam sec + bot_core.req_access = list(access_maint_tunnels, access_theatre, access_robotics) + + if(created_name == initial(name) || !created_name) + if(lasercolor == "b") + name = pick("BLUE BALLER","SANIC","BLUE KILLDEATH MURDERBOT") + else if (lasercolor == "r") + name = pick("RED RAMPAGE","RED ROVER","RED KILLDEATH MURDERBOT") //SECHUD var/datum/atom_hud/secsensor = huds[DATA_HUD_SECURITY_ADVANCED] @@ -101,30 +103,30 @@ dat += hack(user) dat += showpai(user) dat += text({" -Security Unit v2.6 controls

-Status: []
-Behaviour controls are [locked ? "locked" : "unlocked"]
-Maintenance panel panel is [open ? "opened" : "closed"]
"}, + Security Unit v2.6 controls

+ Status: []
+ Behaviour controls are [locked ? "locked" : "unlocked"]
+ Maintenance panel panel is [open ? "opened" : "closed"]
"}, -"[on ? "On" : "Off"]" ) + "[on ? "On" : "Off"]" ) if(!locked || issilicon(user) || user.can_admin_interact()) + dat += "Auto Patrol [auto_patrol ? "On" : "Off"]
" + if(!lasercolor) dat += text({"
-Arrest Unidentifiable Persons: []
-Arrest for Unauthorized Weapons: []
-Arrest for Warrant: []
-
-Operating Mode: []
-Report Arrests[]
-Auto Patrol[]"}, + Arrest Unidentifiable Persons: []
+ Arrest for Unauthorized Weapons: []
+ Arrest for Warrant: []
+
+ Operating Mode: []
+ Report Arrests[]
"}, -"[idcheck ? "Yes" : "No"]", -"[weaponscheck ? "Yes" : "No"]", -"[check_records ? "Yes" : "No"]", -"[arrest_type ? "Detain" : "Arrest"]", -"[declare_arrests ? "Yes" : "No"]", -"[auto_patrol ? "On" : "Off"]" ) + "[idcheck ? "Yes" : "No"]", + "[weaponscheck ? "Yes" : "No"]", + "[check_records ? "Yes" : "No"]", + "[arrest_type ? "Detain" : "Arrest"]", + "[declare_arrests ? "Yes" : "No"]") return dat @@ -239,13 +241,18 @@ Auto Patrol[]"}, if(target) // make sure target exists if(Adjacent(target) && isturf(target.loc)) // if right next to perp stun_attack(target) + if(!lasercolor) + mode = BOT_PREP_ARREST + anchored = 1 + target_lastloc = target.loc + return + else + mode = BOT_HUNT + target = null + target_lastloc = null + return - mode = BOT_PREP_ARREST - anchored = 1 - target_lastloc = target.loc - return - - else // not next to perp + else if(!disabled) // not next to perp var/turf/olddist = get_dist(src, target) walk_to(src, target,1,4) if((get_dist(src, target)) >= (olddist)) @@ -406,7 +413,7 @@ Auto Patrol[]"}, shoot_sound = 'sound/weapons/laser.ogg' if(emagged == 2) if(lasercolor) - projectile = /obj/item/projectile/beam/lasertag + projectile = /obj/item/projectile/beam/disabler else projectile = /obj/item/projectile/beam else @@ -501,6 +508,7 @@ Auto Patrol[]"}, if(lasertag_check) icon_state = "[lasercolor]ed2090" disabled = 1 + walk_to(src, 0) target = null spawn(100) disabled = 0 @@ -569,4 +577,4 @@ Auto Patrol[]"}, if(!C.handcuffed) C.handcuffed = new /obj/item/restraints/handcuffs/cable/zipties/used(C) C.update_handcuffed() - back_to_idle() + back_to_idle() \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/bot/floorbot.dm b/code/modules/mob/living/simple_animal/bot/floorbot.dm index 9ad8837520d..b1133cb0e08 100644 --- a/code/modules/mob/living/simple_animal/bot/floorbot.dm +++ b/code/modules/mob/living/simple_animal/bot/floorbot.dm @@ -14,7 +14,7 @@ bot_filter = RADIO_FLOORBOT model = "Floorbot" bot_purpose = "seek out damaged or missing floor tiles, and repair or replace them as necessary" - bot_core = /obj/machinery/bot_core/floorbot + bot_core_type = /obj/machinery/bot_core/floorbot window_id = "autofloor" window_name = "Automatic Station Floor Repairer v1.1" path_image_color = "#FFA500" diff --git a/code/modules/mob/living/simple_animal/bot/medbot.dm b/code/modules/mob/living/simple_animal/bot/medbot.dm index 7c737690ec0..6cdffd48f16 100644 --- a/code/modules/mob/living/simple_animal/bot/medbot.dm +++ b/code/modules/mob/living/simple_animal/bot/medbot.dm @@ -44,6 +44,7 @@ var/treatment_virus = "spaceacillin" var/treat_virus = 1 //If on, the bot will attempt to treat viral infections, curing them if possible. var/shut_up = 0 //self explanatory :) + var/syndicate_aligned = FALSE // Will it only treat operatives? /mob/living/simple_animal/bot/medbot/tox skin = "tox" @@ -68,8 +69,8 @@ desc = "International Medibot of mystery." skin = "bezerk" treatment_oxy = "perfluorodecalin" - treatment_brute = "styptic_powder" - treatment_fire = "silver_sulfadiazine" + treatment_brute = "bicaridine" + treatment_fire = "kelotane" treatment_tox = "charcoal" /mob/living/simple_animal/bot/medbot/syndicate @@ -77,9 +78,10 @@ desc = "You'd better have insurance!" skin = "bezerk" treatment_oxy = "perfluorodecalin" - treatment_brute = "styptic_powder" - treatment_fire = "silver_sulfadiazine" + treatment_brute = "bicaridine" + treatment_fire = "kelotane" treatment_tox = "charcoal" + syndicate_aligned = TRUE bot_core_type = /obj/machinery/bot_core/medbot/syndicate control_freq = BOT_FREQ + 1000 // make it not show up on lists radio_channel = "Syndicate" @@ -90,6 +92,9 @@ Radio.syndie = 1 /mob/living/simple_animal/bot/medbot/update_icon() + overlays.Cut() + if(skin) + overlays += "medskin_[skin]" if(!on) icon_state = "medibot0" return @@ -101,22 +106,21 @@ else icon_state = "medibot1" -/mob/living/simple_animal/bot/medbot/New() +/mob/living/simple_animal/bot/medbot/New(loc, new_skin) ..() - update_icon() - - spawn(4) - if(skin) - overlays += image('icons/obj/aibots.dmi', "medskin_[skin]") - - var/datum/job/doctor/J = new/datum/job/doctor - access_card.access += J.get_access() - prev_access = access_card.access + var/datum/job/doctor/J = new /datum/job/doctor + access_card.access += J.get_access() + prev_access = access_card.access + qdel(J) var/datum/atom_hud/medsensor = huds[DATA_HUD_MEDICAL_ADVANCED] medsensor.add_hud_to(src) permanent_huds |= medsensor + if(new_skin) + skin = new_skin + update_icon() + /mob/living/simple_animal/bot/medbot/bot_reset() ..() patient = null @@ -271,8 +275,10 @@ if(assess_patient(H)) last_found = world.time if((last_newpatient_speak + 300) < world.time) //Don't spam these messages! - var/message = pick("Hey, [H.name]! Hold on, I'm coming.","Wait [H.name]! I want to help!","[H.name], you appear to be injured!") + var/list/messagevoice = list("Hey, [H.name]! Hold on, I'm coming." = 'sound/voice/mcoming.ogg', "Wait [H.name]! I want to help!" = 'sound/voice/mhelp.ogg', "[H.name], you appear to be injured!" = 'sound/voice/minjured.ogg') + var/message = pick(messagevoice) speak(message) + playsound(loc, messagevoice[message], 50, 0) last_newpatient_speak = world.time return H else @@ -304,8 +310,10 @@ if(!patient) if(!shut_up && prob(1)) - var/message = pick("Radar, put a mask on!","There's always a catch, and it's the best there is.","I knew it, I should've been a plastic surgeon.","What kind of medbay is this? Everyone's dropping like dead flies.","Delicious!") + var/list/messagevoice = list("Radar, put a mask on!" = 'sound/voice/mradar.ogg', "There's always a catch, and I'm the best there is." = 'sound/voice/mcatch.ogg', "I knew it, I should've been a plastic surgeon." = 'sound/voice/msurgeon.ogg', "What kind of medbay is this? Everyone's dropping like flies." = 'sound/voice/mflies.ogg', "Delicious!" = 'sound/voice/mdelicious.ogg') + var/message = pick(messagevoice) speak(message) + playsound(loc, messagevoice[message], 50, 0) var/scan_range = (stationary_mode ? 1 : DEFAULT_SCAN_RANGE) //If in stationary mode, scan range is limited to adjacent patients. patient = scan(/mob/living/carbon/human, oldpatient, scan_range) oldpatient = patient @@ -371,7 +379,7 @@ if(emagged == 2) //Everyone needs our medicine. (Our medicine is toxins) return 1 - if((skin == "bezerk") && (!("syndicate" in C.faction))) + if(syndicate_aligned && (!("syndicate" in C.faction))) return 0 if(declare_crit && C.health <= 0) //Critical condition! Call for help! @@ -440,9 +448,11 @@ soft_reset() return - if(C.stat == 2) - var/death_message = pick("No! NO!","Live, damnit! LIVE!","I...I've never lost a patient before. Not today, I mean.") - speak(death_message) + if(C.stat == DEAD || (C.status_flags & FAKEDEATH)) + var/list/messagevoice = list("No! Stay with me!" = 'sound/voice/mno.ogg', "Live, damnit! LIVE!" = 'sound/voice/mlive.ogg', "I...I've never lost a patient before. Not today, I mean." = 'sound/voice/mlost.ogg') + var/message = pick(messagevoice) + speak(message) + playsound(loc, messagevoice[message], 50, 0) oldpatient = patient soft_reset() return @@ -492,8 +502,10 @@ break if(!reagent_id) //If they don't need any of that they're probably cured! - var/message = pick("All patched up!","An apple a day keeps me away.","Feel better soon!") + var/list/messagevoice = list("All patched up!" = 'sound/voice/mpatchedup.ogg', "An apple a day keeps me away." = 'sound/voice/mapple.ogg', "Feel better soon!" = 'sound/voice/mfeelbetter.ogg') + var/message = pick(messagevoice) speak(message) + playsound(loc, messagevoice[message], 50, 0) bot_reset() return else @@ -554,7 +566,8 @@ if("adv") new /obj/item/storage/firstaid/adv/empty(Tsec) if("bezerk") - new /obj/item/storage/firstaid/tactical/empty(Tsec) + var/obj/item/storage/firstaid/tactical/empty/T = new(Tsec) + T.syndicate_aligned = syndicate_aligned //This is a special case since Syndicate medibots and the mysterious medibot look the same; we also dont' want crew building Syndicate medibots if the mysterious medibot blows up. if("fish") new /obj/item/storage/firstaid/aquatic_kit(Tsec) else @@ -571,6 +584,9 @@ if(prob(50)) new /obj/item/robot_parts/l_arm(Tsec) + if(emagged && prob(25)) + playsound(loc, 'sound/voice/minsult.ogg', 50, 0) + var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread s.set_up(3, 1, src) s.start() @@ -579,7 +595,7 @@ /mob/living/simple_animal/bot/medbot/proc/declare(crit_patient) if(declare_cooldown) return - if((skin == "bezerk")) + if(syndicate_aligned) return var/area/location = get_area(src) speak("Medical emergency! [crit_patient ? "[crit_patient]" : "A patient"] is in critical condition at [location]!", radio_channel) diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/queen.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/queen.dm index 9133b8cc14c..532c2b7357a 100644 --- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/queen.dm +++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/queen.dm @@ -39,7 +39,7 @@ var/lastnestsetup = 0 var/neststep = 0 var/hasnested = 0 - var/spider_max_per_nest = 25 // above this, AI queens become stable + var/spider_max_per_nest = 35 // above this, AI queens become stable var/canlay = 4 // main counter for egg-laying ability! # = num uses, incremented at intervals var/eggslaid = 0 var/spider_can_fakelings = 3 // spawns defective spiderlings that don't grow up, used to freak out crew, atmosphere diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/terror_spiders.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/terror_spiders.dm index ef456ddcb0e..235a161c595 100644 --- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/terror_spiders.dm +++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/terror_spiders.dm @@ -201,11 +201,6 @@ var/global/list/ts_spiderling_list = list() spider_specialattack(G,can_poison) else G.attack_animal(src) - else if(istype(target, /obj/structure/alien/resin)) - var/obj/structure/alien/resin/E = target - do_attack_animation(E) - E.health -= rand(melee_damage_lower, melee_damage_upper) - E.healthcheck() else target.attack_animal(src) diff --git a/code/modules/mob/login.dm b/code/modules/mob/login.dm index 63b248ffd41..fb62ad3a629 100644 --- a/code/modules/mob/login.dm +++ b/code/modules/mob/login.dm @@ -4,6 +4,7 @@ lastKnownIP = client.address computer_id = client.computer_id log_access_in(client) + create_attack_log("Logged in at [atom_loc_line(get_turf(src))]") if(config.log_access) for(var/mob/M in player_list) if(M == src) continue diff --git a/code/modules/mob/logout.dm b/code/modules/mob/logout.dm index a0f8594e870..cbcd51c44a7 100644 --- a/code/modules/mob/logout.dm +++ b/code/modules/mob/logout.dm @@ -3,6 +3,7 @@ unset_machine() player_list -= src log_access_out(src) + create_attack_log("Logged out at [atom_loc_line(get_turf(src))]") // `holder` is nil'd out by now, so we check the `admin_datums` array directly //Only report this stuff if we are currently playing. if(admin_datums[ckey] && ticker && ticker.current_state == GAME_STATE_PLAYING) diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index bbe6caed8a3..beba84eaa3f 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -543,11 +543,11 @@ var/list/slot_equipment_priority = list( \ client.screen = list() hud_used.show_hud(hud_used.hud_version) -/mob/setDir(new_dir) +/mob/setDir(new_dir) if(forced_look) if(isnum(forced_look)) dir = forced_look - else + else var/atom/A = locateUID(forced_look) if(istype(A)) dir = get_cardinal_dir(src, A) @@ -592,7 +592,7 @@ var/list/slot_equipment_priority = list( \ return if(!src || !isturf(src.loc)) return 0 - if(istype(A, /obj/effect/decal/point)) + if(istype(A, /obj/effect/temp_visual/point)) return 0 var/tile = get_turf(A) @@ -600,12 +600,8 @@ var/list/slot_equipment_priority = list( \ return 0 changeNext_move(CLICK_CD_POINT) - var/obj/P = new /obj/effect/decal/point(tile) + var/obj/P = new /obj/effect/temp_visual/point(tile) P.invisibility = invisibility - spawn (20) - if(P) - qdel(P) - return 1 /mob/proc/ret_grab(obj/effect/list_container/mobl/L as obj, flag) diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm index 6d1f856fbd3..274c1602e04 100644 --- a/code/modules/mob/new_player/new_player.dm +++ b/code/modules/mob/new_player/new_player.dm @@ -26,6 +26,7 @@ /mob/new_player/proc/handle_tos_consent() if(!GLOB.join_tos) + tos_consent = TRUE return TRUE establish_db_connection() diff --git a/code/modules/power/singularity/narsie.dm b/code/modules/power/singularity/narsie.dm index 9a911400fd5..0520630dcac 100644 --- a/code/modules/power/singularity/narsie.dm +++ b/code/modules/power/singularity/narsie.dm @@ -10,6 +10,7 @@ move_self = 1 //Do we move on our own? grav_pull = 5 //How many tiles out do we pull? consume_range = 6 //How many tiles out do we eat + gender = FEMALE /obj/singularity/narsie/large name = "Nar-Sie" diff --git a/code/modules/power/smes.dm b/code/modules/power/smes.dm index e69abc5b00f..27229a2d8b3 100644 --- a/code/modules/power/smes.dm +++ b/code/modules/power/smes.dm @@ -224,8 +224,6 @@ /obj/machinery/power/smes/proc/chargedisplay() return round(5.5*charge/(capacity ? capacity : 5e6)) -#define SMESRATE 0.05 - /obj/machinery/power/smes/process() if(stat & BROKEN) return diff --git a/code/modules/reagents/chemistry/machinery/chem_dispenser.dm b/code/modules/reagents/chemistry/machinery/chem_dispenser.dm index e589936a935..d4d232d2ed7 100644 --- a/code/modules/reagents/chemistry/machinery/chem_dispenser.dm +++ b/code/modules/reagents/chemistry/machinery/chem_dispenser.dm @@ -1,7 +1,3 @@ -#define SOLID 1 -#define LIQUID 2 -#define GAS 3 - /obj/machinery/chem_dispenser name = "chem dispenser" density = 1 diff --git a/code/modules/reagents/chemistry/reagents/medicine.dm b/code/modules/reagents/chemistry/reagents/medicine.dm index a979d350c2a..d1b44798b85 100644 --- a/code/modules/reagents/chemistry/reagents/medicine.dm +++ b/code/modules/reagents/chemistry/reagents/medicine.dm @@ -115,7 +115,11 @@ M.adjustToxLoss(-3) M.adjustBruteLoss(-12) M.adjustFireLoss(-12) - M.status_flags &= ~DISFIGURED + if(ishuman(M)) + var/mob/living/carbon/human/H = M + var/obj/item/organ/external/head/head = H.get_organ("head") + if(head) + head.disfigured = FALSE ..() /datum/reagent/medicine/rezadone @@ -131,7 +135,11 @@ M.adjustCloneLoss(-1) //What? We just set cloneloss to 0. Why? Simple; this is so external organs properly unmutate. M.adjustBruteLoss(-1) M.adjustFireLoss(-1) - M.status_flags &= ~DISFIGURED + if(ishuman(M)) + var/mob/living/carbon/human/H = M + var/obj/item/organ/external/head/head = H.get_organ("head") + if(head) + head.disfigured = FALSE ..() /datum/reagent/medicine/rezadone/overdose_process(mob/living/M, severity) diff --git a/code/modules/reagents/chemistry/reagents/toxins.dm b/code/modules/reagents/chemistry/reagents/toxins.dm index 0dbd2224e92..7bff61218c6 100644 --- a/code/modules/reagents/chemistry/reagents/toxins.dm +++ b/code/modules/reagents/chemistry/reagents/toxins.dm @@ -611,11 +611,11 @@ return if(!H.unacidable) - var/obj/item/organ/external/affecting = H.get_organ("head") - affecting.receive_damage(0, 75) + var/obj/item/organ/external/head/affecting = H.get_organ("head") + if(affecting) + affecting.receive_damage(0, 75) H.UpdateDamageIcon() H.emote("scream") - H.status_flags |= DISFIGURED /datum/reagent/facid/reaction_obj(obj/O, volume) if((istype(O, /obj/item) || istype(O, /obj/structure/glowshroom))) @@ -947,8 +947,7 @@ /datum/reagent/glyphosate/reaction_obj(obj/O, volume) if(istype(O,/obj/structure/alien/weeds)) var/obj/structure/alien/weeds/alien_weeds = O - alien_weeds.health -= rand(15,35) // Kills alien weeds pretty fast - alien_weeds.healthcheck() + alien_weeds.take_damage(rand(15, 35), BRUTE, 0) // Kills alien weeds pretty fast else if(istype(O, /obj/structure/glowshroom)) //even a small amount is enough to kill it qdel(O) else if(istype(O, /obj/structure/spacevine)) diff --git a/code/modules/reagents/reagent_containers/glass_containers.dm b/code/modules/reagents/reagent_containers/glass_containers.dm index 39d3babf4bc..6b0dc98dd37 100644 --- a/code/modules/reagents/reagent_containers/glass_containers.dm +++ b/code/modules/reagents/reagent_containers/glass_containers.dm @@ -42,7 +42,8 @@ /obj/machinery/constructable_frame, /obj/machinery/icemachine, /obj/item/bombcore/chemical, - /obj/machinery/vending) + /obj/machinery/vending, + /obj/machinery/fishtank) /obj/item/reagent_containers/glass/New() ..() diff --git a/code/modules/reagents/reagent_containers/spray.dm b/code/modules/reagents/reagent_containers/spray.dm index 02d71db8719..fa709fd7d98 100644 --- a/code/modules/reagents/reagent_containers/spray.dm +++ b/code/modules/reagents/reagent_containers/spray.dm @@ -49,14 +49,14 @@ user.newtonian_move(get_dir(A, user)) if(reagents.has_reagent("sacid")) - msg_admin_attack("[key_name_admin(user)] fired sulphuric acid from \a [src] at [COORD(src)].") - log_game("[key_name(user)] fired sulphuric acid from \a [src] at [COORD(src)].") + msg_admin_attack("[key_name_admin(user)] fired sulphuric acid from \a [src] at [COORD(user)].") + log_game("[key_name(user)] fired sulphuric acid from \a [src] at [COORD(user)].") if(reagents.has_reagent("facid")) - msg_admin_attack("[key_name_admin(user)] fired fluorosulfuric acid from \a [src] at [COORD(src)].") - log_game("[key_name(user)] fired fluorosulfuric Acid from \a [src] at [COORD(src)].") + msg_admin_attack("[key_name_admin(user)] fired fluorosulfuric acid from \a [src] at [COORD(user)].") + log_game("[key_name(user)] fired fluorosulfuric Acid from \a [src] at [COORD(user)].") if(reagents.has_reagent("lube")) - msg_admin_attack("[key_name_admin(user)] fired space lube from \a [src] at [COORD(src)].") - log_game("[key_name(user)] fired space lube from \a [src] at [COORD(src)].") + msg_admin_attack("[key_name_admin(user)] fired space lube from \a [src] at [COORD(user)].") + log_game("[key_name(user)] fired space lube from \a [src] at [COORD(user)].") return diff --git a/code/modules/research/designs/smelting_designs.dm b/code/modules/research/designs/smelting_designs.dm index fe45e8dacad..a043d90fb19 100644 --- a/code/modules/research/designs/smelting_designs.dm +++ b/code/modules/research/designs/smelting_designs.dm @@ -25,6 +25,22 @@ build_path = /obj/item/stack/sheet/plasmaglass category = list("initial") +/datum/design/titaniumglass_alloy + name = "Titanium + Glass alloy" + id = "titaniumglass" + build_type = SMELTER + materials = list(MAT_TITANIUM = MINERAL_MATERIAL_AMOUNT, MAT_GLASS = MINERAL_MATERIAL_AMOUNT) + build_path = /obj/item/stack/sheet/titaniumglass + category = list("initial") + +/datum/design/plastitaniumglass_alloy + name = "Plasma + Titanium + Glass alloy" + id = "plastitaniumglass" + build_type = SMELTER + materials = list(MAT_PLASMA = MINERAL_MATERIAL_AMOUNT, MAT_TITANIUM = MINERAL_MATERIAL_AMOUNT, MAT_GLASS = MINERAL_MATERIAL_AMOUNT) + build_path = /obj/item/stack/sheet/plastitaniumglass + category = list("initial") + /datum/design/alienalloy name = "Alien Alloy" desc = "A sheet of reverse-engineered alien alloy." diff --git a/code/modules/research/xenobiology/xenobio_camera.dm b/code/modules/research/xenobiology/xenobio_camera.dm index f7976645bc4..dcae187b028 100644 --- a/code/modules/research/xenobiology/xenobio_camera.dm +++ b/code/modules/research/xenobiology/xenobio_camera.dm @@ -22,7 +22,6 @@ desc = "A computer used for remotely handling slimes." networks = list("SS13") circuit = /obj/item/circuitboard/xenobiology - off_action = new /datum/action/innate/camera_off/xenobio var/datum/action/innate/slime_place/slime_place_action = new var/datum/action/innate/slime_pick_up/slime_up_action = new var/datum/action/innate/feed_slime/feed_slime_action = new @@ -43,23 +42,27 @@ eyeobj.icon_state = "camera_target" /obj/machinery/computer/camera_advanced/xenobio/GrantActions(mob/living/carbon/user) - off_action.target = user - off_action.Grant(user) + ..() + if(slime_up_action) + slime_up_action.target = src + slime_up_action.Grant(user) + actions += slime_up_action + + if(slime_place_action) + slime_place_action.target = src + slime_place_action.Grant(user) + actions += slime_place_action + + if(feed_slime_action) + feed_slime_action.target = src + feed_slime_action.Grant(user) + actions += feed_slime_action + + if(monkey_recycle_action) + monkey_recycle_action.target = src + monkey_recycle_action.Grant(user) + actions += monkey_recycle_action - jump_action.target = user - jump_action.Grant(user) - - slime_up_action.target = src - slime_up_action.Grant(user) - - slime_place_action.target = src - slime_place_action.Grant(user) - - feed_slime_action.target = src - feed_slime_action.Grant(user) - - monkey_recycle_action.target = src - monkey_recycle_action.Grant(user) /obj/machinery/computer/camera_advanced/xenobio/attack_hand(mob/user) @@ -87,31 +90,6 @@ return ..() -/datum/action/innate/camera_off/xenobio/Activate() - if(!target || !ishuman(target)) - return - var/mob/living/carbon/C = target - var/mob/camera/aiEye/remote/xenobio/remote_eye = C.remote_control - var/obj/machinery/computer/camera_advanced/xenobio/origin = remote_eye.origin - C.remote_view = 0 - origin.current_user = null - origin.jump_action.Remove(C) - origin.slime_place_action.Remove(C) - origin.slime_up_action.Remove(C) - origin.feed_slime_action.Remove(C) - origin.monkey_recycle_action.Remove(C) - //All of this stuff below could probably be a proc for all advanced cameras, only the action removal needs to be camera specific - remote_eye.eye_user = null - C.reset_perspective(null) - if(C.client) - C.client.images -= remote_eye.user_image - for(var/datum/camerachunk/chunk in remote_eye.visibleCameraChunks) - C.client.images -= chunk.obscured - C.remote_control = null - C.unset_machine() - src.Remove(C) - - /datum/action/innate/slime_place name = "Place Slimes" button_icon_state = "slime_down" diff --git a/code/modules/scripting/Implementations/Telecomms.dm b/code/modules/scripting/Implementations/Telecomms.dm index 16640a8b4c8..a24a9522b38 100644 --- a/code/modules/scripting/Implementations/Telecomms.dm +++ b/code/modules/scripting/Implementations/Telecomms.dm @@ -24,14 +24,22 @@ interpreter.GC() +//temp +/datum/TCS_Compiler + var/datum/n_scriptOptions/nS_Options/options + var/datum/n_Scanner/nS_Scanner/scanner + var/list/tokens + var/datum/n_Parser/nS_Parser/parser + var/datum/node/BlockDefinition/GlobalBlock/program + /* -- Compile a raw block of text -- */ -/datum/TCS_Compiler/proc/Compile(code as message) - var/datum/n_scriptOptions/nS_Options/options = new() - var/datum/n_Scanner/nS_Scanner/scanner = new(code, options) - var/list/tokens = scanner.Scan() - var/datum/n_Parser/nS_Parser/parser = new(tokens, options) - var/datum/node/BlockDefinition/GlobalBlock/program = parser.Parse() +/datum/TCS_Compiler/proc/Compile(list/code) + options = new() + scanner = new(code, options) + tokens = scanner.Scan() + parser = new(tokens, options) + program = parser.Parse() var/list/returnerrors = list() diff --git a/code/modules/scripting/Interpreter/Interpreter.dm b/code/modules/scripting/Interpreter/Interpreter.dm index 79802ff2fa5..c24e9ba5e3a 100644 --- a/code/modules/scripting/Interpreter/Interpreter.dm +++ b/code/modules/scripting/Interpreter/Interpreter.dm @@ -184,6 +184,8 @@ Runs each statement in a block of code. else RaiseError(new/datum/runtimeError/UnknownInstruction()) + CHECK_TICK + if(status) break diff --git a/code/modules/scripting/Options.dm b/code/modules/scripting/Options.dm index b27acff91d3..be471756359 100644 --- a/code/modules/scripting/Options.dm +++ b/code/modules/scripting/Options.dm @@ -36,11 +36,12 @@ File: Options if(!CanStartID(id)) //don't need to grab first char in id, since text2ascii does it automatically return 0 - if(length(id) == 1) + var/list/charmap = string2charlist(id) + if(charmap.len == 1) return 1 - for(var/i=2 to length(id)) - if(!IsValidIDChar(copytext(id, i, i + 1))) + for(var/i = 2 to charmap.len) + if(!IsValidIDChar(charmap[i])) return 0 return 1 diff --git a/code/modules/scripting/Scanner/Scanner.dm b/code/modules/scripting/Scanner/Scanner.dm index 011621c8ea8..da6a2c04803 100644 --- a/code/modules/scripting/Scanner/Scanner.dm +++ b/code/modules/scripting/Scanner/Scanner.dm @@ -6,7 +6,7 @@ An object responsible for breaking up source code into tokens for use by the parser. */ /datum/n_Scanner - var/code + var/list/code /* Var: errors A list of fatal errors found by the scanner. If there are any items in this list, then it is not safe to parse the returned tokens. @@ -25,7 +25,7 @@ Proc: LoadCode Loads source code. */ -/datum/n_Scanner/proc/LoadCode(var/c) +/datum/n_Scanner/proc/LoadCode(var/list/c) code=c /* @@ -100,24 +100,23 @@ code - The source code to tokenize. options - An object used to configure the scanner. */ -/datum/n_Scanner/nS_Scanner/New(var/code, var/datum/n_scriptOptions/nS_Options/options) +/datum/n_Scanner/nS_Scanner/New(var/list/c, var/datum/n_scriptOptions/nS_Options/options) . = ..() ignore += ascii2text(13) //Carriage return delim += ignore + options.symbols + end_stmt + string_delim src.options = options - LoadCode(code) + LoadCode(c) /datum/n_Scanner/nS_Scanner/Scan() //Creates a list of tokens from source code var/list/tokens = new - for(, src.codepos <= length(code), src.codepos++) - - var/char = copytext(code, codepos, codepos + 1) - var/nextchar = copytext(code, codepos + 1, codepos + 2) + for(, src.codepos <= code.len, src.codepos++) + var/char = code[codepos] + var/nextchar = TCOMMS_SAFE_INDEX(code, codepos + 1) if(char == "\n") line++ linepos = codepos - if(ignore.Find(char)) + if(char in ignore) continue else if(char == "/" && (nextchar == "*" || nextchar == "/")) @@ -139,6 +138,7 @@ else if(options.symbols.Find(char)) tokens += ReadSymbol() + CHECK_TICK codepos = initial(codepos) line = initial(line) @@ -155,12 +155,12 @@ */ /datum/n_Scanner/nS_Scanner/proc/ReadString(start) var/buf - for(, codepos <= length(code), codepos++)//codepos to length(code)) - var/char = copytext(code, codepos, codepos + 1) + for(, codepos <= code.len, codepos++)//codepos to length(code)) + var/char = code[codepos] switch(char) if("\\") //Backslash (\) encountered in string codepos++ //Skip next character in string, since it was escaped by a backslash - char = copytext(code, codepos, codepos+1) + char = TCOMMS_SAFE_INDEX(code, codepos) switch(char) if("\\") //Double backslash buf += "\\" @@ -190,12 +190,14 @@ Reads characters separated by an item in into a token. */ /datum/n_Scanner/nS_Scanner/proc/ReadWord() - var/char = copytext(code, codepos, codepos + 1) + var/char = code[codepos] var/buf - while(!delim.Find(char) && codepos <= length(code)) + while(!delim.Find(char)) buf += char - char = copytext(code, ++codepos, codepos + 1) + if(++codepos > code.len) break + char = code[codepos] + codepos-- //allow main Scan() proc to read the delimiter if(options.keywords.Find(buf)) return new/datum/token/keyword(buf, line, COL) @@ -207,13 +209,13 @@ Reads a symbol into a token. */ /datum/n_Scanner/nS_Scanner/proc/ReadSymbol() - var/char=copytext(code, codepos, codepos + 1) + var/char = code[codepos] var/buf while(options.symbols.Find(buf + char)) buf += char - if(++codepos > length(code)) break - char = copytext(code, codepos, codepos + 1) + if(++codepos > code.len) break + char = code[codepos] codepos-- //allow main Scan() proc to read the next character return new /datum/token/symbol(buf, line, COL) @@ -223,7 +225,7 @@ Reads a number into a token. */ /datum/n_Scanner/nS_Scanner/proc/ReadNumber() - var/char = copytext(code, codepos, codepos + 1) + var/char = code[codepos] var/buf var/dec = 0 @@ -233,7 +235,7 @@ buf += char codepos++ - char = copytext(code, codepos, codepos + 1) + char = TCOMMS_SAFE_INDEX(code, codepos) var/datum/token/number/T = new(buf, line, COL) if(isnull(text2num(buf))) @@ -249,8 +251,8 @@ */ /datum/n_Scanner/nS_Scanner/proc/ReadComment() - var/char = copytext(code, codepos, codepos + 1) - var/nextchar = copytext(code, codepos + 1, codepos + 2) + var/char = code[codepos] + var/nextchar = TCOMMS_SAFE_INDEX(code, codepos + 1) var/charstring = char + nextchar var/comm = 1 // 1: single-line comment @@ -262,23 +264,23 @@ comm = 2 // starts a multi-line comment while(comm) - if(++codepos > length(code)) + if(++codepos > code.len) break if(expectedend) // ending statement expected... - char = copytext(code, codepos, codepos + 1) + char = code[codepos] if(char == "/") // ending statement found - beak the comment comm = 0 break if(comm == 2) // multi-line comments are broken by ending statements - char = copytext(code, codepos, codepos + 1) + char = code[codepos] if(char == "*") expectedend = 1 continue else - char = copytext(code, codepos, codepos + 1) + char = code[codepos] if(char == "\n") comm = 0 break diff --git a/code/modules/scripting/__defines.dm b/code/modules/scripting/__defines.dm new file mode 100644 index 00000000000..52f30e68fdc --- /dev/null +++ b/code/modules/scripting/__defines.dm @@ -0,0 +1 @@ +#define TCOMMS_SAFE_INDEX(list, index) list.len > index ? list[index] : null diff --git a/code/modules/shuttle/shuttle.dm b/code/modules/shuttle/shuttle.dm index c8f36cfa37e..54f4836ff5b 100644 --- a/code/modules/shuttle/shuttle.dm +++ b/code/modules/shuttle/shuttle.dm @@ -1,4 +1,5 @@ //use this define to highlight docking port bounding boxes (ONLY FOR DEBUG USE) +// also uncomment the #undef at the bottom of the file //#define DOCKING_PORT_HIGHLIGHT //NORTH default dir @@ -909,7 +910,7 @@ var/global/trade_dockrequest_timelimit = 0 shuttleId = "trade_sol" docking_request_message = "A trading ship of Sol origin has requested docking aboard the NSS Cyberiad for trading. This request can be accepted or denied using a communications console." -#undef DOCKING_PORT_HIGHLIGHT +//#undef DOCKING_PORT_HIGHLIGHT /turf/proc/copyTurf(turf/T) diff --git a/code/modules/spacepods/spacepod.dm b/code/modules/spacepods/spacepod.dm index 794e5f69bfe..97e34eee154 100644 --- a/code/modules/spacepods/spacepod.dm +++ b/code/modules/spacepods/spacepod.dm @@ -1,6 +1,6 @@ #define DAMAGE 1 #define FIRE 2 -#define LIGHT 1 +#define POD_LIGHT 1 #define WINDOW 2 #define RIM 3 #define PAINT 4 @@ -78,7 +78,7 @@ var/part = input(user, "Choose part", null) as null|anything in list("Lights","Rim","Paint","Windows") switch(part) if("Lights") - part_type = LIGHT + part_type = POD_LIGHT if("Rim") part_type = RIM if("Paint") @@ -101,7 +101,7 @@ pod_overlays[FIRE] = image(icon, icon_state="pod_fire") if(!pod_paint_effect) pod_paint_effect = new/list(4) - pod_paint_effect[LIGHT] = image(icon,icon_state = "LIGHTS") + pod_paint_effect[POD_LIGHT] = image(icon,icon_state = "LIGHTS") pod_paint_effect[WINDOW] = image(icon,icon_state = "Windows") pod_paint_effect[RIM] = image(icon,icon_state = "RIM") pod_paint_effect[PAINT] = image(icon,icon_state = "PAINT") @@ -162,7 +162,7 @@ if(!pod_paint_effect) pod_paint_effect = new/list(4) - pod_paint_effect[LIGHT] = image(icon,icon_state = "LIGHTS") + pod_paint_effect[POD_LIGHT] = image(icon,icon_state = "LIGHTS") pod_paint_effect[WINDOW] = image(icon,icon_state = "Windows") pod_paint_effect[RIM] = image(icon,icon_state = "RIM") pod_paint_effect[PAINT] = image(icon,icon_state = "PAINT") @@ -170,9 +170,9 @@ if(has_paint) var/image/to_add - if(!isnull(pod_paint_effect[LIGHT])) - to_add = pod_paint_effect[LIGHT] - to_add.color = colors[LIGHT] + if(!isnull(pod_paint_effect[POD_LIGHT])) + to_add = pod_paint_effect[POD_LIGHT] + to_add.color = colors[POD_LIGHT] overlays += to_add if(!isnull(pod_paint_effect[WINDOW])) to_add = pod_paint_effect[WINDOW] @@ -1077,6 +1077,6 @@ obj/spacepod/proc/add_equipment(mob/user, var/obj/item/spacepod_equipment/SPE, v #undef DAMAGE #undef FIRE #undef WINDOW -#undef LIGHT +#undef POD_LIGHT #undef RIM #undef PAINT diff --git a/code/modules/surgery/bones.dm b/code/modules/surgery/bones.dm index dfe2c0feb8c..a053b568dc7 100644 --- a/code/modules/surgery/bones.dm +++ b/code/modules/surgery/bones.dm @@ -49,7 +49,7 @@ var/obj/item/organ/external/affected = target.get_organ(target_zone) user.visible_message("[user] starts applying medication to the damaged bones in [target]'s [affected.name] with \the [tool]." , \ "You start applying medication to the damaged bones in [target]'s [affected.name] with \the [tool].") - target.custom_pain("Something in your [affected.name] is causing you a lot of pain!",1) + target.custom_pain("Something in your [affected.name] is causing you a lot of pain!") ..() /datum/surgery_step/glue_bone/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) @@ -83,7 +83,7 @@ var/obj/item/organ/external/affected = target.get_organ(target_zone) user.visible_message("[user] is beginning to set the bone in [target]'s [affected.name] in place with \the [tool]." , \ "You are beginning to set the bone in [target]'s [affected.name] in place with \the [tool].") - target.custom_pain("The pain in your [affected.name] is going to make you pass out!",1) + target.custom_pain("The pain in your [affected.name] is going to make you pass out!") ..() /datum/surgery_step/set_bone/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) @@ -136,7 +136,7 @@ "Your hand slips, damaging [target]'s face with \the [tool]!") var/obj/item/organ/external/head/h = affected h.receive_damage(10) - h.disfigured = 1 + h.disfigure() return 0 /datum/surgery_step/finish_bone diff --git a/code/modules/surgery/cavity_implant.dm b/code/modules/surgery/cavity_implant.dm index 0e88927e1a2..2ab2aca37c7 100644 --- a/code/modules/surgery/cavity_implant.dm +++ b/code/modules/surgery/cavity_implant.dm @@ -78,7 +78,7 @@ var/obj/item/organ/external/affected = target.get_organ(target_zone) user.visible_message("[user] starts making some space inside [target]'s [get_cavity(affected)] cavity with \the [tool].", \ "You start making some space inside [target]'s [get_cavity(affected)] cavity with \the [tool]." ) - target.custom_pain("The pain in your chest is living hell!",1) + target.custom_pain("The pain in your chest is living hell!") ..() /datum/surgery_step/cavity/make_space/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) @@ -104,7 +104,7 @@ var/obj/item/organ/external/affected = target.get_organ(target_zone) user.visible_message("[user] starts mending [target]'s [get_cavity(affected)] cavity wall with \the [tool].", \ "You start mending [target]'s [get_cavity(affected)] cavity wall with \the [tool]." ) - target.custom_pain("The pain in your chest is living hell!",1) + target.custom_pain("The pain in your chest is living hell!") ..() /datum/surgery_step/cavity/close_space/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) @@ -155,7 +155,7 @@ else //no internal items..but we still need a message! user.visible_message("[user] checks for items in [target]'s [target_zone].", "You check for items in [target]'s [target_zone]...") - target.custom_pain("The pain in your [target_zone] is living hell!",1) + target.custom_pain("The pain in your [target_zone] is living hell!") ..() /datum/surgery_step/cavity/place_item/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) @@ -190,7 +190,7 @@ if((tool.w_class > get_max_wclass(affected)/2 && prob(50) && !(affected.status & ORGAN_ROBOT))) to_chat(user, " You tear some vessels trying to fit the object in the cavity.") affected.internal_bleeding = TRUE - affected.owner.custom_pain("You feel something rip in your [affected.name]!", 1) + affected.owner.custom_pain("You feel something rip in your [affected.name]!") user.drop_item() affected.hidden = tool tool.forceMove(affected) diff --git a/code/modules/surgery/encased.dm b/code/modules/surgery/encased.dm index eddf116a45d..b9a33fcecab 100644 --- a/code/modules/surgery/encased.dm +++ b/code/modules/surgery/encased.dm @@ -38,7 +38,7 @@ user.visible_message("[user] begins to cut through [target]'s [affected.encased] with \the [tool].", \ "You begin to cut through [target]'s [affected.encased] with \the [tool].") - target.custom_pain("Something hurts horribly in your [affected.name]!",1) + target.custom_pain("Something hurts horribly in your [affected.name]!") ..() /datum/surgery_step/open_encased/saw/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) @@ -86,7 +86,7 @@ var/msg = "[user] starts to force open the [affected.encased] in [target]'s [affected.name] with \the [tool]." var/self_msg = "You start to force open the [affected.encased] in [target]'s [affected.name] with \the [tool]." user.visible_message(msg, self_msg) - target.custom_pain("Something hurts horribly in your [affected.name]!",1) + target.custom_pain("Something hurts horribly in your [affected.name]!") ..() /datum/surgery_step/open_encased/retract/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) @@ -137,7 +137,7 @@ var/msg = "[user] starts bending [target]'s [affected.encased] back into place with \the [tool]." var/self_msg = "You start bending [target]'s [affected.encased] back into place with \the [tool]." user.visible_message(msg, self_msg) - target.custom_pain("Something hurts horribly in your [affected.name]!",1) + target.custom_pain("Something hurts horribly in your [affected.name]!") ..() /datum/surgery_step/open_encased/close/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) @@ -187,7 +187,7 @@ var/msg = "[user] starts applying \the [tool] to [target]'s [affected.encased]." var/self_msg = "You start applying \the [tool] to [target]'s [affected.encased]." user.visible_message(msg, self_msg) - target.custom_pain("Something hurts horribly in your [affected.name]!",1) + target.custom_pain("Something hurts horribly in your [affected.name]!") ..() /datum/surgery_step/open_encased/mend/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) diff --git a/code/modules/surgery/face.dm b/code/modules/surgery/face.dm deleted file mode 100644 index d96db814b78..00000000000 --- a/code/modules/surgery/face.dm +++ /dev/null @@ -1,147 +0,0 @@ -//Procedures in this file: Facial reconstruction surgery -////////////////////////////////////////////////////////////////// -// FACE SURGERY // -////////////////////////////////////////////////////////////////// -/datum/surgery/plastic_surgery - name = "Face Repair" - steps = list(/datum/surgery_step/generic/cut_face, /datum/surgery_step/generic/retract_skin, /datum/surgery_step/face/mend_vocal, /datum/surgery_step/face/fix_face,/datum/surgery_step/face/cauterize) - possible_locs = list("head") - - - -/datum/surgery/plastic_surgery/can_start(mob/user, mob/living/carbon/target) - if(istype(target,/mob/living/carbon/human)) - var/mob/living/carbon/human/H = target - var/obj/item/organ/external/affected = H.get_organ(user.zone_sel.selecting) - if(!affected) - return 0 - if(affected.status & ORGAN_ROBOT) - return 0 - if(!affected.disfigured) - return 0 - return 1 - -/datum/surgery_step/face - priority = 2 - can_infect = 0 - -/datum/surgery_step/generic/cut_face - name = "make incision" - allowed_tools = list( - /obj/item/scalpel = 100, \ - /obj/item/kitchen/knife = 90, \ - /obj/item/shard = 60, \ - ) - - time = 16 - -/datum/surgery_step/generic/cut_face/begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) - user.visible_message("[user] starts to cut open [target]'s face and neck with \the [tool].", \ - "You start to cut open [target]'s face and neck with \the [tool].") - ..() - -/datum/surgery_step/generic/cut_face/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) - user.visible_message(" [user] has cut open [target]'s face and neck with \the [tool]." , \ - " You have cut open [target]'s face and neck with \the [tool].",) - - return 1 - -/datum/surgery_step/generic/cut_face/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - user.visible_message(" [user]'s hand slips, slicing [target]'s throat wth \the [tool]!" , \ - " Your hand slips, slicing [target]'s throat wth \the [tool]!" ) - affected.receive_damage(60) - target.AdjustLoseBreath(4) - - return 0 - -/datum/surgery_step/face/mend_vocal - name = "mend vocal cords" - allowed_tools = list( - /obj/item/scalpel/laser/manager = 100, \ - /obj/item/hemostat = 100, \ - /obj/item/stack/cable_coil = 90, \ - /obj/item/assembly/mousetrap = 12 //I don't know. Don't ask me. But I'm leaving it because hilarity. - ) - - time = 24 - -/datum/surgery_step/face/mend_vocal/begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) - user.visible_message("[user] starts mending [target]'s vocal cords with \the [tool].", \ - "You start mending [target]'s vocal cords with \the [tool].") - ..() - -/datum/surgery_step/face/mend_vocal/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) - user.visible_message(" [user] mends [target]'s vocal cords with \the [tool].", \ - " You mend [target]'s vocal cords with \the [tool].") - return 1 - -/datum/surgery_step/face/mend_vocal/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) - user.visible_message(" [user]'s hand slips, clamping [target]'s trachea shut for a moment with \the [tool]!", \ - " Your hand slips, clamping [user]'s trachea shut for a moment with \the [tool]!") - target.AdjustLoseBreath(4) - return 0 - -/datum/surgery_step/face/fix_face - name = "reshape face" - allowed_tools = list( - /obj/item/scalpel/laser/manager = 100, \ - /obj/item/retractor = 100, \ - /obj/item/crowbar = 65, \ - /obj/item/kitchen/utensil/fork = 90) - - time = 64 - -/datum/surgery_step/face/fix_face/begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) - user.visible_message("[user] starts pulling skin on [target]'s face back in place with \the [tool].", \ - "You start pulling skin on [target]'s face back in place with \the [tool].") - ..() - -/datum/surgery_step/face/fix_face/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) - user.visible_message(" [user] pulls skin on [target]'s face back in place with \the [tool].", \ - " You pull skin on [target]'s face back in place with \the [tool].") - return 1 - -/datum/surgery_step/face/fix_face/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - user.visible_message(" [user]'s hand slips, tearing skin on [target]'s face with \the [tool]!", \ - " Your hand slips, tearing skin on [target]'s face with \the [tool]!") - target.apply_damage(10, BRUTE, affected, sharp = 1) - return 0 - -/datum/surgery_step/face/cauterize - name = "close incision" - allowed_tools = list( - /obj/item/scalpel/laser = 100, \ - /obj/item/cautery = 100, \ - /obj/item/clothing/mask/cigarette = 90, \ - /obj/item/lighter = 60, \ - /obj/item/weldingtool = 30 - ) - - time = 24 - -/datum/surgery_step/face/cauterize/begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) - user.visible_message("[user] is beginning to cauterize the incision on [target]'s face and neck with \the [tool]." , \ - "You are beginning to cauterize the incision on [target]'s face and neck with \the [tool].") - ..() - -/datum/surgery_step/face/cauterize/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - user.visible_message(" [user] cauterizes the incision on [target]'s face and neck with \the [tool].", \ - " You cauterize the incision on [target]'s face and neck with \the [tool].") - affected.open = 0 - var/obj/item/organ/external/head/h = affected - h.disfigured = 0 - h.update_icon() - target.regenerate_icons() - - return 1 - -/datum/surgery_step/face/cauterize/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - user.visible_message(" [user]'s hand slips, leaving a small burn on [target]'s face with \the [tool]!", \ - " Your hand slips, leaving a small burn on [target]'s face with \the [tool]!") - target.apply_damage(4, BURN, affected) - - return 0 diff --git a/code/modules/surgery/generic.dm b/code/modules/surgery/generic.dm index 158656f8c01..1e1b3a10365 100644 --- a/code/modules/surgery/generic.dm +++ b/code/modules/surgery/generic.dm @@ -37,7 +37,7 @@ var/obj/item/organ/external/affected = target.get_organ(target_zone) user.visible_message("[user] starts the incision on [target]'s [affected.name] with \the [tool].", \ "You start the incision on [target]'s [affected.name] with \the [tool].") - target.custom_pain("You feel a horrible pain as if from a sharp knife in your [affected.name]!",1) + target.custom_pain("You feel a horrible pain as if from a sharp knife in your [affected.name]!") ..() /datum/surgery_step/generic/cut_open/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) @@ -71,7 +71,7 @@ var/obj/item/organ/external/affected = target.get_organ(target_zone) user.visible_message("[user] starts clamping bleeders in [target]'s [affected.name] with \the [tool].", \ "You start clamping bleeders in [target]'s [affected.name] with \the [tool].") - target.custom_pain("The pain in your [affected.name] is maddening!",1) + target.custom_pain("The pain in your [affected.name] is maddening!") ..() /datum/surgery_step/generic/clamp_bleeders/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) @@ -111,7 +111,7 @@ msg = "[user] starts to pry open the incision and rearrange the organs in [target]'s lower abdomen with \the [tool]." self_msg = "You start to pry open the incision and rearrange the organs in [target]'s lower abdomen with \the [tool]." user.visible_message(msg, self_msg) - target.custom_pain("It feels like the skin on your [affected.name] is on fire!",1) + target.custom_pain("It feels like the skin on your [affected.name] is on fire!") ..() /datum/surgery_step/generic/retract_skin/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) @@ -160,7 +160,7 @@ var/obj/item/organ/external/affected = target.get_organ(target_zone) user.visible_message("[user] is beginning to cauterize the incision on [target]'s [affected.name] with \the [tool]." , \ "You are beginning to cauterize the incision on [target]'s [affected.name] with \the [tool].") - target.custom_pain("Your [affected.name] is being burned!",1) + target.custom_pain("Your [affected.name] is being burned!") ..() /datum/surgery_step/generic/cauterize/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) @@ -219,7 +219,7 @@ var/obj/item/organ/external/affected = target.get_organ(target_zone) user.visible_message("[user] is beginning to amputate [target]'s [affected.name] with \the [tool]." , \ "You are beginning to cut through [target]'s [affected.amputation_point] with \the [tool].") - target.custom_pain("Your [affected.amputation_point] is being ripped apart!",1) + target.custom_pain("Your [affected.amputation_point] is being ripped apart!") ..() /datum/surgery_step/generic/amputate/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) diff --git a/code/modules/surgery/implant_removal.dm b/code/modules/surgery/implant_removal.dm index 7518cc701af..c36df974ea3 100644 --- a/code/modules/surgery/implant_removal.dm +++ b/code/modules/surgery/implant_removal.dm @@ -45,7 +45,7 @@ I = locate(/obj/item/implant) in target user.visible_message("[user] starts poking around inside [target]'s [affected.name] with \the [tool].", \ "You start poking around inside [target]'s [affected.name] with \the [tool]." ) - target.custom_pain("The pain in your [affected.name] is living hell!",1) + target.custom_pain("The pain in your [affected.name] is living hell!") ..() /datum/surgery_step/extract_implant/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) diff --git a/code/modules/surgery/organs/organ.dm b/code/modules/surgery/organs/organ.dm index 8a29c148253..4908133d2c0 100644 --- a/code/modules/surgery/organs/organ.dm +++ b/code/modules/surgery/organs/organ.dm @@ -30,6 +30,7 @@ var/sterile = FALSE //can the organ be infected by germs? var/tough = FALSE //can organ be easily damaged? var/emp_proof = FALSE //is the organ immune to EMPs? + var/hidden_pain = FALSE //will it skip pain messages? /obj/item/organ/Destroy() @@ -232,7 +233,7 @@ if(owner && parent_organ && amount > 0) var/obj/item/organ/external/parent = owner.get_organ(parent_organ) if(parent && !silent) - owner.custom_pain("Something inside your [parent.name] hurts a lot.", 1) + owner.custom_pain("Something inside your [parent.name] hurts a lot.") //check if we've hit max_damage if(damage >= max_damage) diff --git a/code/modules/surgery/organs/organ_external.dm b/code/modules/surgery/organs/organ_external.dm index 794c19e2655..960ce7c0da1 100644 --- a/code/modules/surgery/organs/organ_external.dm +++ b/code/modules/surgery/organs/organ_external.dm @@ -239,7 +239,6 @@ #undef LIMB_SHARP_THRESH_INT_DMG #undef LIMB_THRESH_INT_DMG #undef LIMB_DMG_PROB -#undef LIMB_NO_BONE_DMG_PROB /obj/item/organ/external/proc/heal_damage(brute, burn, internal = 0, robo_repair = 0) if(status & ORGAN_ROBOT && !robo_repair) @@ -273,8 +272,7 @@ This function completely restores a damaged organ to perfect condition. burn_dam = 0 open = 0 //Closing all wounds. internal_bleeding = FALSE - if(istype(src, /obj/item/organ/external/head) && disfigured) //If their head's disfigured, refigure it. - disfigured = 0 + disfigured = FALSE // handle internal organs for(var/obj/item/organ/internal/current_organ in internal_organs) @@ -409,7 +407,7 @@ Note that amputating the affected organ does in fact remove the infection from t var/local_damage = brute_dam + damage if(damage > 15 && local_damage > 30 && prob(damage) && !(status & ORGAN_ROBOT)) internal_bleeding = TRUE - owner.custom_pain("You feel something rip in your [name]!", 1) + owner.custom_pain("You feel something rip in your [name]!") // new damage icon system // returns just the brute/burn damage code @@ -737,19 +735,14 @@ Note that amputating the affected organ does in fact remove the infection from t qdel(spark_system) qdel(src) -/obj/item/organ/external/proc/disfigure(var/type = "brute") +/obj/item/organ/external/proc/disfigure() if(disfigured) return if(owner) - if(type == "brute") - owner.visible_message("You hear a sickening cracking sound coming from \the [owner]'s [name].", \ - "Your [name] becomes a mangled mess!", \ - "You hear a sickening crack.") - else - owner.visible_message("\The [owner]'s [name] melts away, turning into mangled mess!", \ - "Your [name] melts away!", \ - "You hear a sickening sizzle.") - disfigured = 1 + owner.visible_message("You hear a sickening sound coming from \the [owner]'s [name] as it turns into a mangled mess!", \ + "Your [name] becomes a mangled mess!", \ + "You hear a sickening sound.") + disfigured = TRUE /obj/item/organ/external/is_primary_organ(var/mob/living/carbon/human/O = null) if(isnull(O)) diff --git a/code/modules/surgery/organs/pain.dm b/code/modules/surgery/organs/pain.dm index d107c7439c6..e3386aef1b3 100644 --- a/code/modules/surgery/organs/pain.dm +++ b/code/modules/surgery/organs/pain.dm @@ -1,41 +1,28 @@ -mob/var/list/pain_stored = list() -mob/var/last_pain_message = "" -mob/var/next_pain_time = 0 +/mob/living/carbon/human + var/last_pain_message = "" + var/next_pain_time = 0 // partname is the name of a body part // amount is a num from 1 to 100 -mob/living/carbon/proc/pain(var/partname, var/amount, var/force, var/burning = 0) - if(stat >= 2) return +/mob/living/carbon/human/proc/pain(partname, amount) + if(stat >= UNCONSCIOUS) + return if(reagents.has_reagent("sal_acid")) return if(reagents.has_reagent("morphine")) return if(reagents.has_reagent("hydrocodone")) return - if(world.time < next_pain_time && !force) + if(world.time < next_pain_time) return - if(amount > 10 && istype(src,/mob/living/carbon/human)) - if(paralysis) - AdjustParalysis(-round(amount/10)) - if(amount > 50 && prob(amount / 5)) - src:drop_item() var/msg - if(burning) - switch(amount) - if(1 to 10) - msg = "Your [partname] burns." - if(11 to 90) - msg = "Your [partname] burns badly!" - if(91 to 10000) - msg = "OH GOD! Your [partname] is on fire!" - else - switch(amount) - if(1 to 10) - msg = "Your [partname] hurts." - if(11 to 90) - msg = "Your [partname] hurts badly." - if(91 to 10000) - msg = "OH GOD! Your [partname] is hurting terribly!" + switch(amount) + if(1 to 10) + msg = "Your [partname] hurts." + if(11 to 90) + msg = "Your [partname] hurts badly." + if(91 to INFINITY) + msg = "OH GOD! Your [partname] is hurting terribly!" if(msg && (msg != last_pain_message || prob(10))) last_pain_message = msg to_chat(src, msg) @@ -43,20 +30,18 @@ mob/living/carbon/proc/pain(var/partname, var/amount, var/force, var/burning = 0 // message is the custom message to be displayed -// flash_strength is 0 for weak pain flash, 1 for strong pain flash -mob/living/carbon/human/proc/custom_pain(var/message, var/flash_strength) - if(stat >= 1) return +mob/living/carbon/human/proc/custom_pain(message) + if(stat >= UNCONSCIOUS) + return if(NO_PAIN in species.species_traits) return - if(reagents.has_reagent("morphine")) return if(reagents.has_reagent("hydrocodone")) return - var/msg = "[message]" - if(flash_strength >= 1) - msg = "[message]" + + var/msg = "[message]" // Anti message spam checks if(msg && ((msg != last_pain_message) || (world.time >= next_pain_time))) @@ -67,70 +52,33 @@ mob/living/carbon/human/proc/custom_pain(var/message, var/flash_strength) mob/living/carbon/human/proc/handle_pain() // not when sleeping - if(NO_PAIN in species.species_traits) - //While synthetics don't feel pain, they will notice their gears gunking up with residue (toxins) - if(isSynthetic()) - var/toxDamageMessage = null - var/toxMessageProb = 1 - switch(getToxLoss()) - if(25 to 50) - toxMessageProb = 1 - toxDamageMessage = "Your servos seem to be working harder." - if(50 to 75) - toxMessageProb = 2 - toxDamageMessage = "Your joints seem to stick randomly." - if(75 to INFINITY) - toxMessageProb = 5 - toxDamageMessage = "Your motors seem to slip; it really grinds your gears!" - if(toxDamageMessage && prob(toxMessageProb)) - src.custom_pain(toxDamageMessage, getToxLoss() >= 15) + if(stat >= UNCONSCIOUS) + return + if(NO_PAIN in species.species_traits) return - - if(stat >= 2) return if(reagents.has_reagent("morphine")) return if(reagents.has_reagent("hydrocodone")) return + var/maxdam = 0 var/obj/item/organ/external/damaged_organ = null for(var/obj/item/organ/external/E in bodyparts) - if(E.status & ORGAN_DEAD|ORGAN_ROBOT) continue + if((E.status & ORGAN_DEAD|ORGAN_ROBOT) || E.hidden_pain) + continue var/dam = E.get_damage() // make the choice of the organ depend on damage, // but also sometimes use one of the less damaged ones - if(dam > maxdam && (maxdam == 0 || prob(70)) ) + if(dam > maxdam && (maxdam == 0 || prob(70))) damaged_organ = E maxdam = dam if(damaged_organ) - pain(damaged_organ.name, maxdam, 0) - + pain(damaged_organ.name, maxdam) // Damage to internal organs hurts a lot. for(var/obj/item/organ/internal/I in internal_organs) - if(istype(I, /obj/item/organ/internal/brain)) //the brain has no pain receptors, and brain damage is meant to be a stealthy damage type. + if(I.hidden_pain) continue - if(I.damage > 2) if(prob(2)) + if(I.damage > 2 && prob(2)) var/obj/item/organ/external/parent = get_organ(I.parent_organ) - src.custom_pain("You feel a sharp pain in your [parent.limb_name]", 1) - - var/toxDamageMessage = null - var/toxMessageProb = 1 - switch(getToxLoss()) - if(1 to 5) - toxMessageProb = 1 - toxDamageMessage = "Your body stings slightly." - if(6 to 10) - toxMessageProb = 2 - toxDamageMessage = "Your whole body hurts a little." - if(11 to 15) - toxMessageProb = 2 - toxDamageMessage = "Your whole body hurts." - if(15 to 25) - toxMessageProb = 3 - toxDamageMessage = "Your whole body hurts badly." - if(26 to INFINITY) - toxMessageProb = 5 - toxDamageMessage = "Your body aches all over, it's driving you mad." - - if(toxDamageMessage && prob(toxMessageProb)) - src.custom_pain(toxDamageMessage, getToxLoss() >= 15) + custom_pain("You feel a sharp pain in your [parent.limb_name]") \ No newline at end of file diff --git a/code/modules/surgery/organs/subtypes/standard.dm b/code/modules/surgery/organs/subtypes/standard.dm index 3fd8effd56a..30c4e173cdc 100644 --- a/code/modules/surgery/organs/subtypes/standard.dm +++ b/code/modules/surgery/organs/subtypes/standard.dm @@ -211,11 +211,8 @@ /obj/item/organ/external/head/receive_damage(brute, burn, sharp, used_weapon = null, list/forbidden_limbs = list(), ignore_resists = FALSE) ..(brute, burn, sharp, used_weapon, forbidden_limbs, ignore_resists) if(!disfigured) - if(brute_dam > 40) - if(prob(50)) - disfigure("brute") - if(burn_dam > 40) - disfigure("burn") + if(brute_dam + burn_dam > 50) + disfigure() /obj/item/organ/external/head/proc/handle_alt_icon() if(alt_head && alt_heads_list[alt_head]) diff --git a/code/modules/surgery/organs_internal.dm b/code/modules/surgery/organs_internal.dm index 1af925c3166..4c0094592e9 100644 --- a/code/modules/surgery/organs_internal.dm +++ b/code/modules/surgery/organs_internal.dm @@ -116,7 +116,7 @@ if(affected) user.visible_message("[user] starts transplanting [tool] into [target]'s [affected.name].", \ "You start transplanting [tool] into [target]'s [affected.name].") - H.custom_pain("Someone's rooting around in your [affected.name]!",1) + H.custom_pain("Someone's rooting around in your [affected.name]!") else user.visible_message("[user] starts transplanting [tool] into [target]'s [parse_zone(target_zone)].", \ "You start transplanting [tool] into [target]'s [parse_zone(target_zone)].") @@ -143,7 +143,7 @@ self_msg = "You begin injecting [tool] into [target]'s [I.name]." user.visible_message(msg, self_msg) if(H && affected) - H.custom_pain("Something burns horribly in your [affected.name]!",1) + H.custom_pain("Something burns horribly in your [affected.name]!") else if(implement_type in implements_finsh) //same as surgery step /datum/surgery_step/open_encased/close/ @@ -159,7 +159,7 @@ user.visible_message(msg, self_msg) if(H && affected) - H.custom_pain("Something hurts horribly in your [affected.name]!",1) + H.custom_pain("Something hurts horribly in your [affected.name]!") else if(implement_type in implements_extract) current_type = "extract" @@ -188,7 +188,7 @@ user.visible_message("[user] starts to separate [target]'s [I] with [tool].", \ "You start to separate [target]'s [I] with [tool] for removal." ) if(H && affected) - H.custom_pain("The pain in your [affected.name] is living hell!",1) + H.custom_pain("The pain in your [affected.name] is living hell!") else return -1 @@ -221,7 +221,7 @@ to_chat(user, "[I] does not appear to be damaged.") if(affected) - H.custom_pain("The pain in your [affected.name] is living hell!", 1) + H.custom_pain("The pain in your [affected.name] is living hell!") else if(istype(tool, /obj/item/reagent_containers/food/snacks/organ)) to_chat(user, "[tool] was bitten by someone! It's too damaged to use!") diff --git a/code/modules/surgery/other.dm b/code/modules/surgery/other.dm index 012f7ad3c5b..455a6a8de04 100644 --- a/code/modules/surgery/other.dm +++ b/code/modules/surgery/other.dm @@ -80,7 +80,7 @@ var/obj/item/organ/external/affected = target.get_organ(target_zone) user.visible_message("[user] starts patching the damaged vein in [target]'s [affected.name] with \the [tool]." , \ "You start patching the damaged vein in [target]'s [affected.name] with \the [tool].") - target.custom_pain("The pain in [affected.name] is unbearable!",1) + target.custom_pain("The pain in [affected.name] is unbearable!") ..() /datum/surgery_step/fix_vein/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) @@ -133,7 +133,7 @@ var/obj/item/organ/external/affected = target.get_organ(target_zone) user.visible_message("[user] starts cutting away necrotic tissue in [target]'s [affected.name] with \the [tool]." , \ "You start cutting away necrotic tissue in [target]'s [affected.name] with \the [tool].") - target.custom_pain("The pain in [affected.name] is unbearable!",1) + target.custom_pain("The pain in [affected.name] is unbearable!") ..() /datum/surgery_step/fix_dead_tissue/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) @@ -191,7 +191,7 @@ var/obj/item/organ/external/affected = target.get_organ(target_zone) user.visible_message("[user] starts applying medication to the affected tissue in [target]'s [affected.name] with \the [tool]." , \ "You start applying medication to the affected tissue in [target]'s [affected.name] with \the [tool].") - target.custom_pain("Something in your [affected.name] is causing you a lot of pain!",1) + target.custom_pain("Something in your [affected.name] is causing you a lot of pain!") ..() /datum/surgery_step/treat_necrosis/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) @@ -241,7 +241,7 @@ ////////////////////////////////////////////////////////////////// /datum/surgery/remove_thrall name = "Remove Shadow Tumor" - steps = list(/datum/surgery_step/generic/cut_open, /datum/surgery_step/generic/clamp_bleeders, /datum/surgery_step/generic/retract_skin, /datum/surgery_step/open_encased/saw,/datum/surgery_step/open_encased/retract, /datum/surgery_step/internal/dethrall, /datum/surgery_step/glue_bone, /datum/surgery_step/set_bone,/datum/surgery_step/finish_bone,/datum/surgery_step/generic/cauterize) + steps = list(/datum/surgery_step/generic/cut_open, /datum/surgery_step/generic/clamp_bleeders, /datum/surgery_step/generic/retract_skin, /datum/surgery_step/internal/dethrall, /datum/surgery_step/generic/cauterize) possible_locs = list("head", "chest", "groin") /datum/surgery/remove_thrall/synth diff --git a/code/modules/surgery/plastic_surgery.dm b/code/modules/surgery/plastic_surgery.dm new file mode 100644 index 00000000000..4d14d2e8a79 --- /dev/null +++ b/code/modules/surgery/plastic_surgery.dm @@ -0,0 +1,56 @@ +/datum/surgery/plastic_surgery + name = "Plastic Surgery" + steps = list(/datum/surgery_step/generic/cut_open, /datum/surgery_step/generic/retract_skin, /datum/surgery_step/reshape_face, /datum/surgery_step/generic/cauterize) + possible_locs = list("head") + +/datum/surgery/plastic_surgery/can_start(mob/user, mob/living/carbon/target) + if(ishuman(target)) + var/mob/living/carbon/human/H = target + var/obj/item/organ/external/head/head = H.get_organ(user.zone_sel.selecting) + if(!head) + return FALSE + if(head.status & ORGAN_ROBOT) + return FALSE + return TRUE + + +/datum/surgery_step/reshape_face + name = "reshape face" + allowed_tools = list(/obj/item/scalpel = 100, /obj/item/kitchen/knife = 50, /obj/item/wirecutters = 35) + time = 64 + +/datum/surgery_step/reshape_face/begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool, datum/surgery/surgery) + user.visible_message("[user] begins to alter [target]'s appearance.", "You begin to alter [target]'s appearance...") + +/datum/surgery_step/reshape_face/end_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool, datum/surgery/surgery) + var/obj/item/organ/external/head/head = target.get_organ(target_zone) + var/species_names = target.get_species() + if(head.disfigured) + head.disfigured = FALSE + user.visible_message("[user] successfully restores [target]'s appearance!", "You successfully restore [target]'s appearance.") + else + var/list/names = list() + if(!isabductor(user)) + for(var/i in 1 to 10) + names += random_name(target.gender, species_names) + else + for(var/_i in 1 to 9) + names += "Subject [target.gender == MALE ? "i" : "o"]-[pick("a", "b", "c", "d", "e")]-[rand(10000, 99999)]" + names += random_name(target.gender, species_names) //give one normal name in case they want to do regular plastic surgery + var/chosen_name = input(user, "Choose a new name to assign.", "Plastic Surgery") as null|anything in names + if(!chosen_name) + return + var/oldname = target.real_name + target.real_name = chosen_name + var/newname = target.real_name //something about how the code handles names required that I use this instead of target.real_name + user.visible_message("[user] alters [oldname]'s appearance completely, [target.p_they()] [target.p_are()] now [newname]!", "You alter [oldname]'s appearance completely, [target.p_they()] [target.p_are()] now [newname].") + target.sec_hud_set_ID() + return TRUE + + +/datum/surgery_step/reshape_face/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool, datum/surgery/surgery) + var/obj/item/organ/external/head/head = target.get_organ(target_zone) + user.visible_message(" [user]'s hand slips, tearing skin on [target]'s face with [tool]!", \ + " Your hand slips, tearing skin on [target]'s face with [tool]!") + target.apply_damage(10, BRUTE, head, sharp = TRUE) + return FALSE \ No newline at end of file diff --git a/code/modules/surgery/robotics.dm b/code/modules/surgery/robotics.dm index 58b570eb5e3..ed82328c47d 100644 --- a/code/modules/surgery/robotics.dm +++ b/code/modules/surgery/robotics.dm @@ -248,10 +248,7 @@ user.visible_message(" [user] finishes patching damage to [target]'s [affected.name] with \the [tool].", \ " You finish patching damage to [target]'s [affected.name] with \the [tool].") affected.heal_damage(rand(30,50),0,1,1) - if(affected.disfigured) - affected.disfigured = 0 - affected.update_icon() - target.regenerate_icons() + affected.disfigured = FALSE if("burn") user.visible_message(" [user] finishes splicing cable into [target]'s [affected.name].", \ " You finishes splicing new cable into [target]'s [affected.name].") @@ -325,7 +322,7 @@ user.visible_message("[user] begins reattaching [target]'s [tool].", \ "You start reattaching [target]'s [tool].") - target.custom_pain("Someone's rooting around in your [affected.name]!",1) + target.custom_pain("Someone's rooting around in your [affected.name]!") else if(istype(tool,/obj/item/mmi)) current_type = "install" @@ -386,7 +383,7 @@ user.visible_message("[user] starts to decouple [target]'s [I] with \the [tool].", \ "You start to decouple [target]'s [I] with \the [tool]." ) - target.custom_pain("The pain in your [affected.name] is living hell!",1) + target.custom_pain("The pain in your [affected.name] is living hell!") else return -1 @@ -407,7 +404,7 @@ to_chat(user, "There are no damaged components in [affected].") return -1 - target.custom_pain("The pain in your [affected.name] is living hell!",1) + target.custom_pain("The pain in your [affected.name] is living hell!") else if(implement_type in implements_finish) current_type = "finish" @@ -522,7 +519,7 @@ user.visible_message("[user] starts to decouple [target]'s [affected.name] with \the [tool].", \ "You start to decouple [target]'s [affected.name] with \the [tool]." ) - target.custom_pain("Your [affected.amputation_point] is being ripped apart!",1) + target.custom_pain("Your [affected.amputation_point] is being ripped apart!") ..() /datum/surgery_step/robotics/external/amputate/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) diff --git a/config/example/dbconfig.txt b/config/example/dbconfig.txt index a962b4b685c..37768b61732 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 2 +DB_VERSION 3 ## Server the MySQL database can be found at. # Examples: localhost, 200.135.5.43, www.mysqldb.com, etc. diff --git a/html/changelog.html b/html/changelog.html index 464012c5cb9..dc33ff72343 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -56,6 +56,97 @@ -->
+

13 June 2018

+

Aurorablade updated:

+
    +
  • Fluff for Panzerskull
  • +
+

Fox McCloud updated:

+
    +
  • Medibots now actually talk, like beepsky
  • +
  • Adds Plastic surgery; fix someone's face or give them a new identity!
  • +
  • Having more than 50 cloneloss will render you "Unknown"
  • +
  • head disfigurement requires you to have more than 50 combined brute and burn damage, rather than tracking it separately
  • +
  • Fixes Cryoxadone and Rezadone not fixing disfigurement, Fixes fluorosulfuric acid not causing disfigurement at proper thresholds
  • +
  • Fixes syndicate medibot not being constructable from tactical medkits
  • +
  • Syndicate medibot and the mysterious medibot are better at treating brute and burn damage
  • +
+

MINIMAN10000 updated:

+
    +
  • Airlock electronics lock
  • +
  • Airlock electronics close button
  • +
+

Piccione updated:

+
    +
  • Added Magboots to the Paramedic's EVA gear closet
  • +
+

Tayyyyyyy updated:

+
    +
  • Shadowling dethrall has been shortened to scalpel, hemostat, retractor, shine light, cautery
  • +
+ +

11 June 2018

+

FalseIncarnate updated:

+
    +
  • Food on utensils now properly inherits the name of the source dish.
  • +
  • Joined Souls rune can now properly can summon restrained targets with 3+ invokers.
  • +
+ +

09 June 2018

+

Fox McCloud updated:

+
    +
  • Fixes holobarrier icons being missing
  • +
+ +

08 June 2018

+

Alffd updated:

+
    +
  • Adds an automated emergency var on air alarms for mappers
  • +
+

Anasari updated:

+
    +
  • Fixes admin log for spray displaying (0,0,0) all the time.
  • +
+

Desolate updated:

+
    +
  • ED-209 code corrected to work properly. Floorbot code corrected to work properly.
  • +
+

and Dumbdumb updated:

+
    +
  • Unathi and Vox Sec Hardsuit update
  • +
+ +

05 June 2018

+

Kyep updated:

+
    +
  • The Terror Spider away mission now has spiders colonizing the west side of the map. Only the gateway room is safe.
  • +
+ +

04 June 2018

+

Fox McCloud updated:

+
    +
  • Hulk mutation no longer works at range (ie: punching/breaking windows/walls at range)
  • +
  • You must be on harm intent to damage things if you have hulk
  • +
  • Having hulk allows you to punch and damage just about anything
  • +
+

uraniummeltdown updated:

+
    +
  • You can smelt titanium and glass together to form titanium glass for building shuttle windows
  • +
  • You can smelt titanium, plasma and glass together to form plastitanium glass for building plastitanium windows
  • +
  • Fulltile windows now smooth, windows crack as they get damaged and can be repaired with help intent welder
  • +
  • Windows have deconstruction hints and show whether they can be rotated or not
  • +
  • Plasma glass no longer gets auto-colored
  • +
  • RCDs can deconstruct airlocks again, they have no force now though
  • +
  • Wielded fireaxe does a lot of damage to windows and grilles instead of just deleting them
  • +
  • Glass stacks now use stack recipes instead of a custom menu
  • +
+ +

31 May 2018

+

FalseIncarnate updated:

+
    +
  • The singulo no longer feeds on attention.
  • +
+

26 May 2018

Birdtalon updated:

    @@ -64,7 +155,7 @@

Citinited updated:

    -
  • Hopefully fixes all issues with disposals sending you to disposals.
  • +
  • Hopefully fixes all issues with disposals sending you to nullspace.

Fox McCloud updated:

    diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml index 04b66ec89a7..9304a5f6086 100644 --- a/html/changelogs/.all_changelog.yml +++ b/html/changelogs/.all_changelog.yml @@ -6426,7 +6426,7 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py. for charger models. - bugfix: laser tag gun projectiles now play appropriate sound when striking. Citinited: - - bugfix: Hopefully fixes all issues with disposals sending you to disposals. + - bugfix: Hopefully fixes all issues with disposals sending you to nullspace. Fox McCloud: - bugfix: Fixes not being able to propel yourself through space by farting if you possessed both superfart and toxic farts @@ -6437,3 +6437,70 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py. - bugfix: Newscasters properly check for feed channel creation and wanted issue creation - bugfix: ERT should deploy properly without admins now. +2018-05-31: + FalseIncarnate: + - bugfix: The singulo no longer feeds on attention. +2018-06-04: + Fox McCloud: + - bugfix: 'Hulk mutation no longer works at range (ie: punching/breaking windows/walls + at range)' + - tweak: You must be on harm intent to damage things if you have hulk + - rscadd: Having hulk allows you to punch and damage just about anything + uraniummeltdown: + - rscadd: You can smelt titanium and glass together to form titanium glass for building + shuttle windows + - rscadd: You can smelt titanium, plasma and glass together to form plastitanium + glass for building plastitanium windows + - rscadd: Fulltile windows now smooth, windows crack as they get damaged and can + be repaired with help intent welder + - rscadd: Windows have deconstruction hints and show whether they can be rotated + or not + - bugfix: Plasma glass no longer gets auto-colored + - bugfix: RCDs can deconstruct airlocks again, they have no force now though + - tweak: Wielded fireaxe does a lot of damage to windows and grilles instead of + just deleting them + - tweak: Glass stacks now use stack recipes instead of a custom menu +2018-06-05: + Kyep: + - bugfix: The Terror Spider away mission now has spiders colonizing the west side + of the map. Only the gateway room is safe. +2018-06-08: + Alffd: + - rscadd: Adds an automated emergency var on air alarms for mappers + Anasari: + - bugfix: Fixes admin log for spray displaying (0,0,0) all the time. + Desolate: + - bugfix: ED-209 code corrected to work properly. Floorbot code corrected to work + properly. + and Dumbdumb: + - rscadd: Unathi and Vox Sec Hardsuit update +2018-06-09: + Fox McCloud: + - bugfix: Fixes holobarrier icons being missing +2018-06-11: + FalseIncarnate: + - bugfix: Food on utensils now properly inherits the name of the source dish. + - bugfix: Joined Souls rune can now properly can summon restrained targets with + 3+ invokers. +2018-06-13: + Aurorablade: + - rscadd: Fluff for Panzerskull + Fox McCloud: + - rscadd: Medibots now actually talk, like beepsky + - rscadd: Adds Plastic surgery; fix someone's face or give them a new identity! + - tweak: Having more than 50 cloneloss will render you "Unknown" + - tweak: head disfigurement requires you to have more than 50 combined brute and + burn damage, rather than tracking it separately + - bugfix: Fixes Cryoxadone and Rezadone not fixing disfigurement, Fixes fluorosulfuric + acid not causing disfigurement at proper thresholds + - bugfix: Fixes syndicate medibot not being constructable from tactical medkits + - tweak: Syndicate medibot and the mysterious medibot are better at treating brute + and burn damage + MINIMAN10000: + - rscdel: Airlock electronics lock + - bugfix: Airlock electronics close button + Piccione: + - rscadd: Added Magboots to the Paramedic's EVA gear closet + Tayyyyyyy: + - tweak: Shadowling dethrall has been shortened to scalpel, hemostat, retractor, + shine light, cautery diff --git a/html/changelogs/AutoChangeLog-pr-9066.yml b/html/changelogs/AutoChangeLog-pr-9066.yml new file mode 100644 index 00000000000..82fb8ff76dc --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9066.yml @@ -0,0 +1,4 @@ +author: "Fox McCloud" +delete-after: True +changes: + - tweak: "Toxin damage is stealthier and will no longer cause stinging spam message" diff --git a/icons/effects/96x96.dmi b/icons/effects/96x96.dmi index 2fdc968ebd6..a5195cc0167 100644 Binary files a/icons/effects/96x96.dmi and b/icons/effects/96x96.dmi differ diff --git a/icons/effects/effects.dmi b/icons/effects/effects.dmi index fa6f26fefe6..060d8b77a27 100644 Binary files a/icons/effects/effects.dmi and b/icons/effects/effects.dmi differ diff --git a/icons/mob/species/unathi/helmet.dmi b/icons/mob/species/unathi/helmet.dmi index f969705ec83..14b099f3f45 100644 Binary files a/icons/mob/species/unathi/helmet.dmi and b/icons/mob/species/unathi/helmet.dmi differ diff --git a/icons/mob/species/unathi/suit.dmi b/icons/mob/species/unathi/suit.dmi index ebbfa5f9c73..1d0bcf81f27 100644 Binary files a/icons/mob/species/unathi/suit.dmi and b/icons/mob/species/unathi/suit.dmi differ diff --git a/icons/mob/species/vox/helmet.dmi b/icons/mob/species/vox/helmet.dmi index c9227ce2119..bf06b4d2057 100644 Binary files a/icons/mob/species/vox/helmet.dmi and b/icons/mob/species/vox/helmet.dmi differ diff --git a/icons/mob/species/vox/suit.dmi b/icons/mob/species/vox/suit.dmi index ca8289a3ccb..a3d89179bf6 100644 Binary files a/icons/mob/species/vox/suit.dmi and b/icons/mob/species/vox/suit.dmi differ diff --git a/icons/mob/ties.dmi b/icons/mob/ties.dmi index b3f92a3b57f..db92d8c21a6 100644 Binary files a/icons/mob/ties.dmi and b/icons/mob/ties.dmi differ diff --git a/icons/obj/ammo.dmi b/icons/obj/ammo.dmi index a63ff4f5daa..d1aa0e9805a 100644 Binary files a/icons/obj/ammo.dmi and b/icons/obj/ammo.dmi differ diff --git a/icons/obj/clothing/species/unathi/hats.dmi b/icons/obj/clothing/species/unathi/hats.dmi index be2fb4f62aa..1ee46571f66 100644 Binary files a/icons/obj/clothing/species/unathi/hats.dmi and b/icons/obj/clothing/species/unathi/hats.dmi differ diff --git a/icons/obj/clothing/species/unathi/suits.dmi b/icons/obj/clothing/species/unathi/suits.dmi index 34c3ea75105..30b590cc7ed 100644 Binary files a/icons/obj/clothing/species/unathi/suits.dmi and b/icons/obj/clothing/species/unathi/suits.dmi differ diff --git a/icons/obj/custom_items.dmi b/icons/obj/custom_items.dmi index 940f2ba25da..8296c4ceb7d 100644 Binary files a/icons/obj/custom_items.dmi and b/icons/obj/custom_items.dmi differ diff --git a/icons/obj/doors/windoor.dmi b/icons/obj/doors/windoor.dmi index 8104686b483..9bf105faaf6 100644 Binary files a/icons/obj/doors/windoor.dmi and b/icons/obj/doors/windoor.dmi differ diff --git a/icons/obj/guns/projectile.dmi b/icons/obj/guns/projectile.dmi index 22dc1384904..288785052cd 100644 Binary files a/icons/obj/guns/projectile.dmi and b/icons/obj/guns/projectile.dmi differ diff --git a/icons/obj/items.dmi b/icons/obj/items.dmi index d828f2ee9de..5714fcf4c9f 100644 Binary files a/icons/obj/items.dmi and b/icons/obj/items.dmi differ diff --git a/icons/obj/smooth_structures/clockwork_window.dmi b/icons/obj/smooth_structures/clockwork_window.dmi new file mode 100644 index 00000000000..90309ac3d52 Binary files /dev/null and b/icons/obj/smooth_structures/clockwork_window.dmi differ diff --git a/icons/obj/smooth_structures/plasma_window.dmi b/icons/obj/smooth_structures/plasma_window.dmi new file mode 100644 index 00000000000..3d57d156f01 Binary files /dev/null and b/icons/obj/smooth_structures/plasma_window.dmi differ diff --git a/icons/obj/smooth_structures/plastitanium_window.dmi b/icons/obj/smooth_structures/plastitanium_window.dmi new file mode 100644 index 00000000000..82ac0306159 Binary files /dev/null and b/icons/obj/smooth_structures/plastitanium_window.dmi differ diff --git a/icons/obj/smooth_structures/pod_window.dmi b/icons/obj/smooth_structures/pod_window.dmi new file mode 100644 index 00000000000..0fe7501225c Binary files /dev/null and b/icons/obj/smooth_structures/pod_window.dmi differ diff --git a/icons/obj/smooth_structures/reinforced_window.dmi b/icons/obj/smooth_structures/reinforced_window.dmi index b5f24ebbd30..ed9a2a143e6 100644 Binary files a/icons/obj/smooth_structures/reinforced_window.dmi and b/icons/obj/smooth_structures/reinforced_window.dmi differ diff --git a/icons/obj/smooth_structures/rice_window.dmi b/icons/obj/smooth_structures/rice_window.dmi index e3a82935cf2..f5e7a6dd57a 100644 Binary files a/icons/obj/smooth_structures/rice_window.dmi and b/icons/obj/smooth_structures/rice_window.dmi differ diff --git a/icons/obj/smooth_structures/rplasma_window.dmi b/icons/obj/smooth_structures/rplasma_window.dmi new file mode 100644 index 00000000000..c64f42c7f5a Binary files /dev/null and b/icons/obj/smooth_structures/rplasma_window.dmi differ diff --git a/icons/obj/smooth_structures/shuttle_window.dmi b/icons/obj/smooth_structures/shuttle_window.dmi index 3db34cf1ba1..85924dc449b 100644 Binary files a/icons/obj/smooth_structures/shuttle_window.dmi and b/icons/obj/smooth_structures/shuttle_window.dmi differ diff --git a/icons/obj/smooth_structures/tinted_window.dmi b/icons/obj/smooth_structures/tinted_window.dmi index ab992353275..be9affafeea 100644 Binary files a/icons/obj/smooth_structures/tinted_window.dmi and b/icons/obj/smooth_structures/tinted_window.dmi differ diff --git a/icons/obj/smooth_structures/window.dmi b/icons/obj/smooth_structures/window.dmi index 0197f5b20a7..670713bcfe0 100644 Binary files a/icons/obj/smooth_structures/window.dmi and b/icons/obj/smooth_structures/window.dmi differ diff --git a/icons/obj/stationobjs.dmi b/icons/obj/stationobjs.dmi index 997642dcf29..d4b8e837db6 100755 Binary files a/icons/obj/stationobjs.dmi and b/icons/obj/stationobjs.dmi differ diff --git a/icons/obj/structures.dmi b/icons/obj/structures.dmi index 0b17038ade5..838503bbda1 100644 Binary files a/icons/obj/structures.dmi and b/icons/obj/structures.dmi differ diff --git a/paradise.dme b/paradise.dme index 62908577586..530eff9fc13 100644 --- a/paradise.dme +++ b/paradise.dme @@ -224,6 +224,7 @@ #include "code\datums\datum.dm" #include "code\datums\datumvars.dm" #include "code\datums\gas_mixture.dm" +#include "code\datums\holocall.dm" #include "code\datums\hud.dm" #include "code\datums\mind.dm" #include "code\datums\mixed.dm" @@ -630,7 +631,6 @@ #include "code\game\machinery\computer\computer.dm" #include "code\game\machinery\computer\crew.dm" #include "code\game\machinery\computer\HolodeckControl.dm" -#include "code\game\machinery\computer\hologram.dm" #include "code\game\machinery\computer\honkputer.dm" #include "code\game\machinery\computer\law.dm" #include "code\game\machinery\computer\medical.dm" @@ -960,7 +960,6 @@ #include "code\game\objects\structures\false_walls.dm" #include "code\game\objects\structures\flora.dm" #include "code\game\objects\structures\foodcart.dm" -#include "code\game\objects\structures\fullwindow.dm" #include "code\game\objects\structures\girders.dm" #include "code\game\objects\structures\grille.dm" #include "code\game\objects\structures\guillotine.dm" @@ -2106,6 +2105,7 @@ #include "code\modules\research\xenobiology\xenobio_camera.dm" #include "code\modules\research\xenobiology\xenobiology.dm" #include "code\modules\ruins\ruin_areas.dm" +#include "code\modules\scripting\__defines.dm" #include "code\modules\scripting\Errors.dm" #include "code\modules\scripting\Options.dm" #include "code\modules\scripting\AST\AST Nodes.dm" @@ -2156,7 +2156,6 @@ #include "code\modules\surgery\cavity_implant.dm" #include "code\modules\surgery\dental_implant.dm" #include "code\modules\surgery\encased.dm" -#include "code\modules\surgery\face.dm" #include "code\modules\surgery\generic.dm" #include "code\modules\surgery\helpers.dm" #include "code\modules\surgery\implant_removal.dm" @@ -2164,6 +2163,7 @@ #include "code\modules\surgery\limb_reattach.dm" #include "code\modules\surgery\organs_internal.dm" #include "code\modules\surgery\other.dm" +#include "code\modules\surgery\plastic_surgery.dm" #include "code\modules\surgery\remove_embedded_object.dm" #include "code\modules\surgery\rig_removal.dm" #include "code\modules\surgery\robotics.dm" diff --git a/sound/voice/mapple.ogg b/sound/voice/mapple.ogg new file mode 100644 index 00000000000..21e26742ca1 Binary files /dev/null and b/sound/voice/mapple.ogg differ diff --git a/sound/voice/mcatch.ogg b/sound/voice/mcatch.ogg new file mode 100644 index 00000000000..07b8aaab75c Binary files /dev/null and b/sound/voice/mcatch.ogg differ diff --git a/sound/voice/mcoming.ogg b/sound/voice/mcoming.ogg new file mode 100644 index 00000000000..d3eb9e467f4 Binary files /dev/null and b/sound/voice/mcoming.ogg differ diff --git a/sound/voice/mdelicious.ogg b/sound/voice/mdelicious.ogg new file mode 100644 index 00000000000..5158538580e Binary files /dev/null and b/sound/voice/mdelicious.ogg differ diff --git a/sound/voice/mfeelbetter.ogg b/sound/voice/mfeelbetter.ogg new file mode 100644 index 00000000000..fdbe57fd2e9 Binary files /dev/null and b/sound/voice/mfeelbetter.ogg differ diff --git a/sound/voice/mflies.ogg b/sound/voice/mflies.ogg new file mode 100644 index 00000000000..831281ebbee Binary files /dev/null and b/sound/voice/mflies.ogg differ diff --git a/sound/voice/mhelp.ogg b/sound/voice/mhelp.ogg new file mode 100644 index 00000000000..516d5db068d Binary files /dev/null and b/sound/voice/mhelp.ogg differ diff --git a/sound/voice/minjured.ogg b/sound/voice/minjured.ogg new file mode 100644 index 00000000000..0e968b3980c Binary files /dev/null and b/sound/voice/minjured.ogg differ diff --git a/sound/voice/minsult.ogg b/sound/voice/minsult.ogg new file mode 100644 index 00000000000..017292977a1 Binary files /dev/null and b/sound/voice/minsult.ogg differ diff --git a/sound/voice/mlive.ogg b/sound/voice/mlive.ogg new file mode 100644 index 00000000000..ceb0dec9a34 Binary files /dev/null and b/sound/voice/mlive.ogg differ diff --git a/sound/voice/mlost.ogg b/sound/voice/mlost.ogg new file mode 100644 index 00000000000..7b332ac346a Binary files /dev/null and b/sound/voice/mlost.ogg differ diff --git a/sound/voice/mno.ogg b/sound/voice/mno.ogg new file mode 100644 index 00000000000..030e43a0109 Binary files /dev/null and b/sound/voice/mno.ogg differ diff --git a/sound/voice/mpatchedup.ogg b/sound/voice/mpatchedup.ogg new file mode 100644 index 00000000000..1314f6ee471 Binary files /dev/null and b/sound/voice/mpatchedup.ogg differ diff --git a/sound/voice/mradar.ogg b/sound/voice/mradar.ogg new file mode 100644 index 00000000000..ad347a6d891 Binary files /dev/null and b/sound/voice/mradar.ogg differ diff --git a/sound/voice/msurgeon.ogg b/sound/voice/msurgeon.ogg new file mode 100644 index 00000000000..a300ee57ef6 Binary files /dev/null and b/sound/voice/msurgeon.ogg differ