diff --git a/_maps/map_files/cyberiad/cyberiad.dmm b/_maps/map_files/cyberiad/cyberiad.dmm index 4f5befd34ef..e8f41ed182a 100644 --- a/_maps/map_files/cyberiad/cyberiad.dmm +++ b/_maps/map_files/cyberiad/cyberiad.dmm @@ -459,7 +459,7 @@ "aiQ" = (/obj/effect/spawner/window/reinforced,/obj/structure/cable{icon_state = "0-4"; d2 = 4},/turf/simulated/floor/plating,/area/security/permabrig) "aiR" = (/obj/effect/spawner/window/reinforced,/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/security/permabrig) "aiS" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_security{name = "Prison Wing"; req_access_txt = "63"},/turf/simulated/floor/plasteel{icon_state = "red"; dir = 4},/area/security/permabrig) -"aiT" = (/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22; pixel_y = 0; tag = "icon-alarm0 (EAST)"},/obj/machinery/camera{c_tag = "Brig Armory"; dir = 4; network = list("SS13")},/obj/machinery/flasher/portable,/obj/effect/decal/warning_stripes/red/hollow,/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/security/armoury) +"aiT" = (/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22; pixel_y = 0},/obj/machinery/camera{c_tag = "Brig Armory"; dir = 4; network = list("SS13")},/obj/machinery/flasher/portable,/obj/effect/decal/warning_stripes/red/hollow,/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/security/armoury) "aiU" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/flasher/portable,/obj/effect/decal/warning_stripes/red/hollow,/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/security/armoury) "aiV" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plasteel,/area/security/armoury) "aiW" = (/obj/structure/rack,/obj/item/weapon/storage/box/seccarts{pixel_x = 3; pixel_y = 2},/obj/item/weapon/storage/box/handcuffs,/obj/item/weapon/storage/box/flashbangs{pixel_x = -2; pixel_y = -2},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/item/weapon/storage/box/handcuffs,/obj/effect/decal/warning_stripes/red/hollow,/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/security/armoury) @@ -562,7 +562,7 @@ "akP" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 8; external_pressure_bound = 100; on = 1; pressure_checks = 1},/turf/simulated/floor/plasteel{icon_state = "white"},/area/security/medbay) "akQ" = (/turf/simulated/floor/plasteel{icon_state = "white"},/area/security/medbay) "akR" = (/obj/structure/stool/bed/roller,/turf/simulated/floor/plasteel{icon_state = "white"},/area/security/medbay) -"akS" = (/obj/structure/table,/obj/machinery/light{dir = 8},/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22; pixel_y = 0; tag = "icon-alarm0 (EAST)"},/obj/item/weapon/storage/box/evidence,/turf/simulated/floor/plasteel{icon_state = "red"; dir = 8},/area/security/processing) +"akS" = (/obj/structure/table,/obj/machinery/light{dir = 8},/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22; pixel_y = 0},/obj/item/weapon/storage/box/evidence,/turf/simulated/floor/plasteel{icon_state = "red"; dir = 8},/area/security/processing) "akT" = (/obj/structure/stool/bed/chair{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plasteel,/area/security/processing) "akU" = (/obj/structure/table,/turf/simulated/floor/plasteel,/area/security/processing) "akV" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel,/area/security/processing) @@ -640,7 +640,7 @@ "amp" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/turf/simulated/floor/plasteel,/area/security/processing) "amq" = (/turf/simulated/floor/plasteel{icon_state = "red"},/area/security/processing) "amr" = (/turf/simulated/floor/plasteel{icon_state = "red"; dir = 6},/area/security/processing) -"ams" = (/obj/machinery/computer/security{network = list("SS13","Research Outpost","Mining Outpost")},/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22; pixel_y = 0; tag = "icon-alarm0 (EAST)"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/security/warden) +"ams" = (/obj/machinery/computer/security{network = list("SS13","Research Outpost","Mining Outpost")},/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22; pixel_y = 0},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/security/warden) "amt" = (/obj/structure/table,/obj/item/weapon/folder/red,/obj/item/weapon/crowbar,/obj/item/device/radio,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/security/warden) "amu" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8; initialize_directions = 11; level = 1},/turf/simulated/floor/plasteel,/area/security/armoury) "amv" = (/obj/machinery/computer/prisoner,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/security/warden) @@ -1026,7 +1026,7 @@ "atL" = (/obj/structure/stool/bed/chair/wood/wings{tag = "icon-wooden_chair_wings (EAST)"; icon_state = "wooden_chair_wings"; dir = 4},/turf/simulated/floor/wood,/area/maintenance/abandonedbar) "atM" = (/obj/structure/table/woodentable,/obj/item/trash/candle,/turf/simulated/floor/plating,/area/maintenance/abandonedbar) "atN" = (/obj/item/stack/rods,/turf/space,/area/space) -"atO" = (/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22; pixel_y = 0; tag = "icon-alarm0 (EAST)"},/turf/simulated/floor/plasteel{icon_state = "red"; dir = 8},/area/security/prisonershuttle) +"atO" = (/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22; pixel_y = 0},/turf/simulated/floor/plasteel{icon_state = "red"; dir = 8},/area/security/prisonershuttle) "atP" = (/obj/structure/closet/secure_closet/brig{id = "Cell 5"; name = "Cell 5 Locker"},/obj/machinery/camera{c_tag = "Brig Cell 5"; dir = 2; network = list("SS13")},/turf/simulated/floor/plasteel{icon_state = "red"; dir = 8},/area/security/prison/cell_block/B) "atQ" = (/obj/structure/closet/secure_closet/brig{id = "Cell 4"; name = "Cell 4 Locker"},/obj/machinery/camera{c_tag = "Brig Cell 4"; dir = 2; network = list("SS13")},/turf/simulated/floor/plasteel{icon_state = "red"; dir = 8},/area/security/prison/cell_block/A) "atR" = (/obj/effect/spawner/window/reinforced,/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id_tag = "Secure Gate"; name = "Security Blast Door"; opacity = 0},/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating,/area/security/prison/cell_block/A) @@ -4131,7 +4131,7 @@ "bBw" = (/obj/structure/closet/firecloset,/obj/machinery/light{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel{dir = 8; icon_state = "warnwhite"; tag = "icon-warnwhite (NORTH)"},/area/medical/research{name = "Research Division"}) "bBx" = (/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/research{name = "Research Division"}) "bBy" = (/obj/machinery/shower{tag = "icon-shower (WEST)"; icon_state = "shower"; dir = 8},/turf/simulated/floor/plasteel{dir = 4; icon_state = "warnwhite"; tag = "icon-warnwhite (NORTH)"},/area/medical/research{name = "Research Division"}) -"bBz" = (/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22; pixel_y = 0; tag = "icon-alarm0 (EAST)"},/obj/machinery/r_n_d/destructive_analyzer,/turf/simulated/floor/plasteel{dir = 9; icon_state = "warning"},/area/toxins/lab) +"bBz" = (/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22; pixel_y = 0},/obj/machinery/r_n_d/destructive_analyzer,/turf/simulated/floor/plasteel{dir = 9; icon_state = "warning"},/area/toxins/lab) "bBA" = (/turf/simulated/floor/plasteel{dir = 1; icon_state = "warning"},/area/toxins/lab) "bBB" = (/obj/machinery/r_n_d/protolathe,/turf/simulated/floor/plasteel{dir = 5; icon_state = "warning"},/area/toxins/lab) "bBC" = (/obj/machinery/hologram/holopad,/turf/simulated/floor/plasteel{icon_state = "white"},/area/toxins/lab) @@ -5888,7 +5888,7 @@ "cjl" = (/turf/simulated/floor/plasteel{tag = "icon-whiteblue"; icon_state = "whiteblue"},/area/medical/medbay2) "cjm" = (/obj/structure/sign/biohazard,/turf/simulated/wall,/area/medical/virology) "cjn" = (/turf/simulated/floor/plasteel{dir = 2; icon_state = "whitebluecorner"; tag = "icon-whitebluecorner"},/area/medical/medbay2) -"cjo" = (/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22; pixel_y = 0; tag = "icon-alarm0 (EAST)"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/sink{icon_state = "sink"; dir = 8; pixel_x = -12; pixel_y = 2},/turf/simulated/floor/plasteel{dir = 9; icon_state = "warnwhite"; tag = "icon-warnwhite (NORTHEAST)"},/area/medical/virology) +"cjo" = (/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/sink{icon_state = "sink"; dir = 8; pixel_x = -12; pixel_y = 2},/turf/simulated/floor/plasteel{dir = 9; icon_state = "warnwhite"; tag = "icon-warnwhite (NORTHEAST)"},/area/medical/virology) "cjp" = (/turf/simulated/wall/r_wall,/area/medical/patient_a) "cjq" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/wall/r_wall,/area/medical/biostorage) "cjr" = (/obj/structure/extinguisher_cabinet,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/wall/r_wall,/area/medical/biostorage) @@ -7233,7 +7233,7 @@ "cJe" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plasteel,/area/engine/engineering) "cJf" = (/obj/effect/spawner/window/reinforced,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/engine/hardsuitstorage) "cJg" = (/obj/effect/spawner/window/reinforced,/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plating,/area/engine/hardsuitstorage) -"cJh" = (/obj/structure/sink{icon_state = "sink"; dir = 8; pixel_x = -12; pixel_y = 2},/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22; pixel_y = 0; tag = "icon-alarm0 (EAST)"},/turf/simulated/floor/plasteel{tag = "icon-whitegreen (WEST)"; icon_state = "whitegreen"; dir = 8},/area/medical/virology) +"cJh" = (/obj/structure/sink{icon_state = "sink"; dir = 8; pixel_x = -12; pixel_y = 2},/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22; pixel_y = 0},/turf/simulated/floor/plasteel{tag = "icon-whitegreen (WEST)"; icon_state = "whitegreen"; dir = 8},/area/medical/virology) "cJi" = (/obj/machinery/camera{c_tag = "Engineering Chief Engineer's Office"; dir = 4; network = list("SS13")},/obj/item/device/radio/intercom{name = "station intercom (General)"; pixel_x = -28; pixel_y = 0},/obj/machinery/disposal,/obj/structure/disposalpipe/trunk,/obj/machinery/firealarm{dir = 1; pixel_y = -24},/turf/simulated/floor/plasteel{dir = 8; icon_state = "neutralfull"},/area/engine/chiefs_office) "cJj" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel{dir = 8; icon_state = "neutralfull"},/area/engine/chiefs_office) "cJk" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/obj/structure/stool/bed/chair{dir = 1},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/turf/simulated/floor/plasteel{dir = 8; icon_state = "neutralfull"},/area/engine/chiefs_office) @@ -8973,4 +8973,3 @@ bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbi bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik "} - diff --git a/_maps/map_files/cyberiad/z2.dmm b/_maps/map_files/cyberiad/z2.dmm index f92570d1ce3..b304b87d7c0 100644 --- a/_maps/map_files/cyberiad/z2.dmm +++ b/_maps/map_files/cyberiad/z2.dmm @@ -152,6 +152,7 @@ "cV" = (/obj/effect/decal/cleanable/cobweb2,/turf/unsimulated/floor{name = "plating"},/area/prison/solitary) "cW" = (/obj/structure/stool/bed,/turf/unsimulated/floor{icon_state = "floorscorched2"},/area/prison/solitary) "cX" = (/obj/effect/decal/cleanable/blood,/turf/unsimulated/floor{name = "plating"},/area/prison/solitary) +"cY" = (/obj/structure/closet/secure_closet/guncabinet,/obj/item/ammo_box/shotgun/buck,/obj/item/ammo_box/shotgun/buck,/obj/item/ammo_box/shotgun/buck,/obj/item/weapon/gun/projectile/shotgun/automatic/combat,/obj/item/weapon/gun/projectile/shotgun/automatic/combat,/obj/item/weapon/gun/projectile/shotgun/automatic/combat,/turf/simulated/floor/engine,/area/shuttle/gamma/space) "db" = (/turf/simulated/floor/holofloor{tag = "icon-carpet2-0 (EAST)"; icon_state = "carpet2-0"; dir = 4},/area/holodeck/source_theatre) "do" = (/obj/effect/landmark{name = "prisonwarp"},/turf/unsimulated/floor{name = "plating"},/area/prison/solitary) "dp" = (/turf/unsimulated/floor{icon_state = "floorgrime"},/area/prison/solitary) @@ -550,7 +551,6 @@ "rP" = (/obj/structure/table/reinforced,/obj/item/weapon/grenade/clusterbuster,/obj/machinery/ai_status_display{pixel_x = 0; pixel_y = 32},/turf/simulated/floor/engine,/area/shuttle/gamma/space) "rQ" = (/obj/structure/table/reinforced,/obj/item/weapon/grenade/chem_grenade/incendiary{name = "Incendiary Grenade"},/obj/machinery/light{dir = 1},/turf/simulated/floor/engine,/area/shuttle/gamma/space) "rR" = (/obj/structure/table/reinforced,/obj/item/weapon/kitchenknife/combat,/obj/item/weapon/kitchenknife/combat,/obj/item/weapon/kitchenknife/combat,/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = 32},/turf/simulated/floor/engine,/area/shuttle/gamma/space) -"rS" = (/obj/structure/closet/secure_closet/guncabinet,/obj/item/ammo_box/shotgun/buck,/obj/item/ammo_box/shotgun/buck,/obj/item/ammo_box/shotgun/buck,/obj/item/weapon/gun/projectile/shotgun/combat,/obj/item/weapon/gun/projectile/shotgun/combat,/obj/item/weapon/gun/projectile/shotgun/combat,/turf/simulated/floor/engine,/area/shuttle/gamma/space) "rT" = (/obj/structure/closet/secure_closet/guncabinet,/obj/machinery/camera/motion{c_tag = "Gamma Armory Entrance"; network = list("SS13")},/obj/item/ammo_box/magazine/m10mm,/obj/item/ammo_box/magazine/m10mm,/obj/item/ammo_box/magazine/m10mm,/obj/item/weapon/gun/projectile/automatic/pistol{name = "pistol"},/obj/item/weapon/gun/projectile/automatic/pistol{name = "pistol"},/obj/item/weapon/gun/projectile/automatic/pistol{name = "pistol"},/turf/simulated/floor/engine,/area/shuttle/gamma/space) "rU" = (/obj/structure/closet/secure_closet/guncabinet,/obj/item/weapon/gun/energy/gun/nuclear,/obj/item/weapon/gun/energy/gun/nuclear,/obj/item/weapon/gun/energy/gun/nuclear,/obj/machinery/light{dir = 1},/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = 32},/turf/simulated/floor/engine,/area/shuttle/gamma/space) "rV" = (/obj/structure/closet/secure_closet/guncabinet,/obj/item/weapon/gun/energy/sniperrifle,/obj/item/weapon/gun/energy/sniperrifle,/obj/item/weapon/gun/energy/sniperrifle,/turf/simulated/floor/engine,/area/shuttle/gamma/space) @@ -1297,7 +1297,7 @@ aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaqaqaqaqaqaqaqaqaq aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN aNaNaNaNaNaNaNaNaNaNaNaNbZbZbZbZbZaNaNaNaNaNaNaNaNaNaNaNaNaNaNaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN aNaNaNaNaNaNaNbZbZbZbZbZbZrPrQrRbZaNaNaNaNaNaNaNaNaNaNaNaNaNaNaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNaNaNaNaNaNaNbZrSrTrUrVrWrXrXrXbZaNaNaNaNaNaNaNaNaNaNaNaNaNaNaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNaNaNaNaNaNaNbZcYrTrUrVrWrXrXrXbZaNaNaNaNaNaNaNaNaNaNaNaNaNaNaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN aNaNaNaNaNaNaNbZrXrXrXrXrXrXrYrZbZaNaNaNaNaNaNaNaNaNaNaNaNaNaNaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN aNaNaNaNaNaNaNbZsasbsbsbscsdsesbbZaNaNaNaNaNaNaNaNaNaNaNaNaNaNaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN aNaNaNaNaNaNaNsfsgsgsgsgsashsisjbZaNaNaNaNaNaNaNaNaNaNaNaNaNaNaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN diff --git a/code/LINDA/LINDA_fire.dm b/code/LINDA/LINDA_fire.dm index 837c3795b03..f82cd83d3a6 100644 --- a/code/LINDA/LINDA_fire.dm +++ b/code/LINDA/LINDA_fire.dm @@ -118,7 +118,7 @@ perform_exposure() - if(location.wet) location.wet = 0 + if(location.wet) location.wet = TURF_DRY if(bypassing) icon_state = "3" diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm index ba730797ce0..0dca37a8a35 100644 --- a/code/__DEFINES/misc.dm +++ b/code/__DEFINES/misc.dm @@ -174,3 +174,9 @@ #define MANIFEST_ERROR_NAME 1 #define MANIFEST_ERROR_COUNT 2 #define MANIFEST_ERROR_ITEM 4 + +//Turf wet states +#define TURF_DRY 0 +#define TURF_WET_WATER 1 +#define TURF_WET_LUBE 2 +#define TURF_WET_ICE 3 \ No newline at end of file diff --git a/code/datums/supplypacks.dm b/code/datums/supplypacks.dm index a0aaadd6e51..1570dccdafa 100644 --- a/code/datums/supplypacks.dm +++ b/code/datums/supplypacks.dm @@ -301,9 +301,9 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine /datum/supply_packs/security/armory/ballistic name = "Combat Shotguns Crate" - contains = list(/obj/item/weapon/gun/projectile/shotgun/combat, - /obj/item/weapon/gun/projectile/shotgun/combat, - /obj/item/weapon/gun/projectile/shotgun/combat, + contains = list(/obj/item/weapon/gun/projectile/shotgun/automatic/combat, + /obj/item/weapon/gun/projectile/shotgun/automatic/combat, + /obj/item/weapon/gun/projectile/shotgun/automatic/combat, /obj/item/weapon/storage/belt/bandolier, /obj/item/weapon/storage/belt/bandolier, /obj/item/weapon/storage/belt/bandolier) @@ -332,6 +332,22 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine containername = "incendiary weapons crate" access = access_heads +/datum/supply_packs/security/armory/wt550 + name = "WT-550 Auto Rifle Crate" + contains = list(/obj/item/weapon/gun/projectile/automatic/wt550, + /obj/item/weapon/gun/projectile/automatic/wt550) + cost = 35 + containername = "auto rifle crate" + +/datum/supply_packs/security/armory/wt550ammo + name = "WT-550 Rifle Ammo Crate" + contains = list(/obj/item/ammo_box/magazine/wt550m9, + /obj/item/ammo_box/magazine/wt550m9, + /obj/item/ammo_box/magazine/wt550m9, + /obj/item/ammo_box/magazine/wt550m9,) + cost = 30 + containername = "auto rifle ammo crate" + /////// Implants & etc /datum/supply_packs/security/armory/loyalty @@ -1233,6 +1249,12 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine cost = 10 containername = "replacement lights crate" +/datum/supply_packs/misc/noslipfloor + name = "High-traction Floor Tiles" + contains = list(/obj/item/stack/tile/noslip/loaded) + cost = 20 + containername = "high-traction floor tiles" + ///////////// Costumes /datum/supply_packs/misc/costume diff --git a/code/game/gamemodes/wizard/rightandwrong.dm b/code/game/gamemodes/wizard/rightandwrong.dm index a417c839a7e..d0c6f059f26 100644 --- a/code/game/gamemodes/wizard/rightandwrong.dm +++ b/code/game/gamemodes/wizard/rightandwrong.dm @@ -45,7 +45,7 @@ if("shotgun") new /obj/item/weapon/gun/projectile/shotgun/(get_turf(H)) if("combatshotgun") - new /obj/item/weapon/gun/projectile/shotgun/combat(get_turf(H)) + new /obj/item/weapon/gun/projectile/shotgun/automatic/combat(get_turf(H)) if("bulldog") new /obj/item/weapon/gun/projectile/automatic/shotgun/bulldog(get_turf(H)) if("arg") diff --git a/code/game/machinery/computer/arcade.dm b/code/game/machinery/computer/arcade.dm index 17ec358a4a8..14fcee521f8 100644 --- a/code/game/machinery/computer/arcade.dm +++ b/code/game/machinery/computer/arcade.dm @@ -39,6 +39,7 @@ /obj/item/toy/toy_xeno = 2, /obj/random/figure = 16, /obj/random/plushie = 7, + /obj/item/stack/tile/fakespace/loaded = 2, ) /obj/machinery/computer/arcade/power_change() diff --git a/code/game/machinery/constructable_frame.dm b/code/game/machinery/constructable_frame.dm index ba75e86b005..f4c6cc90c57 100644 --- a/code/game/machinery/constructable_frame.dm +++ b/code/game/machinery/constructable_frame.dm @@ -466,6 +466,16 @@ to destroy them and players will be able to make replacements. /obj/item/weapon/stock_parts/console_screen = 1, /obj/item/weapon/stock_parts/cell = 1) +/obj/item/weapon/circuitboard/chem_master + name = "circuit board (Chem Master 2999)" + build_path = /obj/machinery/chem_master/constructable + board_type = "machine" + origin_tech = "materials=2;programming=2;biotech=1" + req_components = list( + /obj/item/weapon/reagent_containers/glass/beaker = 2, + /obj/item/weapon/stock_parts/manipulator = 1, + /obj/item/weapon/stock_parts/console_screen = 1) + /obj/item/weapon/circuitboard/chem_heater name = "circuit board (Chemical Heater)" build_path = /obj/machinery/chem_heater diff --git a/code/game/machinery/vending.dm b/code/game/machinery/vending.dm index 0a87b6c61fd..0a1e3a1c1b5 100644 --- a/code/game/machinery/vending.dm +++ b/code/game/machinery/vending.dm @@ -853,7 +853,7 @@ vend_reply = "Remember the name: Liberation Station!" products = list(/obj/item/weapon/gun/projectile/automatic/pistol/deagle/gold = 2,/obj/item/weapon/gun/projectile/automatic/pistol/deagle/camo = 2, /obj/item/weapon/gun/projectile/automatic/pistol/m2411 = 2,/obj/item/weapon/gun/projectile/automatic/proto = 2, - /obj/item/weapon/gun/projectile/shotgun/combat = 2,/obj/item/weapon/gun/projectile/automatic/gyropistol = 1, + /obj/item/weapon/gun/projectile/shotgun/automatic/combat = 2,/obj/item/weapon/gun/projectile/automatic/gyropistol = 1, /obj/item/weapon/gun/projectile/shotgun = 2,/obj/item/weapon/gun/projectile/automatic/ar = 2) premium = list(/obj/item/ammo_box/magazine/smgm9mm = 2,/obj/item/ammo_box/magazine/m50 = 4,/obj/item/ammo_box/magazine/m45 = 2,/obj/item/ammo_box/magazine/m75 = 2) contraband = list(/obj/item/clothing/under/patriotsuit = 1,/obj/item/weapon/bedsheet/patriot = 3) diff --git a/code/game/objects/effects/spawners/lootdrop.dm b/code/game/objects/effects/spawners/lootdrop.dm index 4301da8c5a2..a916172118a 100644 --- a/code/game/objects/effects/spawners/lootdrop.dm +++ b/code/game/objects/effects/spawners/lootdrop.dm @@ -24,7 +24,7 @@ loot = list( /obj/item/weapon/gun/projectile/automatic/pistol = 8, - /obj/item/weapon/gun/projectile/shotgun/combat = 5, + /obj/item/weapon/gun/projectile/shotgun/automatic/combat = 5, /obj/item/weapon/gun/projectile/revolver/mateba, /obj/item/weapon/gun/projectile/automatic/pistol/deagle ) diff --git a/code/game/objects/items/devices/PDA/PDA.dm b/code/game/objects/items/devices/PDA/PDA.dm index 85a664ad9fd..a9e94d6077b 100755 --- a/code/game/objects/items/devices/PDA/PDA.dm +++ b/code/game/objects/items/devices/PDA/PDA.dm @@ -955,7 +955,7 @@ var/global/list/obj/item/device/pda/PDAs = list() if(!silent) O.show_message(text("\icon[src] *[ttone]*")) /obj/item/device/pda/verb/verb_remove_id() - set category = null + set category = "Object" set name = "Remove id" set src in usr @@ -972,7 +972,7 @@ var/global/list/obj/item/device/pda/PDAs = list() /obj/item/device/pda/verb/verb_remove_pen() - set category = null + set category = "Object" set name = "Remove pen" set src in usr diff --git a/code/game/objects/items/devices/guitar.dm b/code/game/objects/items/devices/guitar.dm index 546989c3c6e..9a3b4dd6901 100644 --- a/code/game/objects/items/devices/guitar.dm +++ b/code/game/objects/items/devices/guitar.dm @@ -20,17 +20,19 @@ return ..() /obj/item/device/guitar/attack_self(mob/user as mob) - interact(user) + ui_interact(user) -/obj/item/device/guitar/interact(mob/user as mob) +/obj/item/device/guitar/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) if(!user) return if(!isliving(user) || user.stat || user.restrained() || user.lying) return - user.set_machine(src) - song.interact(user) + song.ui_interact(user, ui_key, ui, force_open) + +/obj/item/device/guitar/Topic(href, href_list) + song.Topic(href, href_list) /datum/table_recipe/guitar name = "Guitar" diff --git a/code/game/objects/items/devices/violin.dm b/code/game/objects/items/devices/violin.dm index 02038717aff..9c4d5e9ddb4 100644 --- a/code/game/objects/items/devices/violin.dm +++ b/code/game/objects/items/devices/violin.dm @@ -24,14 +24,16 @@ ..() /obj/item/device/violin/attack_self(mob/user as mob) - interact(user) + ui_interact(user) -/obj/item/device/violin/interact(mob/user as mob) +/obj/item/device/violin/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) if(!user) return if(!isliving(user) || user.stat || user.restrained() || user.lying) return - user.set_machine(src) - song.interact(user) + song.ui_interact(user, ui_key, ui, force_open) + +/obj/item/device/violin/Topic(href, href_list) + song.Topic(href, href_list) \ No newline at end of file diff --git a/code/game/objects/items/stacks/tiles/light.dm b/code/game/objects/items/stacks/tiles/light.dm deleted file mode 100644 index 3cf7bd35c68..00000000000 --- a/code/game/objects/items/stacks/tiles/light.dm +++ /dev/null @@ -1,48 +0,0 @@ -#define LIGHTFLOOR_ON 1 -#define LIGHTFLOOR_WHITE 2 -#define LIGHTFLOOR_RED 3 -#define LIGHTFLOOR_GREEN 4 -#define LIGHTFLOOR_YELLOW 5 -#define LIGHTFLOOR_BLUE 6 -#define LIGHTFLOOR_PURPLE 7 - -/obj/item/stack/tile/light - name = "light tiles" - gender = PLURAL - singular_name = "light floor tile" - desc = "A floor tile, made out off glass. Use a multitool on it to change its color." - icon_state = "tile_light blue" - force = 3 - throwforce = 5 - attack_verb = list("bashed", "battered", "bludgeoned", "thrashed", "smashed") - var/on = 1 - var/state = LIGHTFLOOR_ON - -/obj/item/stack/tile/light/proc/color_desc() - switch(state) - if(LIGHTFLOOR_ON) return "light blue" - if(LIGHTFLOOR_WHITE) return "white" - if(LIGHTFLOOR_RED) return "red" - if(LIGHTFLOOR_GREEN) return "green" - if(LIGHTFLOOR_YELLOW) return "yellow" - if(LIGHTFLOOR_BLUE) return "dark blue" - if(LIGHTFLOOR_PURPLE) return "purple" - else return "broken" - -/obj/item/stack/tile/light/attackby(var/obj/item/O as obj, var/mob/user as mob, params) - ..() - if(istype(O,/obj/item/weapon/crowbar)) - new/obj/item/stack/sheet/metal(user.loc) - amount-- - new/obj/item/stack/light_w(user.loc) - if(amount <= 0) - user.unEquip(src, 1) - del(src) - else if(istype(O,/obj/item/device/multitool)) - state++ - if(state>LIGHTFLOOR_PURPLE) state=LIGHTFLOOR_ON - icon_state="tile_"+color_desc() - user << "[src] is now "+color_desc() - - return ..() - \ No newline at end of file diff --git a/code/game/objects/items/stacks/tiles/tile_types.dm b/code/game/objects/items/stacks/tiles/tile_types.dm index 207a046446e..1aaa53457e2 100644 --- a/code/game/objects/items/stacks/tiles/tile_types.dm +++ b/code/game/objects/items/stacks/tiles/tile_types.dm @@ -3,6 +3,11 @@ * Grass * Wood * Carpet + * Plasteel + * Light + * Fakespace + * High-traction + \\ If you don't update the contains list, I'm going to shank you */ /obj/item/stack/tile name = "broken tile" @@ -70,4 +75,44 @@ throw_range = 7 flags = CONDUCT turf_type = /turf/simulated/floor/plasteel - mineralType = "metal" \ No newline at end of file + mineralType = "metal" + +/* + * Light + */ +/obj/item/stack/tile/light + name = "light tiles" + gender = PLURAL + singular_name = "light floor tile" + desc = "A floor tile, made out off glass. Use a multitool on it to change its color." + icon_state = "tile_light blue" + force = 3 + throwforce = 5 + attack_verb = list("bashed", "battered", "bludgeoned", "thrashed", "smashed") + turf_type = /turf/simulated/floor/light + +/* + * Fakespace + */ +/obj/item/stack/tile/fakespace + name = "astral carpet" + singular_name = "astral carpet" + desc = "A piece of carpet with a convincing star pattern." + icon_state = "tile_space" + turf_type = /turf/simulated/floor/fakespace + +/obj/item/stack/tile/fakespace/loaded + amount = 30 + +//High-traction +/obj/item/stack/tile/noslip + name = "high-traction floor tile" + singular_name = "high-traction floor tile" + desc = "A high-traction floor tile. It feels rubbery in your hand." + icon_state = "tile_noslip" + turf_type = /turf/simulated/floor/noslip + origin_tech = "materials=3" + +/obj/item/stack/tile/noslip/loaded + amount = 20 + diff --git a/code/game/objects/items/weapons/gift_wrappaper.dm b/code/game/objects/items/weapons/gift_wrappaper.dm index 194a69608b4..b92b9c593ba 100644 --- a/code/game/objects/items/weapons/gift_wrappaper.dm +++ b/code/game/objects/items/weapons/gift_wrappaper.dm @@ -116,6 +116,7 @@ /obj/item/clothing/under/syndicate/tacticool, /obj/item/weapon/storage/box/fakesyndiesuit, /obj/item/toy/crossbow/tommygun, + /obj/item/stack/tile/fakespace/loaded, ) if(!ispath(gift_type,/obj/item)) return diff --git a/code/game/objects/structures/crates_lockers/crates.dm b/code/game/objects/structures/crates_lockers/crates.dm index 7e37c7a8988..df48bf96d7c 100644 --- a/code/game/objects/structures/crates_lockers/crates.dm +++ b/code/game/objects/structures/crates_lockers/crates.dm @@ -234,6 +234,7 @@ var/emag = "securecrateemag" var/broken = 0 var/locked = 1 + health = 1000 /obj/structure/closet/crate/secure/update_icon() ..() diff --git a/code/game/objects/structures/janicart.dm b/code/game/objects/structures/janicart.dm index 9d8ed7ee3dc..d50ca6b08d0 100644 --- a/code/game/objects/structures/janicart.dm +++ b/code/game/objects/structures/janicart.dm @@ -80,7 +80,7 @@ handle_rotation() if(istype(src.loc, /turf/simulated)) var/turf/simulated/T = src.loc - if(T.wet == 2) //Lube! Fall off! + if(T.wet == TURF_WET_LUBE) //Lube! Fall off! playsound(src, 'sound/misc/slip.ogg', 50, 1, -3) buckled_mob.Stun(7) buckled_mob.Weaken(7) diff --git a/code/game/objects/structures/musician.dm b/code/game/objects/structures/musician.dm index b173ece5b0b..367208bbfe4 100644 --- a/code/game/objects/structures/musician.dm +++ b/code/game/objects/structures/musician.dm @@ -3,13 +3,12 @@ /datum/song var/name = "Untitled" var/list/lines = new() - var/tempo = 5 // delay between notes + var/tempo = 5 // delay between notes - var/playing = 0 // if we're playing - var/help = 0 // if help is open - var/edit = 1 // if we're in editing mode - var/repeat = 0 // number of times remaining to repeat - var/max_repeats = 10 // maximum times we can repeat + var/playing = 0 // if we're playing + var/help = 0 // if help is open + var/repeat = 0 // number of times remaining to repeat + var/max_repeat = 10 // maximum times we can repeat var/instrumentDir = "piano" // the folder with the sounds var/instrumentExt = "ogg" // the file extension @@ -63,9 +62,6 @@ continue M.playsound_local(source, soundfile, 100, falloff = 5) -/datum/song/proc/updateDialog(mob/user as mob) - instrumentObj.updateDialog() // assumes it's an object in world, override if otherwise - /datum/song/proc/shouldStopPlaying(mob/user) if(instrumentObj) //if(!user.canUseTopic(instrumentObj)) @@ -113,68 +109,31 @@ else sleep(tempo) repeat-- - if(repeat >= 0) // don't show the last -1 repeat - updateDialog(user) playing = 0 repeat = 0 - updateDialog(user) -/datum/song/proc/interact(mob/user as mob) - var/dat = "" +/datum/song/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) + var/data[0] - if(lines.len > 0) - dat += "

Playback

" - if(!playing) - dat += "Play Stop

" - dat += "Repeat Song: " - dat += repeat > 0 ? "--" : "--" - dat += " [repeat] times " - dat += repeat < max_repeats ? "++" : "++" - dat += "
" - else - dat += "Play Stop
" - dat += "Repeats left: [repeat]
" - if(!edit) - dat += "
Show Editor
" - else - dat += "

Editing

" - dat += "Hide Editor" - dat += " Start a New Song" - dat += " Import a Song

" - var/bpm = round(600 / tempo) - dat += "Tempo: - [bpm] BPM +

" - var/linecount = 0 - for(var/line in lines) - linecount += 1 - dat += "Line [linecount]: Edit X [line]
" - dat += "Add Line

" - if(help) - dat += "Hide Help
" - dat += {" - Lines are a series of chords, separated by commas (,), each with notes seperated by hyphens (-).
- Every note in a chord will play together, with chord timed by the tempo.
-
- Notes are played by the names of the note, and optionally, the accidental, and/or the octave number.
- By default, every note is natural and in octave 3. Defining otherwise is remembered for each note.
- Example: C,D,E,F,G,A,B will play a C major scale.
- After a note has an accidental placed, it will be remembered: C,C4,C,C3 is C3,C4,C4,C3
- Chords can be played simply by seperating each note with a hyphon: A-C#,Cn-E,E-G#,Gn-B
- A pause may be denoted by an empty chord: C,E,,C,G
- To make a chord be a different time, end it with /x, where the chord length will be length
- defined by tempo / x: C,G/2,E/4
- Combined, an example is: E-E4/4,F#/2,G#/8,B/8,E3-E4/4 -
- Lines may be up to 50 characters.
- A song may only contain up to 50 lines.
- "} - else - dat += "Show Help
" + data["lines"] = lines + data["tempo"] = tempo - var/datum/browser/popup = new(user, "instrument", instrumentObj.name, 700, 500) - popup.set_content(dat) - popup.set_title_image(user.browse_rsc_icon(instrumentObj.icon, instrumentObj.icon_state)) - popup.open() + data["playing"] = playing + data["help"] = help + data["repeat"] = repeat + data["maxRepeat"] = max_repeat + data["minTempo"] = world.tick_lag + data["maxTempo"] = 600 + if(!instrumentObj) + return + + ui = nanomanager.try_update_ui(user, instrumentObj, ui_key, ui, data, force_open) + if (!ui) + ui = new(user, instrumentObj, ui_key, "song.tmpl", instrumentObj.name, 700, 500) + ui.set_initial_data(data) + ui.open() + ui.set_auto_update(1) /datum/song/Topic(href, href_list) if(!in_range(instrumentObj, usr) || (issilicon(usr) && instrumentObj.loc != usr) || !isliving(usr) || !usr.canmove || usr.restrained()) @@ -185,14 +144,16 @@ instrumentObj.add_fingerprint(usr) if(href_list["newsong"]) + playing = 0 lines = new() tempo = sanitize_tempo(5) // default 120 BPM name = "" else if(href_list["import"]) + playing = 0 var/t = "" do - t = html_encode(input(usr, "Please paste the entire song, formatted:", text("[]", name), t) as message) + t = html_encode(input(usr, "Please paste the entire song, formatted:", text("[]", name), t) as message) if(!in_range(instrumentObj, usr)) return @@ -220,13 +181,9 @@ lines.Remove(l) else linenum++ - updateDialog(usr) // make sure updates when complete else if(href_list["help"]) - help = text2num(href_list["help"]) - 1 - - else if(href_list["edit"]) - edit = text2num(href_list["edit"]) - 1 + help = !help if(href_list["repeat"]) //Changing this from a toggle to a number of repeats to avoid infinite loops. if(playing) @@ -234,18 +191,24 @@ repeat += round(text2num(href_list["repeat"])) if(repeat < 0) repeat = 0 - if(repeat > max_repeats) - repeat = max_repeats + if(repeat > max_repeat) + repeat = max_repeat else if(href_list["tempo"]) - tempo = sanitize_tempo(tempo + text2num(href_list["tempo"])) + tempo = sanitize_tempo(tempo + text2num(href_list["tempo"]) * world.tick_lag) else if(href_list["play"]) + if(playing) + return playing = 1 spawn() playsong(usr) - else if(href_list["newline"]) + else if(href_list["insertline"]) + var/num = round(text2num(href_list["insertline"])) + if(num < 1 || num > lines.len + 1) + return + var/newline = html_encode(input("Enter your line: ", instrumentObj.name) as text|null) if(!newline || !in_range(instrumentObj, usr)) return @@ -253,16 +216,17 @@ return if(lentext(newline) > 50) newline = copytext(newline, 1, 50) - lines.Add(newline) + + lines.Insert(num, newline) else if(href_list["deleteline"]) var/num = round(text2num(href_list["deleteline"])) if(num > lines.len || num < 1) return - lines.Cut(num, num+1) + lines.Cut(num, num + 1) else if(href_list["modifyline"]) - var/num = round(text2num(href_list["modifyline"]),1) + var/num = round(text2num(href_list["modifyline"])) var/content = html_encode(input("Enter your line: ", instrumentObj.name, lines[num]) as text|null) if(!content || !in_range(instrumentObj, usr)) return @@ -275,19 +239,12 @@ else if(href_list["stop"]) playing = 0 - updateDialog(usr) - return - /datum/song/proc/sanitize_tempo(new_tempo) - new_tempo = abs(new_tempo) return max(round(new_tempo, world.tick_lag), world.tick_lag) // subclass for handheld instruments, like violin /datum/song/handheld -/datum/song/handheld/updateDialog(mob/user as mob) - instrumentObj.interact(user) - /datum/song/handheld/shouldStopPlaying() if(instrumentObj) return !isliving(instrumentObj.loc) @@ -329,14 +286,16 @@ ..() /obj/structure/piano/attack_hand(mob/user as mob) - interact(user) + ui_interact(user) -/obj/structure/piano/interact(mob/user as mob) +/obj/structure/piano/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) if(!user || !anchored) return - user.set_machine(src) - song.interact(user) + song.ui_interact(user, ui_key, ui, force_open) + +/obj/structure/piano/Topic(href, href_list) + song.Topic(href, href_list) /obj/structure/piano/attackby(obj/item/O as obj, mob/user as mob, params) if (istype(O, /obj/item/weapon/wrench)) diff --git a/code/game/objects/structures/stool_bed_chair_nest/chairs.dm b/code/game/objects/structures/stool_bed_chair_nest/chairs.dm index 53abfd17216..2b5b1bd3ecb 100644 --- a/code/game/objects/structures/stool_bed_chair_nest/chairs.dm +++ b/code/game/objects/structures/stool_bed_chair_nest/chairs.dm @@ -49,7 +49,7 @@ /obj/structure/stool/bed/chair/verb/rotate() set name = "Rotate Chair" - set category = null + set category = "Object" set src in oview(1) if(config.ghost_interaction) diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm index 2e38ae54079..b49d491f1b4 100644 --- a/code/game/objects/structures/window.dm +++ b/code/game/objects/structures/window.dm @@ -273,33 +273,40 @@ var/global/wcCommon = pick(list("#379963", "#0d8395", "#58b5c3", "#49e46e", "#8f /obj/structure/window/verb/rotate() set name = "Rotate Window Counter-Clockwise" - set category = null + set category = "Object" set src in oview(1) + if(usr.stat || !usr.canmove || usr.restrained()) + return + if(anchored) - usr << "It is fastened to the floor therefore you can't rotate it!" + usr << "It is fastened to the floor therefore you can't rotate it!" return 0 dir = turn(dir, 90) // updateSilicate() air_update_turf(1) ini_dir = dir + add_fingerprint(usr) return - /obj/structure/window/verb/revrotate() set name = "Rotate Window Clockwise" - set category = null + set category = "Object" set src in oview(1) + if(usr.stat || !usr.canmove || usr.restrained()) + return + if(anchored) - usr << "It is fastened to the floor therefore you can't rotate it!" + usr << "It is fastened to the floor therefore you can't rotate it!" return 0 dir = turn(dir, 270) // updateSilicate() air_update_turf(1) ini_dir = dir + add_fingerprint(usr) return diff --git a/code/game/turfs/simulated.dm b/code/game/turfs/simulated.dm index ec4585ed46f..44650579eaa 100644 --- a/code/game/turfs/simulated.dm +++ b/code/game/turfs/simulated.dm @@ -17,24 +17,32 @@ /turf/simulated/proc/burn_tile() -/turf/simulated/proc/MakeSlippery(var/wet_setting = 1) // 1 = Water, 2 = Lube +/turf/simulated/proc/MakeSlippery(wet_setting = TURF_WET_WATER) // 1 = Water, 2 = Lube, 3 = Ice if(wet >= wet_setting) return wet = wet_setting - if(wet_setting == 1) + if(wet_setting != TURF_DRY) if(wet_overlay) overlays -= wet_overlay wet_overlay = null - wet_overlay = image('icons/effects/water.dmi', src, "wet_floor_static") + var/turf/simulated/floor/F = src + if(istype(F)) + wet_overlay = image('icons/effects/water.dmi', src, "wet_floor_static") + else + wet_overlay = image('icons/effects/water.dmi', src, "wet_static") overlays += wet_overlay spawn(rand(790, 820)) // Purely so for visual effect if(!istype(src, /turf/simulated)) //Because turfs don't get deleted, they change, adapt, transform, evolve and deform. they are one and they are all. return - if(wet > wet_setting) return - wet = 0 - if(wet_overlay) - overlays -= wet_overlay + MakeDry(wet_setting) + +/turf/simulated/proc/MakeDry(wet_setting = TURF_WET_WATER) + if(wet > wet_setting) + return + wet = TURF_DRY + if(wet_overlay) + overlays -= wet_overlay /turf/simulated/proc/AddTracks(var/typepath,var/bloodDNA,var/comingdir,var/goingdir,var/bloodcolor="#A10808") var/obj/effect/decal/cleanable/blood/tracks/tracks = locate(typepath) in src @@ -94,7 +102,7 @@ if (noslip) return // no slipping while sitting in a chair, plz switch (src.wet) - if(1) + if(TURF_WET_WATER) if ((M.m_intent == "run") && !(istype(M:shoes, /obj/item/clothing/shoes) && M.shoes.flags&NOSLIP)) M.stop_pulling() step(M, M.dir) @@ -107,7 +115,7 @@ return - if(2) //lube //can cause infinite loops - needs work + if(TURF_WET_LUBE) //lube //can cause infinite loops - needs work if(!M.buckled) M.stop_pulling() step(M, M.dir) @@ -120,7 +128,7 @@ playsound(src, 'sound/misc/slip.ogg', 50, 1, -3) M.Weaken(7) - if(3) // Ice + if(TURF_WET_ICE) // Ice if ((M.m_intent == "run") && !(istype(M:shoes, /obj/item/clothing/shoes) && M:shoes.flags&NOSLIP) && prob(30)) M.stop_pulling() step(M, M.dir) diff --git a/code/game/turfs/simulated/floor/fancy_floor.dm b/code/game/turfs/simulated/floor/fancy_floor.dm index 1523cf91f63..c1a74d07973 100644 --- a/code/game/turfs/simulated/floor/fancy_floor.dm +++ b/code/game/turfs/simulated/floor/fancy_floor.dm @@ -82,4 +82,14 @@ /turf/simulated/floor/carpet/burn_tile() burnt = 1 - update_icon() \ No newline at end of file + update_icon() + +/turf/simulated/floor/fakespace + icon = 'icons/turf/space.dmi' + icon_state = "0" + floor_tile = /obj/item/stack/tile/fakespace + broken_states = list("damaged") + +/turf/simulated/floor/fakespace/New() + ..() + icon_state = "[rand(0,25)]" \ No newline at end of file diff --git a/code/game/turfs/simulated/floor/light_floor.dm b/code/game/turfs/simulated/floor/light_floor.dm index 25a66394504..8149dae593a 100644 --- a/code/game/turfs/simulated/floor/light_floor.dm +++ b/code/game/turfs/simulated/floor/light_floor.dm @@ -1,9 +1,19 @@ +#define LIGHTFLOOR_ON 1 +#define LIGHTFLOOR_WHITE 2 +#define LIGHTFLOOR_RED 3 +#define LIGHTFLOOR_GREEN 4 +#define LIGHTFLOOR_YELLOW 5 +#define LIGHTFLOOR_BLUE 6 +#define LIGHTFLOOR_PURPLE 7 + /turf/simulated/floor/light name = "Light floor" light_range = 5 icon_state = "light_on" floor_tile = /obj/item/stack/tile/light broken_states = list("light_broken") + var/on = 1 + var/state = LIGHTFLOOR_ON /turf/simulated/floor/light/New() ..() @@ -11,58 +21,63 @@ /turf/simulated/floor/light/update_icon() ..() - if(istype(builtin_tile, /obj/item/stack/tile/light)) - var/obj/item/stack/tile/light/T = builtin_tile - if(T.on) - switch(T.state) - if(LIGHTFLOOR_ON) - icon_state = "light_on" - set_light(5,null,LIGHT_COLOR_LIGHTBLUE) - if(LIGHTFLOOR_WHITE) - icon_state = "light_on-w" - set_light(5,null,LIGHT_COLOR_WHITE) - if(LIGHTFLOOR_RED) - icon_state = "light_on-r" - set_light(5,null,LIGHT_COLOR_RED) - if(LIGHTFLOOR_GREEN) - icon_state = "light_on-g" - set_light(5,null,LIGHT_COLOR_PURE_GREEN) - if(LIGHTFLOOR_YELLOW) - icon_state = "light_on-y" - set_light(5,null,"#FFFF00") - if(LIGHTFLOOR_BLUE) - icon_state = "light_on-b" - set_light(5,null,LIGHT_COLOR_DARKBLUE) - if(LIGHTFLOOR_PURPLE) - icon_state = "light_on-p" - set_light(5,null,LIGHT_COLOR_PURPLE) - else - icon_state = "light_off" - set_light(0) - else - set_light(0) - icon_state = "light_off" + if(on) + switch(state) + if(LIGHTFLOOR_ON) + icon_state = "light_on" + set_light(5,null,LIGHT_COLOR_LIGHTBLUE) + if(LIGHTFLOOR_WHITE) + icon_state = "light_on-w" + set_light(5,null,LIGHT_COLOR_WHITE) + if(LIGHTFLOOR_RED) + icon_state = "light_on-r" + set_light(5,null,LIGHT_COLOR_RED) + if(LIGHTFLOOR_GREEN) + icon_state = "light_on-g" + set_light(5,null,LIGHT_COLOR_PURE_GREEN) + if(LIGHTFLOOR_YELLOW) + icon_state = "light_on-y" + set_light(5,null,"#FFFF00") + if(LIGHTFLOOR_BLUE) + icon_state = "light_on-b" + set_light(5,null,LIGHT_COLOR_DARKBLUE) + if(LIGHTFLOOR_PURPLE) + icon_state = "light_on-p" + set_light(5,null,LIGHT_COLOR_PURPLE) + else + icon_state = "light_off" + set_light(0) + else + set_light(0) + icon_state = "light_off" /turf/simulated/floor/light/ChangeTurf(turf/T) set_light(0) ..() /turf/simulated/floor/light/attack_hand(mob/user) - if(istype(builtin_tile, /obj/item/stack/tile/light)) - var/obj/item/stack/tile/light/T = builtin_tile - T.on = !T.on - update_icon() + on = !on + update_icon() /turf/simulated/floor/light/attackby(obj/item/C, mob/user, params) if(..()) return if(istype(C,/obj/item/weapon/light/bulb)) //only for light tiles if(istype(builtin_tile, /obj/item/stack/tile/light)) - var/obj/item/stack/tile/light/T = builtin_tile - if(T.state) + if(!state) qdel(C) - T.state = C //fixing it by bashing it with a light bulb, fun eh? + state = LIGHTFLOOR_ON update_icon() user << "You replace the light bulb." else - user << "The light bulb seems fine, no need to replace it." \ No newline at end of file + user << "The light bulb seems fine, no need to replace it." + if(istype(C,/obj/item/device/multitool)) + if(state != 0) + if(state < LIGHTFLOOR_PURPLE) + state++ + else + state = LIGHTFLOOR_ON + user << "You change \the [src]'s light bulb color." + update_icon() + else + user << "\The [src]'s light bulb appears to have burned out." \ No newline at end of file diff --git a/code/game/turfs/simulated/floor/misc_floor.dm b/code/game/turfs/simulated/floor/misc_floor.dm index efa62bc17cb..e48770a177b 100644 --- a/code/game/turfs/simulated/floor/misc_floor.dm +++ b/code/game/turfs/simulated/floor/misc_floor.dm @@ -54,4 +54,15 @@ /turf/simulated/floor/beach/water/New() ..() - overlays += image("icon"='icons/misc/beach.dmi',"icon_state"="water5","layer"=MOB_LAYER+0.1) \ No newline at end of file + overlays += image("icon"='icons/misc/beach.dmi',"icon_state"="water5","layer"=MOB_LAYER+0.1) + +/turf/simulated/floor/noslip + name = "high-traction floor" + icon_state = "noslip" + floor_tile = /obj/item/stack/tile/noslip + broken_states = list("noslip-damaged1","noslip-damaged2","noslip-damaged3") + burnt_states = list("noslip-scorched1","noslip-scorched2") + slowdown = -0.3 + +/turf/simulated/floor/noslip/MakeSlippery() + return \ No newline at end of file diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index e8a2ddf2aaa..37b40525275 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -4,6 +4,7 @@ luminosity = 1 var/intact = 1 + var/slowdown = 0 //negative for faster, positive for slower //Properties for open tiles (/floor) var/oxygen = 0 diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index d82d029a530..e8d01ac9f8e 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -1135,7 +1135,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts ha_style = "None" // No Vulp ears on Unathi m_style = "None" // No Unathi markings on Tajara - body_accessory = null //no vulpatail on humans damnit + body_accessory = null //no vulptail on humans damnit if("speciesprefs")//oldvox code speciesprefs = !speciesprefs diff --git a/code/modules/clothing/shoes/miscellaneous.dm b/code/modules/clothing/shoes/miscellaneous.dm index 46db0d5e139..154526cee3f 100644 --- a/code/modules/clothing/shoes/miscellaneous.dm +++ b/code/modules/clothing/shoes/miscellaneous.dm @@ -57,6 +57,16 @@ put_on_delay = 50 species_restricted = null +/obj/item/clothing/shoes/galoshes/dry + name = "absorbent galoshes" + desc = "A pair of purple rubber boots, designed to prevent slipping on wet surfaces while also drying them." + icon_state = "galoshes_dry" + +/obj/item/clothing/shoes/galoshes/dry/step_action() + var/turf/simulated/t_loc = get_turf(src) + if(istype(t_loc) && t_loc.wet) + t_loc.MakeDry(TURF_WET_WATER) + /obj/item/clothing/shoes/clown_shoes desc = "The prankster's standard-issue clowning shoes. Damn they're huge!" name = "clown shoes" diff --git a/code/modules/mob/living/carbon/human/body_accessories.dm b/code/modules/mob/living/carbon/human/body_accessories.dm index ca94bd49baf..901f43345d8 100644 --- a/code/modules/mob/living/carbon/human/body_accessories.dm +++ b/code/modules/mob/living/carbon/human/body_accessories.dm @@ -100,7 +100,7 @@ var/global/list/body_accessory_by_species = list("None" = null) return 0 -//vulpakin +//Vulpkanin /datum/body_accessory/tail/vulpkanin_2 name = "Vulpkanin Alt 1 (Bushy)" diff --git a/code/modules/mob/living/carbon/human/species/station.dm b/code/modules/mob/living/carbon/human/species/station.dm index 056425a0966..b8a8338ccab 100644 --- a/code/modules/mob/living/carbon/human/species/station.dm +++ b/code/modules/mob/living/carbon/human/species/station.dm @@ -111,7 +111,7 @@ /datum/species/vulpkanin name = "Vulpkanin" - name_plural = "Vulpakanin" + name_plural = "Vulpkanin" icobase = 'icons/mob/human_races/r_vulpkanin.dmi' deform = 'icons/mob/human_races/r_vulpkanin.dmi' path = /mob/living/carbon/human/vulpkanin @@ -173,6 +173,7 @@ default_language = "Galactic Common" language = "Vox-pidgin" + tail = "voxtail" speech_sounds = list('sound/voice/shriek1.ogg') speech_chance = 20 unarmed_type = /datum/unarmed_attack/claws //I dont think it will hurt to give vox claws too. @@ -199,12 +200,16 @@ flags = NO_SCAN | IS_WHITELISTED clothing_flags = HAS_SOCKS dietflags = DIET_OMNI + bodyflags = HAS_TAIL | TAIL_WAGGING blood_color = "#2299FC" flesh_color = "#808D11" reagent_tag = PROCESS_ORG +/datum/species/vox/handle_death(var/mob/living/carbon/human/H) + H.stop_tail_wagging(1) + /datum/species/vox/makeName(var/gender,var/mob/living/carbon/human/H=null) var/sounds = rand(2,8) var/i = 0 diff --git a/code/modules/mob/living/carbon/metroid/death.dm b/code/modules/mob/living/carbon/slime/death.dm similarity index 93% rename from code/modules/mob/living/carbon/metroid/death.dm rename to code/modules/mob/living/carbon/slime/death.dm index e7cac39a36c..6e951320bdc 100644 --- a/code/modules/mob/living/carbon/metroid/death.dm +++ b/code/modules/mob/living/carbon/slime/death.dm @@ -1,29 +1,29 @@ -/mob/living/carbon/slime/death(gibbed) - if(!gibbed) - if(is_adult) - var/mob/living/carbon/slime/M = new /mob/living/carbon/slime(loc) - M.colour = colour - M.rabid = 1 - is_adult = 0 - maxHealth = 150 - revive() - regenerate_icons() - number = rand(1, 1000) - name = "[colour] [is_adult ? "adult" : "baby"] slime ([number])" - return - - if(stat == DEAD) return - stat = DEAD - icon_state = "[colour] baby slime dead" - overlays.len = 0 - for(var/mob/O in viewers(src, null)) - O.show_message("The [name] seizes up and falls limp...", 1) //ded -- Urist - - update_canmove() - if(blind) - blind.layer = 0 - - if(ticker && ticker.mode) - ticker.mode.check_win() - +/mob/living/carbon/slime/death(gibbed) + if(!gibbed) + if(is_adult) + var/mob/living/carbon/slime/M = new /mob/living/carbon/slime(loc) + M.colour = colour + M.rabid = 1 + is_adult = 0 + maxHealth = 150 + revive() + regenerate_icons() + number = rand(1, 1000) + name = "[colour] [is_adult ? "adult" : "baby"] slime ([number])" + return + + if(stat == DEAD) return + stat = DEAD + icon_state = "[colour] baby slime dead" + overlays.len = 0 + for(var/mob/O in viewers(src, null)) + O.show_message("The [name] seizes up and falls limp...", 1) //ded -- Urist + + update_canmove() + if(blind) + blind.layer = 0 + + if(ticker && ticker.mode) + ticker.mode.check_win() + return ..(gibbed) \ No newline at end of file diff --git a/code/modules/mob/living/carbon/metroid/emote.dm b/code/modules/mob/living/carbon/slime/emote.dm similarity index 96% rename from code/modules/mob/living/carbon/metroid/emote.dm rename to code/modules/mob/living/carbon/slime/emote.dm index fa7e5c07466..dcc0b066487 100644 --- a/code/modules/mob/living/carbon/metroid/emote.dm +++ b/code/modules/mob/living/carbon/slime/emote.dm @@ -1,74 +1,74 @@ -/mob/living/carbon/slime/emote(var/act, var/m_type=1, var/message = null) - if (findtext(act, "-", 1, null)) - var/t1 = findtext(act, "-", 1, null) - //param = copytext(act, t1 + 1, length(act) + 1) - act = copytext(act, 1, t1) - - if(findtext(act,"s",-1) && !findtext(act,"_",-2))//Removes ending s's unless they are prefixed with a '_' - act = copytext(act,1,length(act)) - - switch(act) //Alphabetical please - if ("me") - if(silent) - return - if (src.client) - if (client.prefs.muted & MUTE_IC) - src << "\red You cannot send IC messages (muted)." - return - if (src.client.handle_spam_prevention(message,MUTE_IC)) - return - if (stat) - return - if(!(message)) - return - return custom_emote(m_type, message) - if("bounce") - message = "The [src.name] bounces in place." - m_type = 1 - - if ("custom") - return custom_emote(m_type, message) - - if("jiggle") - message = "The [src.name] jiggles!" - m_type = 1 - - if("light") - message = "The [src.name] lights up for a bit, then stops." - m_type = 1 - - if("moan") - message = "The [src.name] moans." - m_type = 2 - - if("shiver") - message = "The [src.name] shivers." - m_type = 2 - - if("sway") - message = "The [src.name] sways around dizzily." - m_type = 1 - - if("twitch") - message = "The [src.name] twitches." - m_type = 1 - - if("vibrate") - message = "The [src.name] vibrates!" - m_type = 1 - - if ("help") //This is an exception - src << "Help for slime emotes. You can use these emotes with say \"*emote\":\n\nbounce, custom, jiggle, light, moan, shiver, sway, twitch, vibrate" - - else - src << "\blue Unusable emote '[act]'. Say *help for a list." - if ((message && src.stat == 0)) - if (m_type & 1) - for(var/mob/O in viewers(src, null)) - O.show_message(message, m_type) - //Foreach goto(703) - else - for(var/mob/O in hearers(src, null)) - O.show_message(message, m_type) - //Foreach goto(746) +/mob/living/carbon/slime/emote(var/act, var/m_type=1, var/message = null) + if (findtext(act, "-", 1, null)) + var/t1 = findtext(act, "-", 1, null) + //param = copytext(act, t1 + 1, length(act) + 1) + act = copytext(act, 1, t1) + + if(findtext(act,"s",-1) && !findtext(act,"_",-2))//Removes ending s's unless they are prefixed with a '_' + act = copytext(act,1,length(act)) + + switch(act) //Alphabetical please + if ("me") + if(silent) + return + if (src.client) + if (client.prefs.muted & MUTE_IC) + src << "\red You cannot send IC messages (muted)." + return + if (src.client.handle_spam_prevention(message,MUTE_IC)) + return + if (stat) + return + if(!(message)) + return + return custom_emote(m_type, message) + if("bounce") + message = "The [src.name] bounces in place." + m_type = 1 + + if ("custom") + return custom_emote(m_type, message) + + if("jiggle") + message = "The [src.name] jiggles!" + m_type = 1 + + if("light") + message = "The [src.name] lights up for a bit, then stops." + m_type = 1 + + if("moan") + message = "The [src.name] moans." + m_type = 2 + + if("shiver") + message = "The [src.name] shivers." + m_type = 2 + + if("sway") + message = "The [src.name] sways around dizzily." + m_type = 1 + + if("twitch") + message = "The [src.name] twitches." + m_type = 1 + + if("vibrate") + message = "The [src.name] vibrates!" + m_type = 1 + + if ("help") //This is an exception + src << "Help for slime emotes. You can use these emotes with say \"*emote\":\n\nbounce, custom, jiggle, light, moan, shiver, sway, twitch, vibrate" + + else + src << "\blue Unusable emote '[act]'. Say *help for a list." + if ((message && src.stat == 0)) + if (m_type & 1) + for(var/mob/O in viewers(src, null)) + O.show_message(message, m_type) + //Foreach goto(703) + else + for(var/mob/O in hearers(src, null)) + O.show_message(message, m_type) + //Foreach goto(746) return \ No newline at end of file diff --git a/code/modules/mob/living/carbon/metroid/examine.dm b/code/modules/mob/living/carbon/slime/examine.dm similarity index 95% rename from code/modules/mob/living/carbon/metroid/examine.dm rename to code/modules/mob/living/carbon/slime/examine.dm index 67ef5770103..826fa93c22e 100644 --- a/code/modules/mob/living/carbon/metroid/examine.dm +++ b/code/modules/mob/living/carbon/slime/examine.dm @@ -1,44 +1,44 @@ -/mob/living/carbon/slime/examine(mob/user) - ..(user) - var/msg = "" - if (src.stat == DEAD) - msg += "It is limp and unresponsive.\n" - else - if (src.getBruteLoss()) - msg += "" - if (src.getBruteLoss() < 40) - msg += "It has some punctures in its flesh!" - else - msg += "It has severe punctures and tears in its flesh!" - msg += "\n" - - switch(powerlevel) - - if(2 to 3) - msg += "It is flickering gently with a little electrical activity.\n" - - if(4 to 5) - msg += "It is glowing gently with moderate levels of electrical activity.\n" - - if(6 to 9) - msg += "It is glowing brightly with high levels of electrical activity.\n" - - if(10) - msg += "It is radiating with massive levels of electrical activity!\n" - - msg += "" - switch(wetlevel) - if(1) - msg += "It looks a bit damp.\n" - if(2) - msg += "It looks a little bit wet.\n" - if(3) - msg += "It looks wet.\n" - if(4) - msg += "It looks very wet.\n" - if(5) - msg += "It looks absolutely soaked.\n" - msg += "" - - msg += "*---------*" +/mob/living/carbon/slime/examine(mob/user) + ..(user) + var/msg = "" + if (src.stat == DEAD) + msg += "It is limp and unresponsive.\n" + else + if (src.getBruteLoss()) + msg += "" + if (src.getBruteLoss() < 40) + msg += "It has some punctures in its flesh!" + else + msg += "It has severe punctures and tears in its flesh!" + msg += "\n" + + switch(powerlevel) + + if(2 to 3) + msg += "It is flickering gently with a little electrical activity.\n" + + if(4 to 5) + msg += "It is glowing gently with moderate levels of electrical activity.\n" + + if(6 to 9) + msg += "It is glowing brightly with high levels of electrical activity.\n" + + if(10) + msg += "It is radiating with massive levels of electrical activity!\n" + + msg += "" + switch(wetlevel) + if(1) + msg += "It looks a bit damp.\n" + if(2) + msg += "It looks a little bit wet.\n" + if(3) + msg += "It looks wet.\n" + if(4) + msg += "It looks very wet.\n" + if(5) + msg += "It looks absolutely soaked.\n" + msg += "" + + msg += "*---------*" user << msg \ No newline at end of file diff --git a/code/modules/mob/living/carbon/metroid/life.dm b/code/modules/mob/living/carbon/slime/life.dm similarity index 96% rename from code/modules/mob/living/carbon/metroid/life.dm rename to code/modules/mob/living/carbon/slime/life.dm index b70075a084b..1e3d901755a 100644 --- a/code/modules/mob/living/carbon/metroid/life.dm +++ b/code/modules/mob/living/carbon/slime/life.dm @@ -1,552 +1,552 @@ -/mob/living/carbon/slime - var/AIproc = 0 // determines if the AI loop is activated - var/Atkcool = 0 // attack cooldown - var/Tempstun = 0 // temporary temperature stuns - var/Discipline = 0 // if a slime has been hit with a freeze gun, or wrestled/attacked off a human, they become disciplined and don't attack anymore for a while - var/SStun = 0 // stun variable - -/mob/living/carbon/slime/Life() - if(..()) - handle_nutrition() - handle_targets() - if (!ckey) - handle_speech_and_mood() - -/mob/living/carbon/slime/proc/AIprocess() // the master AI process - - if(AIproc || stat == DEAD || client) return - - var/hungry = 0 - if (nutrition < get_starve_nutrition()) - hungry = 2 - else if (nutrition < get_grow_nutrition() && prob(25) || nutrition < get_hunger_nutrition()) - hungry = 1 - - AIproc = 1 - - while(AIproc && stat != 2 && (attacked || hungry || rabid || Victim)) - if(Victim) // can't eat AND have this little process at the same time - break - - if(!Target || client) - break - - if(Target.health <= -70 || Target.stat == 2) - Target = null - AIproc = 0 - break - - if(Target) - for(var/mob/living/carbon/slime/M in view(1,Target)) - if(M.Victim == Target) - Target = null - AIproc = 0 - break - if(!AIproc) - break - - if(Target in view(1,src)) - if(istype(Target, /mob/living/silicon)) - if(!Atkcool) - Atkcool = 1 - spawn(45) - Atkcool = 0 - - if(Target.Adjacent(src)) - Target.attack_slime(src) - return - if(!Target.lying && prob(80)) - - if(Target.client && Target.health >= 20) - if(!Atkcool) - Atkcool = 1 - spawn(45) - Atkcool = 0 - - if(Target.Adjacent(src)) - Target.attack_slime(src) - - else - if(!Atkcool && Target.Adjacent(src)) - Feedon(Target) - - else - if(!Atkcool && Target.Adjacent(src)) - Feedon(Target) - - else - if(Target in view(7, src)) - if(!Target.Adjacent(src)) // Bug of the month candidate: slimes were attempting to move to target only if it was directly next to them, which caused them to target things, but not approach them - step_to(src, Target) - sleep(5) - - else - Target = null - AIproc = 0 - break - - var/sleeptime = movement_delay() - if(sleeptime <= 0) sleeptime = 1 - - sleep(sleeptime + 2) // this is about as fast as a player slime can go - - AIproc = 0 - -/mob/living/carbon/slime/handle_environment(datum/gas_mixture/environment) - if(!environment) - adjustToxLoss(rand(10,20)) - return - - //var/environment_heat_capacity = environment.heat_capacity() - var/loc_temp = T0C - if(istype(get_turf(src), /turf/space)) - //environment_heat_capacity = loc:heat_capacity - var/turf/heat_turf = get_turf(src) - loc_temp = heat_turf.temperature - else if(istype(loc, /obj/machinery/atmospherics/unary/cryo_cell)) - loc_temp = loc:air_contents.temperature - else - loc_temp = environment.temperature - - //Account for massive pressure differences - if(bodytemperature < (T0C + 5)) // start calculating temperature damage etc - if(bodytemperature <= (T0C - 40)) // stun temperature - Tempstun = 1 - - if(bodytemperature <= (T0C - 50)) // hurt temperature - if(bodytemperature <= 50) // sqrting negative numbers is bad - adjustToxLoss(301) //The config.health_threshold_dead is -100 by default, and slimes have 150hp (200hp for adults), - else //so the ToxLoss needs to be 300 or above to guarrantee an instant death - adjustToxLoss(round(sqrt(bodytemperature)) * 2) - else - Tempstun = 0 - - - /*moved after the temperature damage code so freeze beams can instantly kill slimes -Deity Link*/ - if(loc_temp < 310.15) // a cold place - bodytemperature += adjust_body_temperature(bodytemperature, loc_temp, 1) - else // a hot place - bodytemperature += adjust_body_temperature(bodytemperature, loc_temp, 1) - - updatehealth() - - return //TODO: DEFERRED - -/mob/living/carbon/slime/proc/adjust_body_temperature(current, loc_temp, boost) - var/temperature = current - var/difference = abs(current-loc_temp) //get difference - var/increments// = difference/10 //find how many increments apart they are - if(difference > 50) - increments = difference/5 - else - increments = difference/10 - var/change = increments*boost // Get the amount to change by (x per increment) - var/temp_change - if(current < loc_temp) - temperature = min(loc_temp, temperature+change) - else if(current > loc_temp) - temperature = max(loc_temp, temperature-change) - temp_change = (temperature - current) - return temp_change - -/mob/living/carbon/slime/handle_chemicals_in_body() - - if(reagents) reagents.metabolize(src) - if (reagents.get_reagent_amount("plasma")>=5) - mutation_chance = min(mutation_chance + 5,50) //Prevents mutation chance going >50% - reagents.remove_reagent("plasma", 5) - if (reagents.get_reagent_amount("epinephrine")>=5) - mutation_chance = max(mutation_chance - 5,0) //Prevents muation chance going <0% - reagents.remove_reagent("epinephrine", 5) - src.updatehealth() - - return //TODO: DEFERRED - -/mob/living/carbon/slime/handle_regular_status_updates() - - if(is_adult) - health = 200 - (getOxyLoss() + getToxLoss() + getFireLoss() + getBruteLoss() + getCloneLoss()) - else - health = 150 - (getOxyLoss() + getToxLoss() + getFireLoss() + getBruteLoss() + getCloneLoss()) - - if(health < config.health_threshold_dead && stat != 2) - death() - return - - else if(src.health <= config.health_threshold_crit) - - if(!src.reagents.has_reagent("epinephrine")) - src.adjustOxyLoss(10) - - if(src.stat != DEAD) - src.stat = UNCONSCIOUS - - if(prob(30)) //I think this is meant to allow slimes to starve to death - adjustOxyLoss(-1) - adjustToxLoss(-1) - adjustFireLoss(-1) - adjustCloneLoss(-1) - adjustBruteLoss(-1) - - if (src.stat == DEAD) - src.lying = 1 - src.blinded = 1 - else - if (src.paralysis || src.stunned || src.weakened || (status_flags && FAKEDEATH)) //Stunned etc. - if (src.stunned > 0) - AdjustStunned(-1) - src.stat = 0 - if (src.weakened > 0) - AdjustWeakened(-1) - src.lying = 0 - src.stat = 0 - if (src.paralysis > 0) - AdjustParalysis(-1) - src.blinded = 0 - src.lying = 0 - src.stat = 0 - - else - src.lying = 0 - src.stat = 0 - - if (src.stuttering) src.stuttering = 0 - - if (src.eye_blind) - src.eye_blind = 0 - src.blinded = 1 - - if (src.ear_deaf > 0) src.ear_deaf = 0 - if (src.ear_damage < 25) - src.ear_damage = 0 - - src.density = !( src.lying ) - - if (src.sdisabilities & BLIND) - src.blinded = 1 - if (src.sdisabilities & DEAF) - src.ear_deaf = 1 - - if (src.eye_blurry > 0) - src.eye_blurry = 0 - - if (src.druggy > 0) - src.druggy = 0 - - return 1 - -/mob/living/carbon/slime/proc/handle_nutrition() - - if (prob(15)) - nutrition -= 1 + is_adult - - if(nutrition <= 0) - nutrition = 0 - if(prob(75)) - adjustToxLoss(rand(0,5)) - - else if (nutrition >= get_grow_nutrition() && amount_grown < 10) - nutrition -= 20 - amount_grown++ - - if(amount_grown >= 10 && !Victim && !Target && !ckey) - if(is_adult) - Reproduce() - else - Evolve() - - -/mob/living/carbon/slime/proc/handle_targets() - if(Tempstun) - if(!Victim) // not while they're eating! - canmove = 0 - else - canmove = 1 - - if(attacked > 50) attacked = 50 - - if(attacked > 0) - attacked-- - - if(Discipline > 0) - - if(Discipline >= 5 && rabid) - if(prob(60)) rabid = 0 - - if(prob(10)) - Discipline-- - - if(!client) - if(!canmove) return - - if(Victim) return // if it's eating someone already, continue eating! - - if(Target) - --target_patience - if (target_patience <= 0 || SStun || Discipline || attacked) // Tired of chasing or something draws out attention - target_patience = 0 - Target = null - - if(AIproc && SStun) return - - var/hungry = 0 // determines if the slime is hungry - - if (nutrition < get_starve_nutrition()) - hungry = 2 - else if (nutrition < get_grow_nutrition() && prob(25) || nutrition < get_hunger_nutrition()) - hungry = 1 - - if(hungry == 2 && !client) // if a slime is starving, it starts losing its friends - if(Friends.len > 0 && prob(1)) - var/mob/nofriend = pick(Friends) - --Friends[nofriend] - - if(!Target) - if(will_hunt() && hungry || attacked || rabid) // Only add to the list if we need to - var/list/targets = list() - - for(var/mob/living/L in view(7,src)) - - if(isslime(L) || L.stat == DEAD) // Ignore other slimes and dead mobs - continue - - if(L in Friends) // No eating friends! - continue - - if(issilicon(L) && (rabid || attacked)) // They can't eat silicons, but they can glomp them in defence - targets += L // Possible target found! - - if(istype(L, /mob/living/carbon/human)) //Ignore slime(wo)men - var/mob/living/carbon/human/H = L - if(H.species.name == "Slime People") - continue - - if(!L.canmove) // Only one slime can latch on at a time. - var/notarget = 0 - for(var/mob/living/carbon/slime/M in view(1,L)) - if(M.Victim == L) - notarget = 1 - if(notarget) - continue - - targets += L // Possible target found! - - if(targets.len > 0) - if(attacked || rabid || hungry == 2) - Target = targets[1] // I am attacked and am fighting back or so hungry I don't even care - else - for(var/mob/living/carbon/C in targets) - if(!Discipline && prob(5)) - if(ishuman(C) || isalienadult(C)) - Target = C - break - - if(islarva(C) || issmall(C)) - Target = C - break - - if (Target) - target_patience = rand(5,7) - if (is_adult) - target_patience += 3 - - if(!Target) // If we have no target, we are wandering or following orders - if (Leader) - if (holding_still) - holding_still = max(holding_still - 1, 0) - else if(canmove && isturf(loc)) - step_to(src, Leader) - - else if(hungry) - if (holding_still) - holding_still = max(holding_still - hungry, 0) - else if(canmove && isturf(loc) && prob(50)) - step(src, pick(cardinal)) - - else - if (holding_still) - holding_still = max(holding_still - 1, 0) - else if(canmove && isturf(loc) && prob(33)) - step(src, pick(cardinal)) - else if(!AIproc) - spawn() - AIprocess() - -/mob/living/carbon/slime/proc/handle_speech_and_mood() - //Mood starts here - var/newmood = "" - if (rabid || attacked) newmood = "angry" - else if (Target) newmood = "mischevous" - - if (!newmood) - if (Discipline && prob(25)) - newmood = "pout" - else if (prob(1)) - newmood = pick("sad", ":3", "pout") - - if ((mood == "sad" || mood == ":3" || mood == "pout") && !newmood) - if (prob(75)) newmood = mood - - if (newmood != mood) // This is so we don't redraw them every time - mood = newmood - regenerate_icons() - - //Speech understanding starts here - var/to_say - if (speech_buffer.len > 0) - var/who = speech_buffer[1] // Who said it? - var/phrase = speech_buffer[2] // What did they say? - if ((findtext(phrase, num2text(number)) || findtext(phrase, "slimes"))) // Talking to us - if (findtext(phrase, "hello") || findtext(phrase, "hi")) - to_say = pick("Hello...", "Hi...") - else if (findtext(phrase, "follow")) - if (Leader) - if (Leader == who) // Already following him - to_say = pick("Yes...", "Lead...", "Following...") - else if (Friends[who] > Friends[Leader]) // VIVA - Leader = who - to_say = "Yes... I follow [who]..." - else - to_say = "No... I follow [Leader]..." - else - if (Friends[who] > 2) - Leader = who - to_say = "I follow..." - else // Not friendly enough - to_say = pick("No...", "I won't follow...") - else if (findtext(phrase, "stop")) - if (Victim) // We are asked to stop feeding - if (Friends[who] > 4) - Victim = null - Target = null - if (Friends[who] < 7) - --Friends[who] - to_say = "Grrr..." // I'm angry but I do it - else - to_say = "Fine..." - else if (Target) // We are asked to stop chasing - if (Friends[who] > 3) - Target = null - if (Friends[who] < 6) - --Friends[who] - to_say = "Grrr..." // I'm angry but I do it - else - to_say = "Fine..." - else if (Leader) // We are asked to stop following - if (Leader == who) - to_say = "Yes... I'll stay..." - Leader = null - else - if (Friends[who] > Friends[Leader]) - Leader = null - to_say = "Yes... I'll stop..." - else - to_say = "No... I'll keep following..." - else if (findtext(phrase, "stay")) - if (Leader) - if (Leader == who) - holding_still = Friends[who] * 10 - to_say = "Yes... Staying..." - else if (Friends[who] > Friends[Leader]) - holding_still = (Friends[who] - Friends[Leader]) * 10 - to_say = "Yes... Staying..." - else - to_say = "No... I'll keep following..." - else - if (Friends[who] > 2) - holding_still = Friends[who] * 10 - to_say = "Yes... Staying..." - else - to_say = "No... I won't stay..." - speech_buffer = list() - - //Speech starts here - if (to_say) - say (to_say) - else if(prob(1)) - emote(pick("bounce","sway","light","vibrate","jiggle")) - else - var/t = 10 - var/slimes_near = -1 // Don't count myself - var/dead_slimes = 0 - var/friends_near = list() - for (var/mob/living/carbon/M in view(7,src)) - if (isslime(M)) - ++slimes_near - if (M.stat == DEAD) - ++dead_slimes - if (M in Friends) - t += 20 - friends_near += M - if (nutrition < get_hunger_nutrition()) t += 10 - if (nutrition < get_starve_nutrition()) t += 10 - if (prob(2) && prob(t)) - var/phrases = list() - if (Target) phrases += "[Target]... looks tasty..." - if (nutrition < get_starve_nutrition()) - phrases += "So... hungry..." - phrases += "Very... hungry..." - phrases += "Need... food..." - phrases += "Must... eat..." - else if (nutrition < get_hunger_nutrition()) - phrases += "Hungry..." - phrases += "Where is the food?" - phrases += "I want to eat..." - phrases += "Rawr..." - phrases += "Blop..." - phrases += "Blorble..." - if (rabid || attacked) - phrases += "Hrr..." - phrases += "Nhuu..." - phrases += "Unn..." - if (mood == ":3") - phrases += "Purr..." - if (attacked) - phrases += "Grrr..." - if (getToxLoss() > 30) - phrases += "Cold..." - if (getToxLoss() > 60) - phrases += "So... cold..." - phrases += "Very... cold..." - if (getToxLoss() > 90) - phrases += "..." - phrases += "C... c..." - if (Victim) - phrases += "Nom..." - phrases += "Tasty..." - if (powerlevel > 3) phrases += "Bzzz..." - if (powerlevel > 5) phrases += "Zap..." - if (powerlevel > 8) phrases += "Zap... Bzz..." - if (mood == "sad") phrases += "Bored..." - if (slimes_near) phrases += "Brother..." - if (slimes_near > 1) phrases += "Brothers..." - if (dead_slimes) phrases += "What happened?" - if (!slimes_near) - phrases += "Lonely..." - for (var/M in friends_near) - phrases += "[M]... friend..." - if (nutrition < get_hunger_nutrition()) - phrases += "[M]... feed me..." - say (pick(phrases)) - -/mob/living/carbon/slime/proc/get_max_nutrition() // Can't go above it - if (is_adult) return 1200 - else return 1000 - -/mob/living/carbon/slime/proc/get_grow_nutrition() // Above it we grow, below it we can eat - if (is_adult) return 1000 - else return 800 - -/mob/living/carbon/slime/proc/get_hunger_nutrition() // Below it we will always eat - if (is_adult) return 600 - else return 500 - -/mob/living/carbon/slime/proc/get_starve_nutrition() // Below it we will eat before everything else - if (is_adult) return 300 - else return 200 - -/mob/living/carbon/slime/proc/will_hunt(var/hunger = -1) // Check for being stopped from feeding and chasing - if (hunger == 2 || rabid || attacked) return 1 - if (Leader) return 0 - if (holding_still) return 0 - return 1 +/mob/living/carbon/slime + var/AIproc = 0 // determines if the AI loop is activated + var/Atkcool = 0 // attack cooldown + var/Tempstun = 0 // temporary temperature stuns + var/Discipline = 0 // if a slime has been hit with a freeze gun, or wrestled/attacked off a human, they become disciplined and don't attack anymore for a while + var/SStun = 0 // stun variable + +/mob/living/carbon/slime/Life() + if(..()) + handle_nutrition() + handle_targets() + if (!ckey) + handle_speech_and_mood() + +/mob/living/carbon/slime/proc/AIprocess() // the master AI process + + if(AIproc || stat == DEAD || client) return + + var/hungry = 0 + if (nutrition < get_starve_nutrition()) + hungry = 2 + else if (nutrition < get_grow_nutrition() && prob(25) || nutrition < get_hunger_nutrition()) + hungry = 1 + + AIproc = 1 + + while(AIproc && stat != 2 && (attacked || hungry || rabid || Victim)) + if(Victim) // can't eat AND have this little process at the same time + break + + if(!Target || client) + break + + if(Target.health <= -70 || Target.stat == 2) + Target = null + AIproc = 0 + break + + if(Target) + for(var/mob/living/carbon/slime/M in view(1,Target)) + if(M.Victim == Target) + Target = null + AIproc = 0 + break + if(!AIproc) + break + + if(Target in view(1,src)) + if(istype(Target, /mob/living/silicon)) + if(!Atkcool) + Atkcool = 1 + spawn(45) + Atkcool = 0 + + if(Target.Adjacent(src)) + Target.attack_slime(src) + return + if(!Target.lying && prob(80)) + + if(Target.client && Target.health >= 20) + if(!Atkcool) + Atkcool = 1 + spawn(45) + Atkcool = 0 + + if(Target.Adjacent(src)) + Target.attack_slime(src) + + else + if(!Atkcool && Target.Adjacent(src)) + Feedon(Target) + + else + if(!Atkcool && Target.Adjacent(src)) + Feedon(Target) + + else + if(Target in view(7, src)) + if(!Target.Adjacent(src)) // Bug of the month candidate: slimes were attempting to move to target only if it was directly next to them, which caused them to target things, but not approach them + step_to(src, Target) + sleep(5) + + else + Target = null + AIproc = 0 + break + + var/sleeptime = movement_delay() + if(sleeptime <= 0) sleeptime = 1 + + sleep(sleeptime + 2) // this is about as fast as a player slime can go + + AIproc = 0 + +/mob/living/carbon/slime/handle_environment(datum/gas_mixture/environment) + if(!environment) + adjustToxLoss(rand(10,20)) + return + + //var/environment_heat_capacity = environment.heat_capacity() + var/loc_temp = T0C + if(istype(get_turf(src), /turf/space)) + //environment_heat_capacity = loc:heat_capacity + var/turf/heat_turf = get_turf(src) + loc_temp = heat_turf.temperature + else if(istype(loc, /obj/machinery/atmospherics/unary/cryo_cell)) + loc_temp = loc:air_contents.temperature + else + loc_temp = environment.temperature + + //Account for massive pressure differences + if(bodytemperature < (T0C + 5)) // start calculating temperature damage etc + if(bodytemperature <= (T0C - 40)) // stun temperature + Tempstun = 1 + + if(bodytemperature <= (T0C - 50)) // hurt temperature + if(bodytemperature <= 50) // sqrting negative numbers is bad + adjustToxLoss(301) //The config.health_threshold_dead is -100 by default, and slimes have 150hp (200hp for adults), + else //so the ToxLoss needs to be 300 or above to guarrantee an instant death + adjustToxLoss(round(sqrt(bodytemperature)) * 2) + else + Tempstun = 0 + + + /*moved after the temperature damage code so freeze beams can instantly kill slimes -Deity Link*/ + if(loc_temp < 310.15) // a cold place + bodytemperature += adjust_body_temperature(bodytemperature, loc_temp, 1) + else // a hot place + bodytemperature += adjust_body_temperature(bodytemperature, loc_temp, 1) + + updatehealth() + + return //TODO: DEFERRED + +/mob/living/carbon/slime/proc/adjust_body_temperature(current, loc_temp, boost) + var/temperature = current + var/difference = abs(current-loc_temp) //get difference + var/increments// = difference/10 //find how many increments apart they are + if(difference > 50) + increments = difference/5 + else + increments = difference/10 + var/change = increments*boost // Get the amount to change by (x per increment) + var/temp_change + if(current < loc_temp) + temperature = min(loc_temp, temperature+change) + else if(current > loc_temp) + temperature = max(loc_temp, temperature-change) + temp_change = (temperature - current) + return temp_change + +/mob/living/carbon/slime/handle_chemicals_in_body() + + if(reagents) reagents.metabolize(src) + if (reagents.get_reagent_amount("plasma")>=5) + mutation_chance = min(mutation_chance + 5,50) //Prevents mutation chance going >50% + reagents.remove_reagent("plasma", 5) + if (reagents.get_reagent_amount("epinephrine")>=5) + mutation_chance = max(mutation_chance - 5,0) //Prevents muation chance going <0% + reagents.remove_reagent("epinephrine", 5) + src.updatehealth() + + return //TODO: DEFERRED + +/mob/living/carbon/slime/handle_regular_status_updates() + + if(is_adult) + health = 200 - (getOxyLoss() + getToxLoss() + getFireLoss() + getBruteLoss() + getCloneLoss()) + else + health = 150 - (getOxyLoss() + getToxLoss() + getFireLoss() + getBruteLoss() + getCloneLoss()) + + if(health < config.health_threshold_dead && stat != 2) + death() + return + + else if(src.health <= config.health_threshold_crit) + + if(!src.reagents.has_reagent("epinephrine")) + src.adjustOxyLoss(10) + + if(src.stat != DEAD) + src.stat = UNCONSCIOUS + + if(prob(30)) //I think this is meant to allow slimes to starve to death + adjustOxyLoss(-1) + adjustToxLoss(-1) + adjustFireLoss(-1) + adjustCloneLoss(-1) + adjustBruteLoss(-1) + + if (src.stat == DEAD) + src.lying = 1 + src.blinded = 1 + else + if (src.paralysis || src.stunned || src.weakened || (status_flags && FAKEDEATH)) //Stunned etc. + if (src.stunned > 0) + AdjustStunned(-1) + src.stat = 0 + if (src.weakened > 0) + AdjustWeakened(-1) + src.lying = 0 + src.stat = 0 + if (src.paralysis > 0) + AdjustParalysis(-1) + src.blinded = 0 + src.lying = 0 + src.stat = 0 + + else + src.lying = 0 + src.stat = 0 + + if (src.stuttering) src.stuttering = 0 + + if (src.eye_blind) + src.eye_blind = 0 + src.blinded = 1 + + if (src.ear_deaf > 0) src.ear_deaf = 0 + if (src.ear_damage < 25) + src.ear_damage = 0 + + src.density = !( src.lying ) + + if (src.sdisabilities & BLIND) + src.blinded = 1 + if (src.sdisabilities & DEAF) + src.ear_deaf = 1 + + if (src.eye_blurry > 0) + src.eye_blurry = 0 + + if (src.druggy > 0) + src.druggy = 0 + + return 1 + +/mob/living/carbon/slime/proc/handle_nutrition() + + if (prob(15)) + nutrition -= 1 + is_adult + + if(nutrition <= 0) + nutrition = 0 + if(prob(75)) + adjustToxLoss(rand(0,5)) + + else if (nutrition >= get_grow_nutrition() && amount_grown < 10) + nutrition -= 20 + amount_grown++ + + if(amount_grown >= 10 && !Victim && !Target && !ckey) + if(is_adult) + Reproduce() + else + Evolve() + + +/mob/living/carbon/slime/proc/handle_targets() + if(Tempstun) + if(!Victim) // not while they're eating! + canmove = 0 + else + canmove = 1 + + if(attacked > 50) attacked = 50 + + if(attacked > 0) + attacked-- + + if(Discipline > 0) + + if(Discipline >= 5 && rabid) + if(prob(60)) rabid = 0 + + if(prob(10)) + Discipline-- + + if(!client) + if(!canmove) return + + if(Victim) return // if it's eating someone already, continue eating! + + if(Target) + --target_patience + if (target_patience <= 0 || SStun || Discipline || attacked) // Tired of chasing or something draws out attention + target_patience = 0 + Target = null + + if(AIproc && SStun) return + + var/hungry = 0 // determines if the slime is hungry + + if (nutrition < get_starve_nutrition()) + hungry = 2 + else if (nutrition < get_grow_nutrition() && prob(25) || nutrition < get_hunger_nutrition()) + hungry = 1 + + if(hungry == 2 && !client) // if a slime is starving, it starts losing its friends + if(Friends.len > 0 && prob(1)) + var/mob/nofriend = pick(Friends) + --Friends[nofriend] + + if(!Target) + if(will_hunt() && hungry || attacked || rabid) // Only add to the list if we need to + var/list/targets = list() + + for(var/mob/living/L in view(7,src)) + + if(isslime(L) || L.stat == DEAD) // Ignore other slimes and dead mobs + continue + + if(L in Friends) // No eating friends! + continue + + if(issilicon(L) && (rabid || attacked)) // They can't eat silicons, but they can glomp them in defence + targets += L // Possible target found! + + if(istype(L, /mob/living/carbon/human)) //Ignore slime(wo)men + var/mob/living/carbon/human/H = L + if(H.species.name == "Slime People") + continue + + if(!L.canmove) // Only one slime can latch on at a time. + var/notarget = 0 + for(var/mob/living/carbon/slime/M in view(1,L)) + if(M.Victim == L) + notarget = 1 + if(notarget) + continue + + targets += L // Possible target found! + + if(targets.len > 0) + if(attacked || rabid || hungry == 2) + Target = targets[1] // I am attacked and am fighting back or so hungry I don't even care + else + for(var/mob/living/carbon/C in targets) + if(!Discipline && prob(5)) + if(ishuman(C) || isalienadult(C)) + Target = C + break + + if(islarva(C) || issmall(C)) + Target = C + break + + if (Target) + target_patience = rand(5,7) + if (is_adult) + target_patience += 3 + + if(!Target) // If we have no target, we are wandering or following orders + if (Leader) + if (holding_still) + holding_still = max(holding_still - 1, 0) + else if(canmove && isturf(loc)) + step_to(src, Leader) + + else if(hungry) + if (holding_still) + holding_still = max(holding_still - hungry, 0) + else if(canmove && isturf(loc) && prob(50)) + step(src, pick(cardinal)) + + else + if (holding_still) + holding_still = max(holding_still - 1, 0) + else if(canmove && isturf(loc) && prob(33)) + step(src, pick(cardinal)) + else if(!AIproc) + spawn() + AIprocess() + +/mob/living/carbon/slime/proc/handle_speech_and_mood() + //Mood starts here + var/newmood = "" + if (rabid || attacked) newmood = "angry" + else if (Target) newmood = "mischevous" + + if (!newmood) + if (Discipline && prob(25)) + newmood = "pout" + else if (prob(1)) + newmood = pick("sad", ":3", "pout") + + if ((mood == "sad" || mood == ":3" || mood == "pout") && !newmood) + if (prob(75)) newmood = mood + + if (newmood != mood) // This is so we don't redraw them every time + mood = newmood + regenerate_icons() + + //Speech understanding starts here + var/to_say + if (speech_buffer.len > 0) + var/who = speech_buffer[1] // Who said it? + var/phrase = speech_buffer[2] // What did they say? + if ((findtext(phrase, num2text(number)) || findtext(phrase, "slimes"))) // Talking to us + if (findtext(phrase, "hello") || findtext(phrase, "hi")) + to_say = pick("Hello...", "Hi...") + else if (findtext(phrase, "follow")) + if (Leader) + if (Leader == who) // Already following him + to_say = pick("Yes...", "Lead...", "Following...") + else if (Friends[who] > Friends[Leader]) // VIVA + Leader = who + to_say = "Yes... I follow [who]..." + else + to_say = "No... I follow [Leader]..." + else + if (Friends[who] > 2) + Leader = who + to_say = "I follow..." + else // Not friendly enough + to_say = pick("No...", "I won't follow...") + else if (findtext(phrase, "stop")) + if (Victim) // We are asked to stop feeding + if (Friends[who] > 4) + Victim = null + Target = null + if (Friends[who] < 7) + --Friends[who] + to_say = "Grrr..." // I'm angry but I do it + else + to_say = "Fine..." + else if (Target) // We are asked to stop chasing + if (Friends[who] > 3) + Target = null + if (Friends[who] < 6) + --Friends[who] + to_say = "Grrr..." // I'm angry but I do it + else + to_say = "Fine..." + else if (Leader) // We are asked to stop following + if (Leader == who) + to_say = "Yes... I'll stay..." + Leader = null + else + if (Friends[who] > Friends[Leader]) + Leader = null + to_say = "Yes... I'll stop..." + else + to_say = "No... I'll keep following..." + else if (findtext(phrase, "stay")) + if (Leader) + if (Leader == who) + holding_still = Friends[who] * 10 + to_say = "Yes... Staying..." + else if (Friends[who] > Friends[Leader]) + holding_still = (Friends[who] - Friends[Leader]) * 10 + to_say = "Yes... Staying..." + else + to_say = "No... I'll keep following..." + else + if (Friends[who] > 2) + holding_still = Friends[who] * 10 + to_say = "Yes... Staying..." + else + to_say = "No... I won't stay..." + speech_buffer = list() + + //Speech starts here + if (to_say) + say (to_say) + else if(prob(1)) + emote(pick("bounce","sway","light","vibrate","jiggle")) + else + var/t = 10 + var/slimes_near = -1 // Don't count myself + var/dead_slimes = 0 + var/friends_near = list() + for (var/mob/living/carbon/M in view(7,src)) + if (isslime(M)) + ++slimes_near + if (M.stat == DEAD) + ++dead_slimes + if (M in Friends) + t += 20 + friends_near += M + if (nutrition < get_hunger_nutrition()) t += 10 + if (nutrition < get_starve_nutrition()) t += 10 + if (prob(2) && prob(t)) + var/phrases = list() + if (Target) phrases += "[Target]... looks tasty..." + if (nutrition < get_starve_nutrition()) + phrases += "So... hungry..." + phrases += "Very... hungry..." + phrases += "Need... food..." + phrases += "Must... eat..." + else if (nutrition < get_hunger_nutrition()) + phrases += "Hungry..." + phrases += "Where is the food?" + phrases += "I want to eat..." + phrases += "Rawr..." + phrases += "Blop..." + phrases += "Blorble..." + if (rabid || attacked) + phrases += "Hrr..." + phrases += "Nhuu..." + phrases += "Unn..." + if (mood == ":3") + phrases += "Purr..." + if (attacked) + phrases += "Grrr..." + if (getToxLoss() > 30) + phrases += "Cold..." + if (getToxLoss() > 60) + phrases += "So... cold..." + phrases += "Very... cold..." + if (getToxLoss() > 90) + phrases += "..." + phrases += "C... c..." + if (Victim) + phrases += "Nom..." + phrases += "Tasty..." + if (powerlevel > 3) phrases += "Bzzz..." + if (powerlevel > 5) phrases += "Zap..." + if (powerlevel > 8) phrases += "Zap... Bzz..." + if (mood == "sad") phrases += "Bored..." + if (slimes_near) phrases += "Brother..." + if (slimes_near > 1) phrases += "Brothers..." + if (dead_slimes) phrases += "What happened?" + if (!slimes_near) + phrases += "Lonely..." + for (var/M in friends_near) + phrases += "[M]... friend..." + if (nutrition < get_hunger_nutrition()) + phrases += "[M]... feed me..." + say (pick(phrases)) + +/mob/living/carbon/slime/proc/get_max_nutrition() // Can't go above it + if (is_adult) return 1200 + else return 1000 + +/mob/living/carbon/slime/proc/get_grow_nutrition() // Above it we grow, below it we can eat + if (is_adult) return 1000 + else return 800 + +/mob/living/carbon/slime/proc/get_hunger_nutrition() // Below it we will always eat + if (is_adult) return 600 + else return 500 + +/mob/living/carbon/slime/proc/get_starve_nutrition() // Below it we will eat before everything else + if (is_adult) return 300 + else return 200 + +/mob/living/carbon/slime/proc/will_hunt(var/hunger = -1) // Check for being stopped from feeding and chasing + if (hunger == 2 || rabid || attacked) return 1 + if (Leader) return 0 + if (holding_still) return 0 + return 1 diff --git a/code/modules/mob/living/carbon/metroid/login.dm b/code/modules/mob/living/carbon/slime/login.dm similarity index 93% rename from code/modules/mob/living/carbon/metroid/login.dm rename to code/modules/mob/living/carbon/slime/login.dm index 8ca29bf4818..d3ac320f2f4 100644 --- a/code/modules/mob/living/carbon/metroid/login.dm +++ b/code/modules/mob/living/carbon/slime/login.dm @@ -1,4 +1,4 @@ -/mob/living/carbon/slime/Login() - ..() - update_hud() - return +/mob/living/carbon/slime/Login() + ..() + update_hud() + return diff --git a/code/modules/mob/living/carbon/metroid/powers.dm b/code/modules/mob/living/carbon/slime/powers.dm similarity index 95% rename from code/modules/mob/living/carbon/metroid/powers.dm rename to code/modules/mob/living/carbon/slime/powers.dm index fdbe54a9220..494bb6eb6df 100644 --- a/code/modules/mob/living/carbon/metroid/powers.dm +++ b/code/modules/mob/living/carbon/slime/powers.dm @@ -1,228 +1,228 @@ -/mob/living/carbon/slime/verb/Feed() - set category = "Slime" - set desc = "This will let you feed on any valid creature in the surrounding area. This should also be used to halt the feeding process." - if(Victim) - Feedstop() - return - - if(stat) - src << "I must be conscious to do this..." - return - - var/list/choices = list() - for(var/mob/living/C in view(1,src)) - if(C!=src && !istype(C,/mob/living/carbon/slime) && Adjacent(C)) - choices += C - - var/mob/living/M = input(src,"Who do you wish to feed on?") in null|choices - if(!M) return - if(Adjacent(M)) - - if(!istype(src, /mob/living/carbon/brain)) - if(!istype(M, /mob/living/carbon/slime)) - if(stat != 2) - if(health > -70) - - for(var/mob/living/carbon/slime/met in view()) - if(met.Victim == M && met != src) - src << "The [met.name] is already feeding on this subject..." - return - src << "\blue I have latched onto the subject and begun feeding..." - M << "\red The [src.name] has latched onto your head!" - Feedon(M) - - else - src << "This subject does not have a strong enough life energy..." - else - src << "This subject does not have an edible life energy..." - else - src << "I must not feed on my brothers..." - else - src << "This subject does not have an edible life energy..." - - - -/mob/living/carbon/slime/proc/Feedon(var/mob/living/M) - Victim = M - src.loc = M.loc - canmove = 0 - anchored = 1 - var/lastnut = nutrition - var/fed_succesfully = 0 - if(is_adult) - icon_state = "[colour] adult slime eat" - else - icon_state = "[colour] baby slime eat" - - while(Victim && M.health > -70 && M.stat != DEAD && stat != DEAD) - canmove = 0 - - if(Adjacent(M)) - loc = M.loc - - if(prob(15) && M.client && istype(M, /mob/living/carbon)) - M << "[pick("You can feel your body becoming weak!", \ - "You feel like you're about to die!", \ - "You feel every part of your body screaming in agony!", \ - "A low, rolling pain passes through your body!", \ - "Your body feels as if it's falling apart!", \ - "You feel extremely weak!", \ - "A sharp, deep pain bathes every inch of your body!")]" - - if(istype(M, /mob/living/carbon)) - Victim.adjustCloneLoss(rand(5,6)) - Victim.adjustToxLoss(rand(1,2)) - if(Victim.health <= 0) - Victim.adjustToxLoss(rand(2,4)) - - fed_succesfully = 1 - - else if(istype(M, /mob/living/simple_animal)) - Victim.adjustBruteLoss(is_adult ? rand(7, 15) : rand(4, 12)) - fed_succesfully = 1 - - else - if(prob(25)) - src << "[pick("This subject is incompatable", \ - "This subject does not have a life energy", "This subject is empty", \ - "I am not satisified", "I can not feed from this subject", \ - "I do not feel nourished", "This subject is not food")]..." - - if(fed_succesfully) - //I have no idea why this is not in handle_nutrition() - nutrition += rand(15,30) - if(nutrition >= lastnut + 50) - if(prob(80)) - lastnut = nutrition - powerlevel++ - if(powerlevel > 10) - powerlevel = 10 - adjustToxLoss(-10) - - //Heal yourself. - adjustOxyLoss(-10) - adjustBruteLoss(-10) - adjustFireLoss(-10) - adjustCloneLoss(-10) - - updatehealth() - if(Victim) - Victim.updatehealth() - - sleep(rand(15,45)) - - else - break - - if(stat == 2) - if(!is_adult) - icon_state = "[colour] baby slime dead" - - else - if(is_adult) - icon_state = "[colour] adult slime" - else - icon_state = "[colour] baby slime" - - canmove = 1 - anchored = 0 - - if(M) - if(M.health <= -70) - M.canmove = 0 - if(!client) - if(Victim && !rabid && !attacked) - if(Victim.LAssailant && Victim.LAssailant != Victim) - if(prob(50)) - if(!(Victim.LAssailant in Friends)) - Friends[Victim.LAssailant] = 1 - //Friends.Add(Victim.LAssailant) // no idea why i was using the |= operator - else - ++Friends[Victim.LAssailant] - - - if(M.client && istype(src, /mob/living/carbon/human)) - if(prob(85)) - rabid = 1 // UUUNNBGHHHH GONNA EAT JUUUUUU - - if(client) src << "This subject does not have a strong enough life energy anymore..." - else - M.canmove = 1 - - if(client) src << "I have stopped feeding..." - else - if(client) src << "I have stopped feeding..." - - Victim = null - -/mob/living/carbon/slime/proc/Feedstop() - if(Victim) - if(Victim.client) Victim << "[src] has let go of your head!" - Victim = null - -/mob/living/carbon/slime/proc/UpdateFeed(var/mob/M) - if(Victim) - if(Victim == M) - loc = M.loc // simple "attach to head" effect! - - -/mob/living/carbon/slime/verb/Evolve() - set category = "Slime" - set desc = "This will let you evolve from baby to adult slime." - - if(stat) - src << "I must be conscious to do this..." - return - if(!is_adult) - if(amount_grown >= 10) - is_adult = 1 - maxHealth = 200 - amount_grown = 0 - regenerate_icons() - name = text("[colour] [is_adult ? "adult" : "baby"] slime ([number])") - else - src << "I am not ready to evolve yet..." - else - src << "I have already evolved..." - -/mob/living/carbon/slime/verb/Reproduce() - set category = "Slime" - set desc = "This will make you split into four Slimes." - - if(stat) - src << "I must be conscious to do this..." - return - - if(is_adult) - if(amount_grown >= 10) - if(stat) - src << "I must be conscious to do this..." - return - - var/list/babies = list() - var/new_nutrition = round(nutrition * 0.9) - var/new_powerlevel = round(powerlevel / 4) - for(var/i=1,i<=4,i++) - var/mob/living/carbon/slime/M = new /mob/living/carbon/slime/(loc) - if(prob(mutation_chance)) - M.colour = slime_mutation[rand(1,4)] - else - M.colour = colour - if(ckey) M.nutrition = new_nutrition //Player slimes are more robust at spliting. Once an oversight of poor copypasta, now a feature! - M.powerlevel = new_powerlevel - if(i != 1) step_away(M,src) - M.Friends = Friends.Copy() - babies += M - feedback_add_details("slime_babies_born","slimebirth_[replacetext(M.colour," ","_")]") - - var/mob/living/carbon/slime/new_slime = pick(babies) - new_slime.universal_speak = universal_speak - if(src.mind) - src.mind.transfer_to(new_slime) - else - new_slime.key = src.key - qdel(src) - else - src << "I am not ready to reproduce yet..." - else +/mob/living/carbon/slime/verb/Feed() + set category = "Slime" + set desc = "This will let you feed on any valid creature in the surrounding area. This should also be used to halt the feeding process." + if(Victim) + Feedstop() + return + + if(stat) + src << "I must be conscious to do this..." + return + + var/list/choices = list() + for(var/mob/living/C in view(1,src)) + if(C!=src && !istype(C,/mob/living/carbon/slime) && Adjacent(C)) + choices += C + + var/mob/living/M = input(src,"Who do you wish to feed on?") in null|choices + if(!M) return + if(Adjacent(M)) + + if(!istype(src, /mob/living/carbon/brain)) + if(!istype(M, /mob/living/carbon/slime)) + if(stat != 2) + if(health > -70) + + for(var/mob/living/carbon/slime/met in view()) + if(met.Victim == M && met != src) + src << "The [met.name] is already feeding on this subject..." + return + src << "\blue I have latched onto the subject and begun feeding..." + M << "\red The [src.name] has latched onto your head!" + Feedon(M) + + else + src << "This subject does not have a strong enough life energy..." + else + src << "This subject does not have an edible life energy..." + else + src << "I must not feed on my brothers..." + else + src << "This subject does not have an edible life energy..." + + + +/mob/living/carbon/slime/proc/Feedon(var/mob/living/M) + Victim = M + src.loc = M.loc + canmove = 0 + anchored = 1 + var/lastnut = nutrition + var/fed_succesfully = 0 + if(is_adult) + icon_state = "[colour] adult slime eat" + else + icon_state = "[colour] baby slime eat" + + while(Victim && M.health > -70 && M.stat != DEAD && stat != DEAD) + canmove = 0 + + if(Adjacent(M)) + loc = M.loc + + if(prob(15) && M.client && istype(M, /mob/living/carbon)) + M << "[pick("You can feel your body becoming weak!", \ + "You feel like you're about to die!", \ + "You feel every part of your body screaming in agony!", \ + "A low, rolling pain passes through your body!", \ + "Your body feels as if it's falling apart!", \ + "You feel extremely weak!", \ + "A sharp, deep pain bathes every inch of your body!")]" + + if(istype(M, /mob/living/carbon)) + Victim.adjustCloneLoss(rand(5,6)) + Victim.adjustToxLoss(rand(1,2)) + if(Victim.health <= 0) + Victim.adjustToxLoss(rand(2,4)) + + fed_succesfully = 1 + + else if(istype(M, /mob/living/simple_animal)) + Victim.adjustBruteLoss(is_adult ? rand(7, 15) : rand(4, 12)) + fed_succesfully = 1 + + else + if(prob(25)) + src << "[pick("This subject is incompatable", \ + "This subject does not have a life energy", "This subject is empty", \ + "I am not satisified", "I can not feed from this subject", \ + "I do not feel nourished", "This subject is not food")]..." + + if(fed_succesfully) + //I have no idea why this is not in handle_nutrition() + nutrition += rand(15,30) + if(nutrition >= lastnut + 50) + if(prob(80)) + lastnut = nutrition + powerlevel++ + if(powerlevel > 10) + powerlevel = 10 + adjustToxLoss(-10) + + //Heal yourself. + adjustOxyLoss(-10) + adjustBruteLoss(-10) + adjustFireLoss(-10) + adjustCloneLoss(-10) + + updatehealth() + if(Victim) + Victim.updatehealth() + + sleep(rand(15,45)) + + else + break + + if(stat == 2) + if(!is_adult) + icon_state = "[colour] baby slime dead" + + else + if(is_adult) + icon_state = "[colour] adult slime" + else + icon_state = "[colour] baby slime" + + canmove = 1 + anchored = 0 + + if(M) + if(M.health <= -70) + M.canmove = 0 + if(!client) + if(Victim && !rabid && !attacked) + if(Victim.LAssailant && Victim.LAssailant != Victim) + if(prob(50)) + if(!(Victim.LAssailant in Friends)) + Friends[Victim.LAssailant] = 1 + //Friends.Add(Victim.LAssailant) // no idea why i was using the |= operator + else + ++Friends[Victim.LAssailant] + + + if(M.client && istype(src, /mob/living/carbon/human)) + if(prob(85)) + rabid = 1 // UUUNNBGHHHH GONNA EAT JUUUUUU + + if(client) src << "This subject does not have a strong enough life energy anymore..." + else + M.canmove = 1 + + if(client) src << "I have stopped feeding..." + else + if(client) src << "I have stopped feeding..." + + Victim = null + +/mob/living/carbon/slime/proc/Feedstop() + if(Victim) + if(Victim.client) Victim << "[src] has let go of your head!" + Victim = null + +/mob/living/carbon/slime/proc/UpdateFeed(var/mob/M) + if(Victim) + if(Victim == M) + loc = M.loc // simple "attach to head" effect! + + +/mob/living/carbon/slime/verb/Evolve() + set category = "Slime" + set desc = "This will let you evolve from baby to adult slime." + + if(stat) + src << "I must be conscious to do this..." + return + if(!is_adult) + if(amount_grown >= 10) + is_adult = 1 + maxHealth = 200 + amount_grown = 0 + regenerate_icons() + name = text("[colour] [is_adult ? "adult" : "baby"] slime ([number])") + else + src << "I am not ready to evolve yet..." + else + src << "I have already evolved..." + +/mob/living/carbon/slime/verb/Reproduce() + set category = "Slime" + set desc = "This will make you split into four Slimes." + + if(stat) + src << "I must be conscious to do this..." + return + + if(is_adult) + if(amount_grown >= 10) + if(stat) + src << "I must be conscious to do this..." + return + + var/list/babies = list() + var/new_nutrition = round(nutrition * 0.9) + var/new_powerlevel = round(powerlevel / 4) + for(var/i=1,i<=4,i++) + var/mob/living/carbon/slime/M = new /mob/living/carbon/slime/(loc) + if(prob(mutation_chance)) + M.colour = slime_mutation[rand(1,4)] + else + M.colour = colour + if(ckey) M.nutrition = new_nutrition //Player slimes are more robust at spliting. Once an oversight of poor copypasta, now a feature! + M.powerlevel = new_powerlevel + if(i != 1) step_away(M,src) + M.Friends = Friends.Copy() + babies += M + feedback_add_details("slime_babies_born","slimebirth_[replacetext(M.colour," ","_")]") + + var/mob/living/carbon/slime/new_slime = pick(babies) + new_slime.universal_speak = universal_speak + if(src.mind) + src.mind.transfer_to(new_slime) + else + new_slime.key = src.key + qdel(src) + else + src << "I am not ready to reproduce yet..." + else src << "I am not old enough to reproduce yet..." \ No newline at end of file diff --git a/code/modules/mob/living/carbon/metroid/say.dm b/code/modules/mob/living/carbon/slime/say.dm similarity index 100% rename from code/modules/mob/living/carbon/metroid/say.dm rename to code/modules/mob/living/carbon/slime/say.dm diff --git a/code/modules/mob/living/carbon/metroid/metroid.dm b/code/modules/mob/living/carbon/slime/slime.dm similarity index 51% rename from code/modules/mob/living/carbon/metroid/metroid.dm rename to code/modules/mob/living/carbon/slime/slime.dm index 96680de98b8..1e229b853a3 100644 --- a/code/modules/mob/living/carbon/metroid/metroid.dm +++ b/code/modules/mob/living/carbon/slime/slime.dm @@ -1,1004 +1,576 @@ -/mob/living/carbon/slime - name = "baby slime" - icon = 'icons/mob/slimes.dmi' - icon_state = "grey baby slime" - pass_flags = PASSTABLE - ventcrawler = 2 - speak_emote = list("telepathically chirps") - - layer = 5 - - maxHealth = 150 - health = 150 - gender = NEUTER - - update_icon = 0 - nutrition = 700 - - see_in_dark = 8 - update_slimes = 0 - - // canstun and canweaken don't affect slimes because they ignore stun and weakened variables - // for the sake of cleanliness, though, here they are. - status_flags = CANPARALYSE|CANPUSH - - var/cores = 1 // the number of /obj/item/slime_extract's the slime has left inside - var/mutation_chance = 30 // Chance of mutating, should be between 25 and 35 - - var/powerlevel = 0 // 1-10 controls how much electricity they are generating - var/amount_grown = 0 // controls how long the slime has been overfed, if 10, grows or reproduces - - var/number = 0 // Used to understand when someone is talking to it - - var/mob/living/Victim = null // the person the slime is currently feeding on - var/mob/living/Target = null // AI variable - tells the slime to hunt this down - var/mob/living/Leader = null // AI variable - tells the slime to follow this person - - var/attacked = 0 // Determines if it's been attacked recently. Can be any number, is a cooloff-ish variable - var/rabid = 0 // If set to 1, the slime will attack and eat anything it comes in contact with - var/holding_still = 0 // AI variable, cooloff-ish for how long it's going to stay in one place - var/target_patience = 0 // AI variable, cooloff-ish for how long it's going to follow its target - - var/list/Friends = list() // A list of friends; they are not considered targets for feeding; passed down after splitting - - var/list/speech_buffer = list() // Last phrase said near it and person who said it - - var/mood = "" // To show its face - var/is_adult = 0 - - var/core_removal_stage = 0 //For removing cores. - - ///////////TIME FOR SUBSPECIES - - var/colour = "grey" - var/coretype = /obj/item/slime_extract/grey - var/list/slime_mutation[4] - -/mob/living/carbon/slime/New() - create_reagents(100) - spawn (0) - number = rand(1, 1000) - name = "[colour] [is_adult ? "adult" : "baby"] slime ([number])" - icon_state = "[colour] [is_adult ? "adult" : "baby"] slime" - real_name = name - slime_mutation = mutation_table(colour) - mutation_chance = rand(25, 35) - var/sanitizedcolour = replacetext(colour, " ", "") - coretype = text2path("/obj/item/slime_extract/[sanitizedcolour]") - ..() - -/mob/living/carbon/slime/regenerate_icons() - icon_state = "[colour] [is_adult ? "adult" : "baby"] slime" - overlays.len = 0 - if (mood) - overlays += image('icons/mob/slimes.dmi', icon_state = "aslime-[mood]") - ..() - -/mob/living/carbon/slime/movement_delay() - if (bodytemperature >= 330.23) // 135 F - return -1 // slimes become supercharged at high temperatures - - var/tally = 0 - - var/health_deficiency = (100 - health) - if(health_deficiency >= 45) tally += (health_deficiency / 25) - - if (bodytemperature < 183.222) - tally += (283.222 - bodytemperature) / 10 * 1.75 - - if(reagents) - if(reagents.has_reagent("methamphetamine")) // Meth slows slimes down - tally *= 2 - - if(reagents.has_reagent("frostoil")) // Frostoil also makes them move VEEERRYYYYY slow - tally *= 5 - - if(health <= 0) // if damaged, the slime moves twice as slow - tally *= 2 - - return tally + config.slime_delay - -/mob/living/carbon/slime/Bump(atom/movable/AM as mob|obj, yes) - if ((!(yes) || now_pushing)) - return - now_pushing = 1 - - if(isobj(AM)) - if(!client && powerlevel > 0) - var/probab = 10 - switch(powerlevel) - if(1 to 2) probab = 20 - if(3 to 4) probab = 30 - if(5 to 6) probab = 40 - if(7 to 8) probab = 60 - if(9) probab = 70 - if(10) probab = 95 - if(prob(probab)) - if(istype(AM, /obj/structure/window) || istype(AM, /obj/structure/grille)) - if(nutrition <= get_hunger_nutrition() && !Atkcool) - if (is_adult || prob(5)) - AM.attack_slime(src) - spawn() - Atkcool = 1 - sleep(45) - Atkcool = 0 - - if(ismob(AM)) - var/mob/tmob = AM - - if(is_adult) - if(istype(tmob, /mob/living/carbon/human)) - if(prob(90)) - now_pushing = 0 - return - else - if(istype(tmob, /mob/living/carbon/human)) - now_pushing = 0 - return - - now_pushing = 0 - ..() - if (!istype(AM, /atom/movable)) - return - if (!( now_pushing )) - now_pushing = 1 - if (!( AM.anchored )) - var/t = get_dir(src, AM) - if (istype(AM, /obj/structure/window)) - if(AM:ini_dir == NORTHWEST || AM:ini_dir == NORTHEAST || AM:ini_dir == SOUTHWEST || AM:ini_dir == SOUTHEAST) - for(var/obj/structure/window/win in get_step(AM,t)) - now_pushing = 0 - return - step(AM, t) - now_pushing = null - -/mob/living/carbon/slime/Process_Spacemove(var/movement_dir = 0) - return 2 - -/mob/living/carbon/slime/Stat() - ..() - - statpanel("Status") - if(is_adult) - stat(null, "Health: [round((health / 200) * 100)]%") - else - stat(null, "Health: [round((health / 150) * 100)]%") - - if (client.statpanel == "Status") - stat(null, "Nutrition: [nutrition]/[get_max_nutrition()]") - if(amount_grown >= 10) - if(is_adult) - stat(null, "You can reproduce!") - else - stat(null, "You can evolve!") - - stat(null,"Power Level: [powerlevel]") - -/mob/living/carbon/slime/adjustFireLoss(amount) - ..(-abs(amount)) // Heals them - return - -/mob/living/carbon/slime/bullet_act(var/obj/item/projectile/Proj) - attacked += 10 - ..(Proj) - return 0 - -/mob/living/carbon/slime/emp_act(severity) - powerlevel = 0 // oh no, the power! - ..() - -/mob/living/carbon/slime/ex_act(severity) - ..() - - var/b_loss = null - var/f_loss = null - switch (severity) - if (1.0) - qdel(src) - return - - if (2.0) - - b_loss += 60 - f_loss += 60 - - - if(3.0) - b_loss += 30 - - adjustBruteLoss(b_loss) - adjustFireLoss(f_loss) - - updatehealth() - - -/mob/living/carbon/slime/blob_act() - show_message(" The blob attacks you!") - adjustBruteLoss(20) - updatehealth() - return - - -/mob/living/carbon/slime/unEquip(obj/item/W as obj) - return - -/mob/living/carbon/slime/attack_ui(slot) - return - -/mob/living/carbon/slime/attack_slime(mob/living/carbon/slime/M as mob) - if (!ticker) - M << "You cannot attack people before the game has started." - return - - if (Victim) return // can't attack while eating! - - if (health > -100) - - M.do_attack_animation(src) - visible_message(" The [M.name] has glomped [src]!", \ - " The [M.name] has glomped [src]!") - var/damage = rand(1, 3) - attacked += 5 - - if(M.is_adult) - damage = rand(1, 6) - else - damage = rand(1, 3) - - adjustBruteLoss(damage) - - updatehealth() - return - -/mob/living/carbon/slime/attack_animal(mob/living/simple_animal/M as mob) - if(M.melee_damage_upper == 0) - M.custom_emote(1, "[M.friendly] [src]") - else - M.do_attack_animation(src) - if(M.attack_sound) - playsound(loc, M.attack_sound, 50, 1, 1) - visible_message("[M] [M.attacktext] [src]!", \ - "[M] [M.attacktext] [src]!") - M.attack_log += text("\[[time_stamp()]\] attacked [src.name] ([src.ckey])") - src.attack_log += text("\[[time_stamp()]\] was attacked by [M.name] ([M.ckey])") - var/damage = rand(M.melee_damage_lower, M.melee_damage_upper) - attacked += 10 - adjustBruteLoss(damage) - updatehealth() - -/mob/living/carbon/slime/attack_larva(mob/living/carbon/alien/larva/L as mob) - - switch(L.a_intent) - - if(I_HELP) - visible_message("[L] rubs its head against [src].") - - - else - L.do_attack_animation(src) - attacked += 10 - visible_message("[L] bites [src]!", \ - "[L] bites [src]!") - playsound(loc, 'sound/weapons/bite.ogg', 50, 1, -1) - - if(stat != DEAD) - var/damage = rand(1, 3) - L.amount_grown = min(L.amount_grown + damage, L.max_grown) - adjustBruteLoss(damage) - -/mob/living/carbon/slime/attack_hand(mob/living/carbon/human/M as mob) - if (!ticker) - M << "You cannot attack people before the game has started." - return - - if (istype(loc, /turf) && istype(loc.loc, /area/start)) - M << "No attacking people at spawn, you jackass." - return - - ..() - - if(Victim) - if(Victim == M) - if(prob(60)) - visible_message("[M] attempts to wrestle \the [name] off!") - playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1) - - else - visible_message(" [M] manages to wrestle \the [name] off!") - playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) - - if(prob(90) && !client) - Discipline++ - - spawn() - SStun = 1 - sleep(rand(45,60)) - if(src) - SStun = 0 - - Victim = null - anchored = 0 - step_away(src,M) - - return - - else - if(prob(30)) - visible_message("[M] attempts to wrestle \the [name] off of [Victim]!") - playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1) - - else - visible_message(" [M] manages to wrestle \the [name] off of [Victim]!") - playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) - - if(prob(80) && !client) - Discipline++ - - if(!is_adult) - if(Discipline == 1) - attacked = 0 - - spawn() - SStun = 1 - sleep(rand(55,65)) - if(src) - SStun = 0 - - Victim = null - anchored = 0 - step_away(src,M) - - return - -/* - if(M.gloves && istype(M.gloves,/obj/item/clothing/gloves)) - var/obj/item/clothing/gloves/G = M.gloves - if(G.cell) - if(M.a_intent == "hurt")//Stungloves. Any contact will stun the alien. - if(G.cell.charge >= 2500) - G.cell.use(2500) - visible_message("[src] has been touched with the stun gloves by [M]!") - return - else - M << "\red Not enough charge! " - return -*/ - - switch(M.a_intent) - - if (I_HELP) - help_shake_act(M) - - if (I_GRAB) - grabbedby(M) - - else - M.do_attack_animation(src) - var/damage = rand(1, 9) - - attacked += 10 - if (prob(90)) - if (HULK in M.mutations) - damage += 5 - 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) - visible_message("[M] has punched [src]!", \ - "[M] has punched [src]!") - - adjustBruteLoss(damage) - updatehealth() - else - playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1) - visible_message("[M] has attempted to punch [src]!") - return - - - -/mob/living/carbon/slime/attack_alien(mob/living/carbon/alien/humanoid/M as mob) - if (!ticker) - M << "You cannot attack people before the game has started." - return - - if (istype(loc, /turf) && istype(loc.loc, /area/start)) - M << "No attacking people at spawn, you jackass." - return - - switch(M.a_intent) - if (I_HELP) - visible_message("[M] caresses [src] with its scythe like arm.") - - if (I_HARM) - M.do_attack_animation(src) - if (prob(95)) - attacked += 10 - playsound(loc, 'sound/weapons/slice.ogg', 25, 1, -1) - var/damage = rand(15, 30) - if (damage >= 25) - damage = rand(20, 40) - visible_message("[M] has attacked [name]!", \ - "[M] has attacked [name]!") - else - visible_message("[M] has wounded [name]!", \ - ")[M] has wounded [name]!") - adjustBruteLoss(damage) - updatehealth() - else - playsound(loc, 'sound/weapons/slashmiss.ogg', 25, 1, -1) - visible_message("[M] has attempted to lunge at [name]!", \ - "[M] has attempted to lunge at [name]!") - - if (I_GRAB) - grabbedby(M) - - if (I_DISARM) - M.do_attack_animation(src) - playsound(loc, 'sound/weapons/pierce.ogg', 25, 1, -1) - var/damage = 5 - attacked += 10 - - if(prob(95)) - visible_message("[M] has tackled [name]!", \ - "[M] has tackled [name]!") - - if(Victim || Target) - Victim = null - Target = null - anchored = 0 - if(prob(80) && !client) - Discipline++ - if(!istype(src, /mob/living/carbon/slime)) - if(Discipline == 1) - attacked = 0 - - spawn() - SStun = 1 - sleep(rand(5,20)) - SStun = 0 - - spawn(0) - - step_away(src,M,15) - sleep(3) - step_away(src,M,15) - - else - drop_item() - visible_message("[M] has disarmed [name]!", - "[M] has disarmed [name]!") - adjustBruteLoss(damage) - updatehealth() - return - -/mob/living/carbon/slime/attackby(obj/item/W, mob/user, params) - if(istype(W,/obj/item/stack/sheet/mineral/plasma)) //Lets you feed slimes plasma. - if (user in Friends) - ++Friends[user] - else - Friends[user] = 1 - user << "You feed the slime the plasma. It chirps happily." - var/obj/item/stack/sheet/mineral/plasma/S = W - S.use(1) - return - else if(W.force > 0) - attacked += 10 - if(prob(25)) - user << "[W] passes right through [src]!" - return - if(Discipline && prob(50)) // wow, buddy, why am I getting attacked?? - Discipline = 0 - else if(W.force >= 3) - if(is_adult) - if(prob(5 + round(W.force/2))) - if(Victim || Target) - if(prob(80) && !client) - Discipline++ - - Victim = null - Target = null - anchored = 0 - - spawn() - SStun = 1 - sleep(rand(5,20)) - SStun = 0 - - spawn(0) - if(user) - canmove = 0 - step_away(src, user) - if(prob(25 + W.force)) - sleep(2) - if(user) - step_away(src, user) - canmove = 1 - - else - if(prob(10 + W.force*2)) - if(Victim || Target) - if(prob(80) && !client) - Discipline++ - if(Discipline == 1) - attacked = 0 - spawn() - SStun = 1 - sleep(rand(5,20)) - SStun = 0 - - Victim = null - Target = null - anchored = 0 - - spawn(0) - if(user) - canmove = 0 - step_away(src, user) - if(prob(25 + W.force*4)) - sleep(2) - if(user) - step_away(src, user) - canmove = 1 - ..() - -/mob/living/carbon/slime/restrained() - return 0 - -mob/living/carbon/slime/var/temperature_resistance = T0C+75 - -/mob/living/carbon/slime/show_inv(mob/user) - return - -/mob/living/carbon/slime/toggle_throw_mode() - return - -/mob/living/carbon/slime/proc/apply_water() - adjustToxLoss(rand(15,20)) - if (!client) - if (Target) // Like cats - Target = null - ++Discipline - return - -/mob/living/carbon/slime/can_use_vents() - if(Victim) - return "You cannot ventcrawl while feeding." - ..() - -/obj/item/slime_extract - name = "slime extract" - desc = "Goo extracted from a slime. Legends claim these to have \"magical powers\"." - icon = 'icons/mob/slimes.dmi' - icon_state = "grey slime extract" - force = 1.0 - w_class = 1.0 - throwforce = 0 - throw_speed = 3 - throw_range = 6 - origin_tech = "biotech=4" - item_color = "grey" - var/Uses = 1 // uses before it goes inert - var/enhanced = 0 //has it been enhanced before? - - attackby(obj/item/O as obj, mob/user as mob, params) - if(istype(O, /obj/item/weapon/slimesteroid2)) - if(enhanced == 1) - user << " This extract has already been enhanced!" - return ..() - if(Uses == 0) - user << " You can't enhance a used extract!" - return ..() - user <<"You apply the enhancer. It now has triple the amount of uses." - Uses = 3 - enhanced = 1 - qdel(O) - if(istype(O,/obj/item/weapon/storage/bag)) - ..() - -/obj/item/slime_extract/New() - ..() - create_reagents(100) - - -/obj/item/slime_extract/grey - name = "grey slime extract" - icon_state = "grey slime extract" - item_color = "grey" - -/obj/item/slime_extract/gold - name = "gold slime extract" - icon_state = "gold slime extract" - item_color = "gold" - -/obj/item/slime_extract/silver - name = "silver slime extract" - icon_state = "silver slime extract" - item_color = "silver" - -/obj/item/slime_extract/metal - name = "metal slime extract" - icon_state = "metal slime extract" - item_color = "metal" - -/obj/item/slime_extract/purple - name = "purple slime extract" - icon_state = "purple slime extract" - item_color = "purple" - -/obj/item/slime_extract/darkpurple - name = "dark purple slime extract" - icon_state = "dark purple slime extract" - item_color = "darkpurple" - -/obj/item/slime_extract/orange - name = "orange slime extract" - icon_state = "orange slime extract" - item_color = "orange" - -/obj/item/slime_extract/yellow - name = "yellow slime extract" - icon_state = "yellow slime extract" - item_color = "yellow" - -/obj/item/slime_extract/red - name = "red slime extract" - icon_state = "red slime extract" - item_color = "red" - -/obj/item/slime_extract/blue - name = "blue slime extract" - icon_state = "blue slime extract" - item_color = "blue" - -/obj/item/slime_extract/darkblue - name = "dark blue slime extract" - icon_state = "dark blue slime extract" - item_color = "darkblue" - -/obj/item/slime_extract/pink - name = "pink slime extract" - icon_state = "pink slime extract" - item_color = "pink" - -/obj/item/slime_extract/green - name = "green slime extract" - icon_state = "green slime extract" - item_color = "green" - -/obj/item/slime_extract/lightpink - name = "light pink slime extract" - icon_state = "light pink slime extract" - item_color = "lightpink" - -/obj/item/slime_extract/black - name = "black slime extract" - icon_state = "black slime extract" - item_color = "black" - -/obj/item/slime_extract/oil - name = "oil slime extract" - icon_state = "oil slime extract" - item_color = "oil" - -/obj/item/slime_extract/adamantine - name = "adamantine slime extract" - icon_state = "adamantine slime extract" - item_color = "adamantine" - -/obj/item/slime_extract/bluespace - name = "bluespace slime extract" - icon_state = "bluespace slime extract" - -/obj/item/slime_extract/pyrite - name = "pyrite slime extract" - icon_state = "pyrite slime extract" - -/obj/item/slime_extract/cerulean - name = "cerulean slime extract" - icon_state = "cerulean slime extract" - -/obj/item/slime_extract/sepia - name = "sepia slime extract" - icon_state = "sepia slime extract" - -/obj/item/slime_extract/rainbow - name = "rainbow slime extract" - icon_state = "rainbow slime extract" - -////Pet Slime Creation/// - -/obj/item/weapon/slimepotion - name = "docility potion" - desc = "A potent chemical mix that will nullify a slime's powers, causing it to become docile and tame." - icon = 'icons/obj/chemical.dmi' - icon_state = "bottle19" - w_class = 1 - origin_tech = "biotech=4" - - attack(mob/living/carbon/slime/M as mob, mob/user as mob) - if(!istype(M, /mob/living/carbon/slime))//If target is not a slime. - user << " The potion only works on slimes!" - return ..() - if(M.stat) - user << " The slime is dead!" - return..() - if(M.mind) - user << " The slime resists!" - return ..() - if(M.is_adult) - var/mob/living/simple_animal/adultslime/pet = new /mob/living/simple_animal/adultslime(M.loc) - pet.icon_state = "[M.colour] adult slime" - pet.icon_living = "[M.colour] adult slime" - pet.icon_dead = "[M.colour] baby slime dead" - pet.colour = "[M.colour]" - qdel(M) - var/newname = sanitize(copytext(input(user, "Would you like to give the slime a name?", "Name your new pet", "pet slime") as null|text,1,MAX_NAME_LEN)) - - if (!newname) - newname = "pet slime" - pet.name = newname - pet.real_name = newname - qdel(src) - else - var/mob/living/simple_animal/slime/pet = new /mob/living/simple_animal/slime(M.loc) - pet.icon_state = "[M.colour] baby slime" - pet.icon_living = "[M.colour] baby slime" - pet.icon_dead = "[M.colour] baby slime dead" - pet.colour = "[M.colour]" - qdel(M) - var/newname = sanitize(copytext(input(user, "Would you like to give the slime a name?", "Name your new pet", "pet slime") as null|text,1,MAX_NAME_LEN)) - - if (!newname) - newname = "pet slime" - pet.name = newname - pet.real_name = newname - qdel(src) - user <<"You feed the slime the potion, removing it's powers and calming it." - -/obj/item/weapon/sentience_potion - name = "sentience potion" - desc = "A miraculous chemical mix that can raise the intelligence of creatures to human levels. Unlike normal slime potions, it can be absorbed by any nonsentient being." - icon = 'icons/obj/chemical.dmi' - icon_state = "bottle19" - origin_tech = "biotech=5" - var/list/not_interested = list() - var/being_used = 0 - w_class = 1 - - -/obj/item/weapon/sentience_potion/afterattack(mob/living/M, mob/user) - if(being_used || !ismob(M)) - return - if(!isslime(M) && !isanimal(M) || M.ckey) //only works on animals that aren't player controlled - user << "[M] is already too intelligent for this to work!" - return ..() - if(M.stat) - user << "[M] is dead!" - return..() - - user << "You offer the sentience potion to [M]..." - being_used = 1 - - var/list/candidates = get_candidates(ROLE_SENTIENT, ALIEN_AFK_BRACKET) - - shuffle(candidates) - - var/time_passed = world.time - var/list/consenting_candidates = list() - - for(var/candidate in candidates) - - if(candidate in not_interested) - continue - - spawn(0) - switch(alert(candidate, "Would you like to play as [M.name]? Please choose quickly!","Confirmation","Yes","No")) - if("Yes") - if((world.time-time_passed)>=50 || !src) - return - consenting_candidates += candidate - if("No") - if(!src) - return - not_interested += candidate - - sleep(50) - - if(!src) - return - - listclearnulls(consenting_candidates) //some candidates might have left during sleep(50) - - if(consenting_candidates.len) - var/client/C = null - C = pick(consenting_candidates) - M.key = C.key - M.universal_speak = 1 - M.faction |= "sentient" - M << "All at once it makes sense: you know what you are and who you are! Self awareness is yours!" - M << "You are grateful to be self aware and owe [user] a great debt. Serve [user], and assist them in completing their goals at any cost." - user << "[M] accepts the potion and suddenly becomes attentive and aware. It worked!" - if(isanimal(M)) - var/mob/living/simple_animal/S = M - S.master_commander = user - qdel(src) - else - user << "[M] looks interested for a moment, but then looks back down. Maybe you should try again later." - being_used = 0 - ..() - - -/obj/item/weapon/slimesteroid - name = "slime steroid" - desc = "A potent chemical mix that will cause a slime to generate more extract." - icon = 'icons/obj/chemical.dmi' - icon_state = "bottle16" - w_class = 1 - origin_tech = "biotech=4" - - - attack(mob/living/carbon/slime/M as mob, mob/user as mob) - if(!istype(M, /mob/living/carbon/slime))//If target is not a slime. - user << " The steroid only works on baby slimes!" - return ..() - if(M.is_adult) //Can't tame adults - user << " Only baby slimes can use the steroid!" - return..() - if(M.stat) - user << " The slime is dead!" - return..() - if(M.cores == 3) - user <<" The slime already has the maximum amount of extract!" - return..() - - user <<"You feed the slime the steroid. It now has triple the amount of extract." - M.cores = 3 - qdel(src) - -/obj/item/weapon/slimesteroid2 - name = "extract enhancer" - desc = "A potent chemical mix that will give a slime extract three uses." - icon = 'icons/obj/chemical.dmi' - icon_state = "bottle17" - w_class = 1 - origin_tech = "biotech=4" - - -/obj/item/weapon/slimespeed - name = "slime speed potion" - desc = "A potent chemical mix that will remove the slowdown from any item." - icon = 'icons/obj/chemical.dmi' - icon_state = "bottle3" - w_class = 1 - origin_tech = "biotech=4" - -/obj/item/weapon/slimespeed/afterattack(obj/item/C, mob/user) - ..() - if(!istype(C)) - user << "The potion can only be used on items!" - return - if(C.slowdown <= 0) - user << "The [C] can't be made any faster!" - return..() - user <<"You slather the red gunk over the [C], making it faster." - C.color = "#FF0000" - C.slowdown = 0 - qdel(src) - -/obj/item/weapon/slimefireproof - name = "slime chill potion" - desc = "A potent chemical mix that will fireproof any article of clothing. Has three uses." - icon = 'icons/obj/chemical.dmi' - icon_state = "bottle17" - var/uses = 3 - w_class = 1 - origin_tech = "biotech=4" - - -/obj/item/weapon/slimefireproof/afterattack(obj/item/clothing/C, mob/user) - ..() - if(!uses) - qdel(src) - return - if(!istype(C)) - user << "The potion can only be used on clothing!" - return - if(C.max_heat_protection_temperature == FIRE_IMMUNITY_SUIT_MAX_TEMP_PROTECT) - user << "The [C] is already fireproof!" - return..() - user <<"You slather the blue gunk over the [C], fireproofing it." - C.name = "fireproofed [C.name]" - C.color = "#000080" - C.max_heat_protection_temperature = FIRE_IMMUNITY_SUIT_MAX_TEMP_PROTECT - C.heat_protection = C.body_parts_covered - uses -- - if(!uses) - qdel(src) - - -/obj/effect/goleRUNe - anchored = 1 - desc = "a strange rune used to create golems. It glows when spirits are nearby." - name = "rune" - icon = 'icons/obj/rune.dmi' - icon_state = "golem" - unacidable = 1 - layer = TURF_LAYER - var/list/mob/dead/observer/ghosts[0] - - New() - ..() - processing_objects.Add(src) - - process() - if(ghosts.len>0) - icon_state = "golem2" - else - icon_state = "golem" - - attack_hand(mob/living/user as mob) - var/mob/dead/observer/ghost - for(var/mob/dead/observer/O in src.loc) - if(!check_observer(O)) - O << "\red You are not eligible to become a golem." - continue - ghost = O - break - if(!ghost) - user << "The rune fizzles uselessly. There is no spirit nearby." - return - var/mob/living/carbon/human/golem/G = new /mob/living/carbon/human/golem - if(prob(50)) G.gender = "female" - G.loc = src.loc - G.key = ghost.key - G << "You are an adamantine golem. You move slowly, but are highly resistant to heat and cold as well as blunt trauma. You are unable to wear clothes, but can still use most tools. Serve [user], and assist them in completing their goals at any cost." - qdel(src) - - - proc/announce_to_ghosts() - for(var/mob/dead/observer/O in player_list) - if(O.client) - var/area/A = get_area(src) - if(A) - O << "\blue Golem rune created in [A.name]. (Teleport | Sign Up)" - - Topic(href,href_list) - if("signup" in href_list) - var/mob/dead/observer/O = locate(href_list["signup"]) - volunteer(O) - - attack_ghost(var/mob/dead/observer/O) - if(!O) return - volunteer(O) - - proc/check_observer(var/mob/dead/observer/O) - if(!O) - return 0 - if(!O.client) - return 0 - if(O.mind && O.mind.current && O.mind.current.stat != DEAD) - return 0 - if(O.has_enabled_antagHUD == 1 && config.antag_hud_restricted) - return 0 - return 1 - - proc/volunteer(var/mob/dead/observer/O) - if(O in ghosts) - ghosts.Remove(O) - O << "\red You are no longer signed up to be a golem." - else - if(!check_observer(O)) - O << "\red You are not eligible to become a golem." - return - ghosts.Add(O) - O << "\blue You are signed up to be a golem." \ No newline at end of file +/mob/living/carbon/slime + name = "baby slime" + icon = 'icons/mob/slimes.dmi' + icon_state = "grey baby slime" + pass_flags = PASSTABLE + ventcrawler = 2 + speak_emote = list("telepathically chirps") + + layer = 5 + + maxHealth = 150 + health = 150 + gender = NEUTER + + update_icon = 0 + nutrition = 700 + + see_in_dark = 8 + update_slimes = 0 + + // canstun and canweaken don't affect slimes because they ignore stun and weakened variables + // for the sake of cleanliness, though, here they are. + status_flags = CANPARALYSE|CANPUSH + + var/cores = 1 // the number of /obj/item/slime_extract's the slime has left inside + var/mutation_chance = 30 // Chance of mutating, should be between 25 and 35 + + var/powerlevel = 0 // 1-10 controls how much electricity they are generating + var/amount_grown = 0 // controls how long the slime has been overfed, if 10, grows or reproduces + + var/number = 0 // Used to understand when someone is talking to it + + var/mob/living/Victim = null // the person the slime is currently feeding on + var/mob/living/Target = null // AI variable - tells the slime to hunt this down + var/mob/living/Leader = null // AI variable - tells the slime to follow this person + + var/attacked = 0 // Determines if it's been attacked recently. Can be any number, is a cooloff-ish variable + var/rabid = 0 // If set to 1, the slime will attack and eat anything it comes in contact with + var/holding_still = 0 // AI variable, cooloff-ish for how long it's going to stay in one place + var/target_patience = 0 // AI variable, cooloff-ish for how long it's going to follow its target + + var/list/Friends = list() // A list of friends; they are not considered targets for feeding; passed down after splitting + + var/list/speech_buffer = list() // Last phrase said near it and person who said it + + var/mood = "" // To show its face + var/is_adult = 0 + + var/core_removal_stage = 0 //For removing cores. + + ///////////TIME FOR SUBSPECIES + + var/colour = "grey" + var/coretype = /obj/item/slime_extract/grey + var/list/slime_mutation[4] + +/mob/living/carbon/slime/New() + create_reagents(100) + spawn (0) + number = rand(1, 1000) + name = "[colour] [is_adult ? "adult" : "baby"] slime ([number])" + icon_state = "[colour] [is_adult ? "adult" : "baby"] slime" + real_name = name + slime_mutation = mutation_table(colour) + mutation_chance = rand(25, 35) + var/sanitizedcolour = replacetext(colour, " ", "") + coretype = text2path("/obj/item/slime_extract/[sanitizedcolour]") + ..() + +/mob/living/carbon/slime/regenerate_icons() + icon_state = "[colour] [is_adult ? "adult" : "baby"] slime" + overlays.len = 0 + if (mood) + overlays += image('icons/mob/slimes.dmi', icon_state = "aslime-[mood]") + ..() + +/mob/living/carbon/slime/movement_delay() + if (bodytemperature >= 330.23) // 135 F + return -1 // slimes become supercharged at high temperatures + + var/tally = 0 + + var/health_deficiency = (100 - health) + if(health_deficiency >= 45) tally += (health_deficiency / 25) + + if (bodytemperature < 183.222) + tally += (283.222 - bodytemperature) / 10 * 1.75 + + if(reagents) + if(reagents.has_reagent("methamphetamine")) // Meth slows slimes down + tally *= 2 + + if(reagents.has_reagent("frostoil")) // Frostoil also makes them move VEEERRYYYYY slow + tally *= 5 + + if(health <= 0) // if damaged, the slime moves twice as slow + tally *= 2 + + return tally + config.slime_delay + +/mob/living/carbon/slime/Bump(atom/movable/AM as mob|obj, yes) + if ((!(yes) || now_pushing)) + return + now_pushing = 1 + + if(isobj(AM)) + if(!client && powerlevel > 0) + var/probab = 10 + switch(powerlevel) + if(1 to 2) probab = 20 + if(3 to 4) probab = 30 + if(5 to 6) probab = 40 + if(7 to 8) probab = 60 + if(9) probab = 70 + if(10) probab = 95 + if(prob(probab)) + if(istype(AM, /obj/structure/window) || istype(AM, /obj/structure/grille)) + if(nutrition <= get_hunger_nutrition() && !Atkcool) + if (is_adult || prob(5)) + AM.attack_slime(src) + spawn() + Atkcool = 1 + sleep(45) + Atkcool = 0 + + if(ismob(AM)) + var/mob/tmob = AM + + if(is_adult) + if(istype(tmob, /mob/living/carbon/human)) + if(prob(90)) + now_pushing = 0 + return + else + if(istype(tmob, /mob/living/carbon/human)) + now_pushing = 0 + return + + now_pushing = 0 + ..() + if (!istype(AM, /atom/movable)) + return + if (!( now_pushing )) + now_pushing = 1 + if (!( AM.anchored )) + var/t = get_dir(src, AM) + if (istype(AM, /obj/structure/window)) + if(AM:ini_dir == NORTHWEST || AM:ini_dir == NORTHEAST || AM:ini_dir == SOUTHWEST || AM:ini_dir == SOUTHEAST) + for(var/obj/structure/window/win in get_step(AM,t)) + now_pushing = 0 + return + step(AM, t) + now_pushing = null + +/mob/living/carbon/slime/Process_Spacemove(var/movement_dir = 0) + return 2 + +/mob/living/carbon/slime/Stat() + ..() + + statpanel("Status") + if(is_adult) + stat(null, "Health: [round((health / 200) * 100)]%") + else + stat(null, "Health: [round((health / 150) * 100)]%") + + if (client.statpanel == "Status") + stat(null, "Nutrition: [nutrition]/[get_max_nutrition()]") + if(amount_grown >= 10) + if(is_adult) + stat(null, "You can reproduce!") + else + stat(null, "You can evolve!") + + stat(null,"Power Level: [powerlevel]") + +/mob/living/carbon/slime/adjustFireLoss(amount) + ..(-abs(amount)) // Heals them + return + +/mob/living/carbon/slime/bullet_act(var/obj/item/projectile/Proj) + attacked += 10 + ..(Proj) + return 0 + +/mob/living/carbon/slime/emp_act(severity) + powerlevel = 0 // oh no, the power! + ..() + +/mob/living/carbon/slime/ex_act(severity) + ..() + + var/b_loss = null + var/f_loss = null + switch (severity) + if (1.0) + qdel(src) + return + + if (2.0) + + b_loss += 60 + f_loss += 60 + + + if(3.0) + b_loss += 30 + + adjustBruteLoss(b_loss) + adjustFireLoss(f_loss) + + updatehealth() + + +/mob/living/carbon/slime/blob_act() + show_message(" The blob attacks you!") + adjustBruteLoss(20) + updatehealth() + return + + +/mob/living/carbon/slime/unEquip(obj/item/W as obj) + return + +/mob/living/carbon/slime/attack_ui(slot) + return + +/mob/living/carbon/slime/attack_slime(mob/living/carbon/slime/M as mob) + if (!ticker) + M << "You cannot attack people before the game has started." + return + + if (Victim) return // can't attack while eating! + + if (health > -100) + + M.do_attack_animation(src) + visible_message(" The [M.name] has glomped [src]!", \ + " The [M.name] has glomped [src]!") + var/damage = rand(1, 3) + attacked += 5 + + if(M.is_adult) + damage = rand(1, 6) + else + damage = rand(1, 3) + + adjustBruteLoss(damage) + + updatehealth() + return + +/mob/living/carbon/slime/attack_animal(mob/living/simple_animal/M as mob) + if(M.melee_damage_upper == 0) + M.custom_emote(1, "[M.friendly] [src]") + else + M.do_attack_animation(src) + if(M.attack_sound) + playsound(loc, M.attack_sound, 50, 1, 1) + visible_message("[M] [M.attacktext] [src]!", \ + "[M] [M.attacktext] [src]!") + M.attack_log += text("\[[time_stamp()]\] attacked [src.name] ([src.ckey])") + src.attack_log += text("\[[time_stamp()]\] was attacked by [M.name] ([M.ckey])") + var/damage = rand(M.melee_damage_lower, M.melee_damage_upper) + attacked += 10 + adjustBruteLoss(damage) + updatehealth() + +/mob/living/carbon/slime/attack_larva(mob/living/carbon/alien/larva/L as mob) + + switch(L.a_intent) + + if(I_HELP) + visible_message("[L] rubs its head against [src].") + + + else + L.do_attack_animation(src) + attacked += 10 + visible_message("[L] bites [src]!", \ + "[L] bites [src]!") + playsound(loc, 'sound/weapons/bite.ogg', 50, 1, -1) + + if(stat != DEAD) + var/damage = rand(1, 3) + L.amount_grown = min(L.amount_grown + damage, L.max_grown) + adjustBruteLoss(damage) + +/mob/living/carbon/slime/attack_hand(mob/living/carbon/human/M as mob) + if (!ticker) + M << "You cannot attack people before the game has started." + return + + if (istype(loc, /turf) && istype(loc.loc, /area/start)) + M << "No attacking people at spawn, you jackass." + return + + ..() + + if(Victim) + if(Victim == M) + if(prob(60)) + visible_message("[M] attempts to wrestle \the [name] off!") + playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1) + + else + visible_message(" [M] manages to wrestle \the [name] off!") + playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) + + if(prob(90) && !client) + Discipline++ + + spawn() + SStun = 1 + sleep(rand(45,60)) + if(src) + SStun = 0 + + Victim = null + anchored = 0 + step_away(src,M) + + return + + else + if(prob(30)) + visible_message("[M] attempts to wrestle \the [name] off of [Victim]!") + playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1) + + else + visible_message(" [M] manages to wrestle \the [name] off of [Victim]!") + playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) + + if(prob(80) && !client) + Discipline++ + + if(!is_adult) + if(Discipline == 1) + attacked = 0 + + spawn() + SStun = 1 + sleep(rand(55,65)) + if(src) + SStun = 0 + + Victim = null + anchored = 0 + step_away(src,M) + + return + +/* + if(M.gloves && istype(M.gloves,/obj/item/clothing/gloves)) + var/obj/item/clothing/gloves/G = M.gloves + if(G.cell) + if(M.a_intent == "hurt")//Stungloves. Any contact will stun the alien. + if(G.cell.charge >= 2500) + G.cell.use(2500) + visible_message("[src] has been touched with the stun gloves by [M]!") + return + else + M << "\red Not enough charge! " + return +*/ + + switch(M.a_intent) + + if (I_HELP) + help_shake_act(M) + + if (I_GRAB) + grabbedby(M) + + else + M.do_attack_animation(src) + var/damage = rand(1, 9) + + attacked += 10 + if (prob(90)) + if (HULK in M.mutations) + damage += 5 + 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) + visible_message("[M] has punched [src]!", \ + "[M] has punched [src]!") + + adjustBruteLoss(damage) + updatehealth() + else + playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1) + visible_message("[M] has attempted to punch [src]!") + return + + + +/mob/living/carbon/slime/attack_alien(mob/living/carbon/alien/humanoid/M as mob) + if (!ticker) + M << "You cannot attack people before the game has started." + return + + if (istype(loc, /turf) && istype(loc.loc, /area/start)) + M << "No attacking people at spawn, you jackass." + return + + switch(M.a_intent) + if (I_HELP) + visible_message("[M] caresses [src] with its scythe like arm.") + + if (I_HARM) + M.do_attack_animation(src) + if (prob(95)) + attacked += 10 + playsound(loc, 'sound/weapons/slice.ogg', 25, 1, -1) + var/damage = rand(15, 30) + if (damage >= 25) + damage = rand(20, 40) + visible_message("[M] has attacked [name]!", \ + "[M] has attacked [name]!") + else + visible_message("[M] has wounded [name]!", \ + ")[M] has wounded [name]!") + adjustBruteLoss(damage) + updatehealth() + else + playsound(loc, 'sound/weapons/slashmiss.ogg', 25, 1, -1) + visible_message("[M] has attempted to lunge at [name]!", \ + "[M] has attempted to lunge at [name]!") + + if (I_GRAB) + grabbedby(M) + + if (I_DISARM) + M.do_attack_animation(src) + playsound(loc, 'sound/weapons/pierce.ogg', 25, 1, -1) + var/damage = 5 + attacked += 10 + + if(prob(95)) + visible_message("[M] has tackled [name]!", \ + "[M] has tackled [name]!") + + if(Victim || Target) + Victim = null + Target = null + anchored = 0 + if(prob(80) && !client) + Discipline++ + if(!istype(src, /mob/living/carbon/slime)) + if(Discipline == 1) + attacked = 0 + + spawn() + SStun = 1 + sleep(rand(5,20)) + SStun = 0 + + spawn(0) + + step_away(src,M,15) + sleep(3) + step_away(src,M,15) + + else + drop_item() + visible_message("[M] has disarmed [name]!", + "[M] has disarmed [name]!") + adjustBruteLoss(damage) + updatehealth() + return + +/mob/living/carbon/slime/attackby(obj/item/W, mob/user, params) + if(istype(W,/obj/item/stack/sheet/mineral/plasma)) //Lets you feed slimes plasma. + if (user in Friends) + ++Friends[user] + else + Friends[user] = 1 + user << "You feed the slime the plasma. It chirps happily." + var/obj/item/stack/sheet/mineral/plasma/S = W + S.use(1) + return + else if(W.force > 0) + attacked += 10 + if(prob(25)) + user << "[W] passes right through [src]!" + return + if(Discipline && prob(50)) // wow, buddy, why am I getting attacked?? + Discipline = 0 + else if(W.force >= 3) + if(is_adult) + if(prob(5 + round(W.force/2))) + if(Victim || Target) + if(prob(80) && !client) + Discipline++ + + Victim = null + Target = null + anchored = 0 + + spawn() + SStun = 1 + sleep(rand(5,20)) + SStun = 0 + + spawn(0) + if(user) + canmove = 0 + step_away(src, user) + if(prob(25 + W.force)) + sleep(2) + if(user) + step_away(src, user) + canmove = 1 + + else + if(prob(10 + W.force*2)) + if(Victim || Target) + if(prob(80) && !client) + Discipline++ + if(Discipline == 1) + attacked = 0 + spawn() + SStun = 1 + sleep(rand(5,20)) + SStun = 0 + + Victim = null + Target = null + anchored = 0 + + spawn(0) + if(user) + canmove = 0 + step_away(src, user) + if(prob(25 + W.force*4)) + sleep(2) + if(user) + step_away(src, user) + canmove = 1 + ..() + +/mob/living/carbon/slime/restrained() + return 0 + +mob/living/carbon/slime/var/temperature_resistance = T0C+75 + +/mob/living/carbon/slime/show_inv(mob/user) + return + +/mob/living/carbon/slime/toggle_throw_mode() + return + +/mob/living/carbon/slime/proc/apply_water() + adjustToxLoss(rand(15,20)) + if (!client) + if (Target) // Like cats + Target = null + ++Discipline + return + +/mob/living/carbon/slime/can_use_vents() + if(Victim) + return "You cannot ventcrawl while feeding." + ..() \ No newline at end of file diff --git a/code/modules/mob/living/carbon/metroid/subtypes.dm b/code/modules/mob/living/carbon/slime/subtypes.dm similarity index 95% rename from code/modules/mob/living/carbon/metroid/subtypes.dm rename to code/modules/mob/living/carbon/slime/subtypes.dm index 3b7e0107abb..35d38e31a48 100644 --- a/code/modules/mob/living/carbon/metroid/subtypes.dm +++ b/code/modules/mob/living/carbon/slime/subtypes.dm @@ -1,79 +1,79 @@ -proc/mutation_table(var/colour) - var/list/slime_mutation[4] - switch(colour) - //Tier 1 - if("grey") - slime_mutation[1] = "orange" - slime_mutation[2] = "metal" - slime_mutation[3] = "blue" - slime_mutation[4] = "purple" - //Tier 2 - if("purple") - slime_mutation[1] = "dark purple" - slime_mutation[2] = "dark blue" - slime_mutation[3] = "green" - slime_mutation[4] = "green" - if("metal") - slime_mutation[1] = "silver" - slime_mutation[2] = "yellow" - slime_mutation[3] = "gold" - slime_mutation[4] = "gold" - if("orange") - slime_mutation[1] = "dark purple" - slime_mutation[2] = "yellow" - slime_mutation[3] = "red" - slime_mutation[4] = "red" - if("blue") - slime_mutation[1] = "dark blue" - slime_mutation[2] = "silver" - slime_mutation[3] = "pink" - slime_mutation[4] = "pink" - //Tier 3 - if("dark blue") - slime_mutation[1] = "purple" - slime_mutation[2] = "blue" - slime_mutation[3] = "cerulean" - slime_mutation[4] = "cerulean" - if("dark purple") - slime_mutation[1] = "purple" - slime_mutation[2] = "orange" - slime_mutation[3] = "sepia" - slime_mutation[4] = "sepia" - if("yellow") - slime_mutation[1] = "metal" - slime_mutation[2] = "orange" - slime_mutation[3] = "bluespace" - slime_mutation[4] = "bluespace" - if("silver") - slime_mutation[1] = "metal" - slime_mutation[2] = "blue" - slime_mutation[3] = "pyrite" - slime_mutation[4] = "pyrite" - //Tier 4 - if("pink") - slime_mutation[1] = "pink" - slime_mutation[2] = "pink" - slime_mutation[3] = "light pink" - slime_mutation[4] = "light pink" - if("red") - slime_mutation[1] = "red" - slime_mutation[2] = "red" - slime_mutation[3] = "oil" - slime_mutation[4] = "oil" - if("gold") - slime_mutation[1] = "gold" - slime_mutation[2] = "gold" - slime_mutation[3] = "adamantine" - slime_mutation[4] = "adamantine" - if("green") - slime_mutation[1] = "green" - slime_mutation[2] = "green" - slime_mutation[3] = "black" - slime_mutation[4] = "black" - // Tier 5 - else - slime_mutation[1] = colour - slime_mutation[2] = colour - slime_mutation[3] = colour - slime_mutation[4] = colour +proc/mutation_table(var/colour) + var/list/slime_mutation[4] + switch(colour) + //Tier 1 + if("grey") + slime_mutation[1] = "orange" + slime_mutation[2] = "metal" + slime_mutation[3] = "blue" + slime_mutation[4] = "purple" + //Tier 2 + if("purple") + slime_mutation[1] = "dark purple" + slime_mutation[2] = "dark blue" + slime_mutation[3] = "green" + slime_mutation[4] = "green" + if("metal") + slime_mutation[1] = "silver" + slime_mutation[2] = "yellow" + slime_mutation[3] = "gold" + slime_mutation[4] = "gold" + if("orange") + slime_mutation[1] = "dark purple" + slime_mutation[2] = "yellow" + slime_mutation[3] = "red" + slime_mutation[4] = "red" + if("blue") + slime_mutation[1] = "dark blue" + slime_mutation[2] = "silver" + slime_mutation[3] = "pink" + slime_mutation[4] = "pink" + //Tier 3 + if("dark blue") + slime_mutation[1] = "purple" + slime_mutation[2] = "blue" + slime_mutation[3] = "cerulean" + slime_mutation[4] = "cerulean" + if("dark purple") + slime_mutation[1] = "purple" + slime_mutation[2] = "orange" + slime_mutation[3] = "sepia" + slime_mutation[4] = "sepia" + if("yellow") + slime_mutation[1] = "metal" + slime_mutation[2] = "orange" + slime_mutation[3] = "bluespace" + slime_mutation[4] = "bluespace" + if("silver") + slime_mutation[1] = "metal" + slime_mutation[2] = "blue" + slime_mutation[3] = "pyrite" + slime_mutation[4] = "pyrite" + //Tier 4 + if("pink") + slime_mutation[1] = "pink" + slime_mutation[2] = "pink" + slime_mutation[3] = "light pink" + slime_mutation[4] = "light pink" + if("red") + slime_mutation[1] = "red" + slime_mutation[2] = "red" + slime_mutation[3] = "oil" + slime_mutation[4] = "oil" + if("gold") + slime_mutation[1] = "gold" + slime_mutation[2] = "gold" + slime_mutation[3] = "adamantine" + slime_mutation[4] = "adamantine" + if("green") + slime_mutation[1] = "green" + slime_mutation[2] = "green" + slime_mutation[3] = "black" + slime_mutation[4] = "black" + // Tier 5 + else + slime_mutation[1] = colour + slime_mutation[2] = colour + slime_mutation[3] = colour + slime_mutation[4] = colour return(slime_mutation) \ No newline at end of file diff --git a/code/modules/mob/living/carbon/metroid/update_icons.dm b/code/modules/mob/living/carbon/slime/update_icons.dm similarity index 96% rename from code/modules/mob/living/carbon/metroid/update_icons.dm rename to code/modules/mob/living/carbon/slime/update_icons.dm index 8902770055d..2310f32a76e 100644 --- a/code/modules/mob/living/carbon/metroid/update_icons.dm +++ b/code/modules/mob/living/carbon/slime/update_icons.dm @@ -1 +1 @@ -//no special icon processing +//no special icon processing diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm index 214c6dfa3a9..22a41279401 100644 --- a/code/modules/mob/mob_movement.dm +++ b/code/modules/mob/mob_movement.dm @@ -236,7 +236,9 @@ src << "\blue You're pinned to a wall by [mob.pinned[1]]!" return 0 + var/turf/T = mob.loc move_delay = world.time//set move delay + move_delay += T.slowdown mob.last_movement = world.time mob.last_move_intent = world.time + 10 switch(mob.m_intent) @@ -265,7 +267,6 @@ var/mob/M = L[1] if(M) if ((get_dist(mob, M) <= 1 || M.loc == mob.loc)) - var/turf/T = mob.loc . = ..() if (isturf(M.loc)) var/diag = get_dir(mob, M) diff --git a/code/modules/mob/new_player/sprite_accessories.dm b/code/modules/mob/new_player/sprite_accessories.dm index 3043d929555..1a411b55d70 100644 --- a/code/modules/mob/new_player/sprite_accessories.dm +++ b/code/modules/mob/new_player/sprite_accessories.dm @@ -937,6 +937,12 @@ species_allowed = list("Vulpkanin") gender = NEUTER + vulp_vulpine_fluff + name = "Vulpine and Earfluff" + icon_state = "vulp_facial_vulpine_fluff" + species_allowed = list("Vulpkanin") + gender = NEUTER + vulp_mask name = "Mask" icon_state = "vulp_facial_mask" @@ -1589,6 +1595,12 @@ icon_state = "vulp_facial_vulpine" species_allowed = list("Vulpkanin") +/datum/sprite_accessory/head_accessory/vulp_vulpine_fluff + icon = 'icons/mob/human_face.dmi' + name = "Vulpine and Earfluff" + icon_state = "vulp_facial_vulpine_fluff" + species_allowed = list("Vulpkanin") + /datum/sprite_accessory/head_accessory/vulp_mask icon = 'icons/mob/human_face.dmi' name = "Mask" diff --git a/code/modules/paperwork/paper.dm b/code/modules/paperwork/paper.dm index 1cd4d014532..723f4a2147d 100644 --- a/code/modules/paperwork/paper.dm +++ b/code/modules/paperwork/paper.dm @@ -563,11 +563,11 @@ /obj/item/weapon/paper/blueshield name = "paper- 'Blueshield Mission Briefing'" - info = "Blueshield Mission Briefing
You are charged with the defence of any persons of importance within the station. This includes but is not limited to The Captain, The Heads of Staff and Central Command staff. You answer directly to the Head of Security who will assist you in achieving your mission.
Where required to achieve your primary responsibility you should liaise with security and share resources, however the day to day security operations of the station are outside of your jurisdiction.
Monitor the health and safety of your principals, identify any potential risks and threats then alert the proper departments to resolve the situation. You are authorized to act as bodyguard to any of the station heads that you determine are most in need of protection, however additional access to their departments shall be granted solely at their discretion.
Observe the station alert system and carry your armaments only as required by the situation or when authorized by the Head of Security or Captain in exceptional cases.
Remember, as an agent of Nanotrasen it is your responsibility to conduct yourself appropriately and you will be held to the highest standard. You will be held accountable for your actions. Security is authorized to search, interrogate or detain you as required by their own procedures. Internal affairs will also monitor and observe your conduct and their mandate applies equally to security and Blueshield operations." + info = "Blueshield Mission Briefing
You are charged with the defence of any persons of importance within the station. This includes, but is not limited to, The Captain, The Heads of Staff and Central Command staff. You answer directly to the Nanotrasen Representative who will assist you in achieving your mission.
When required to achieve your primary responsibility, you should liaise with security and share resources; however, the day to day security operations of the station are outside of your jurisdiction.
Monitor the health and safety of your principals, identify any potential risks and threats, then alert the proper departments to resolve the situation. You are authorized to act as bodyguard to any of the station heads that you determine are most in need of protection; however, additional access to their departments shall be granted solely at their discretion.
Observe the station alert system and carry your armaments only as required by the situation, or when authorized by the Head of Security or Captain in exceptional cases.
Remember, as an agent of Nanotrasen it is your responsibility to conduct yourself appropriately and you will be held to the highest standard. You will be held accountable for your actions. Security is authorized to search, interrogate or detain you as required by their own procedures. Internal affairs will also monitor and observe your conduct, and their mandate applies equally to security and Blueshield operations." /obj/item/weapon/paper/ntrep name = "paper- 'Nanotrasen Representative Mission Briefing'" - info = "Nanotrasen Representative Mission Briefing

Nanotrasen Central Command has dispatched you to this station in order to liaise with command staff on their behalf. As experienced field officers, the staff on the station are experts in handling their own fields. It is your job however to consider the bigger picture and to direct the staff towards Nanotrasen's corporate interests.
As a civilian, you should consider yourself an advisor, diplomat and intermediary. The command staff do not answer to you directly and are not required to follow your orders nor do you have disciplinary authority over personnel. In all station internal matters you answer to the Head of Personnel who will direct you in your conduct within the station. However you also answer to Central Command who may, as required, direct you in acting on company interests.
Central Command may dispatch orders to the staff through you which you are responsible to communicate, however enforcement of these orders is not your mandate and will be handled directly by Central Command or authorized Nanotrasen personnel. When not specifically directed by Central Command, assist the head of personnel in evaluation of the station and receiving departmental reports.
Your office has been provided with a direct link to Central Command, through which you can issue any urgent reports or requests for Nanotrasen intervention. Remember that any direct intervention is a costly exercise and should be used only when the situation justifies the request. You will be held accountable for any unnecessary usage of Nanotrasen resources.
" + info = "Nanotrasen Representative Mission Briefing

Nanotrasen Central Command has dispatched you to this station in order to liaise with command staff on their behalf. As experienced field officers, the staff on the station are experts in handling their own fields. It is your job, however, to consider the bigger picture and to direct the staff towards Nanotrasen's corporate interests.
As a civilian, you should consider yourself an advisor, diplomat and intermediary. The command staff do not answer to you directly and are not required to follow your orders, nor do you have disciplinary authority over personnel. In all station internal matters you answer to the Head of Personnel who will direct you in your conduct within the station. However, you also answer to Central Command who may, as required, direct you in acting on company interests.
Central Command may dispatch orders to the staff through you which you are responsible to communicate; however, enforcement of these orders is not your mandate and will be handled directly by Central Command or authorized Nanotrasen personnel. When not specifically directed by Central Command, assist the Head of Personnel in evaluation of the station and receiving departmental reports.
Your office has been provided with a direct link to Central Command, through which you can issue any urgent reports or requests for Nanotrasen intervention. Remember that any direct intervention is a costly exercise and should be used only when the situation justifies the request. You will be held accountable for any unnecessary usage of Nanotrasen resources.
" /obj/item/weapon/paper/armory name = "paper- 'Armory Inventory'" diff --git a/code/modules/projectiles/ammunition/ammo_casings.dm b/code/modules/projectiles/ammunition/ammo_casings.dm index 557407ac8a3..9914e0bb87f 100644 --- a/code/modules/projectiles/ammunition/ammo_casings.dm +++ b/code/modules/projectiles/ammunition/ammo_casings.dm @@ -28,17 +28,37 @@ /obj/item/ammo_casing/c9mmap desc = "A 9mm bullet casing." caliber = "9mm" - projectile_type =/obj/item/projectile/bullet/armourpiercing + projectile_type = "/obj/item/projectile/bullet/armourpiercing" /obj/item/ammo_casing/c9mmtox desc = "A 9mm bullet casing." caliber = "9mm" - projectile_type = /obj/item/projectile/bullet/toxinbullet + projectile_type = "/obj/item/projectile/bullet/toxinbullet" /obj/item/ammo_casing/c9mminc desc = "A 9mm bullet casing." caliber = "9mm" - projectile_type = /obj/item/projectile/bullet/incendiary/firebullet + projectile_type = "/obj/item/projectile/bullet/incendiary/firebullet" + +/obj/item/ammo_casing/c46x30mm + desc = "A 4.6x30mm bullet casing." + caliber = "4.6x30mm" + projectile_type = "/obj/item/projectile/bullet/weakbullet3" + +/obj/item/ammo_casing/c46x30mmap + desc = "A 4.6x30mm bullet casing." + caliber = "4.6x30mm" + projectile_type = "/obj/item/projectile/bullet/armourpiercing" + +/obj/item/ammo_casing/c46x30mmtox + desc = "A 4.6x30mm bullet casing." + caliber = "4.6x30mm" + projectile_type = "/obj/item/projectile/bullet/toxinbullet" + +/obj/item/ammo_casing/c46x30mminc + desc = "A 4.6x30mm bullet casing." + caliber = "4.6x30mm" + projectile_type = "/obj/item/projectile/bullet/incendiary/firebullet" /obj/item/ammo_casing/c45 desc = "A .45 bullet casing." @@ -60,7 +80,7 @@ desc = "A 12 gauge buckshot shell." icon_state = "gshell" projectile_type = "/obj/item/projectile/bullet/pellet" - pellets = 5 + pellets = 6 deviation = 30 /obj/item/ammo_casing/shotgun/rubbershot @@ -68,7 +88,7 @@ desc = "A shotgun casing filled with densely-packed rubber balls, used to incapacitate crowds from a distance." icon_state = "bshell" projectile_type = "/obj/item/projectile/bullet/rpellet" - pellets = 5 + pellets = 6 deviation = 30 materials = list(MAT_METAL=4000) @@ -94,7 +114,7 @@ desc = "An extremely weak shotgun shell with multiple small pellets made out of metal shards. This one has been packed with even more \ propellant. It's like playing russian roulette, with a shotgun." icon_state = "improvshell" - projectile_type = /obj/item/projectile/bullet/pellet/random + projectile_type = "/obj/item/projectile/bullet/pellet/random" materials = list(MAT_METAL=250) pellets = 5 deviation = 30 @@ -135,7 +155,7 @@ name = "FRAG-12 slug" desc = "A high explosive breaching round for a 12 gauge shotgun." icon_state = "heshell" - projectile_type = /obj/item/projectile/bullet/frag12 + projectile_type = "/obj/item/projectile/bullet/frag12" /obj/item/ammo_casing/shotgun/incendiary/dragonsbreath name = "dragonsbreath shell" @@ -150,7 +170,7 @@ desc = "An advanced shotgun shell which uses a subspace ansible crystal to produce an effect similar to a standard ion rifle. \ The unique properties of the crystal splot the pulse into a spread of individually weaker bolts." icon_state = "ionshell" - projectile_type = /obj/item/projectile/ion/weak + projectile_type = "/obj/item/projectile/ion/weak" pellets = 4 deviation = 30 @@ -158,7 +178,7 @@ name = "laser slug" desc = "An advanced shotgun shell that uses a micro laser to replicate the effects of a laser weapon in a ballistic package." icon_state = "lshell" - projectile_type = /obj/item/projectile/beam + projectile_type = "/obj/item/projectile/beam" /obj/item/ammo_casing/shotgun/techshell name = "unloaded technological shell" diff --git a/code/modules/projectiles/ammunition/magazines.dm b/code/modules/projectiles/ammunition/magazines.dm index 9ef9938071a..e72a2519230 100644 --- a/code/modules/projectiles/ammunition/magazines.dm +++ b/code/modules/projectiles/ammunition/magazines.dm @@ -49,7 +49,7 @@ desc = "Oh god, this shouldn't be here" ammo_type = "/obj/item/ammo_casing/shotgun/buckshot" caliber = "shotgun" - max_ammo = 8 + max_ammo = 6 multiload = 0 /obj/item/ammo_box/magazine/internal/cylinder/dualshot @@ -116,10 +116,33 @@ ..() icon_state = "[initial(icon_state)]-[ammo_count() ? "8" : "0"]" +/obj/item/ammo_box/magazine/wt550m9 + name = "wt550 magazine (4.6x30mm)" + icon_state = "46x30mmt-20" + ammo_type = "/obj/item/ammo_casing/c46x30mm" + caliber = "4.6x30mm" + max_ammo = 20 + +/obj/item/ammo_box/magazine/wt550m9/update_icon() + ..() + icon_state = "46x30mmt-[round(ammo_count(),4)]" + +/obj/item/ammo_box/magazine/wt550m9/wtap + name = "wt550 magazine (Armour Piercing 4.6x30mm)" + ammo_type = "/obj/item/ammo_casing/c46x30mmap" + +/obj/item/ammo_box/magazine/wt550m9/wttx + name = "wt550 magazine (Toxin Tipped 4.6x30mm)" + ammo_type = "/obj/item/ammo_casing/c46x30mmtox" + +/obj/item/ammo_box/magazine/wt550m9/wtic + name = "wt550 magazine (Incindiary 4.6x30mm)" + ammo_type = "/obj/item/ammo_casing/c46x30mminc" + /obj/item/ammo_box/magazine/uzim9mm name = "uzi magazine (9mm)" icon_state = "uzi9mm-32" - ammo_type = /obj/item/ammo_casing/c9mm + ammo_type = "/obj/item/ammo_casing/c9mm" caliber = "9mm" max_ammo = 32 @@ -137,17 +160,17 @@ /obj/item/ammo_box/magazine/smgm9mm/ap name = "SMG magazine (Armour Piercing 9mm)" - ammo_type = /obj/item/ammo_casing/c9mmap + ammo_type = "/obj/item/ammo_casing/c9mmap" materials = list(MAT_METAL = 3000) /obj/item/ammo_box/magazine/smgm9mm/toxin name = "SMG magazine (Toxin Tipped 9mm)" - ammo_type = /obj/item/ammo_casing/c9mmtox + ammo_type = "/obj/item/ammo_casing/c9mmtox" materials = list(MAT_METAL = 3000) /obj/item/ammo_box/magazine/smgm9mm/fire name = "SMG Magazine (Incendiary 9mm)" - ammo_type = /obj/item/ammo_casing/c9mminc + ammo_type = "/obj/item/ammo_casing/c9mminc" materials = list(MAT_METAL = 3000) /obj/item/ammo_box/magazine/smgm9mm/update_icon() @@ -194,7 +217,7 @@ name = "toploader magazine (5.56mm)" icon_state = "5.56m" origin_tech = "combat=5;syndicate=1" - ammo_type = /obj/item/ammo_casing/a556 + ammo_type = "/obj/item/ammo_casing/a556" caliber = "a556" max_ammo = 30 multiple_sprites = 2 diff --git a/code/modules/projectiles/guns/projectile/automatic.dm b/code/modules/projectiles/guns/projectile/automatic.dm index 2121d3e4cf8..2c3760e2d11 100644 --- a/code/modules/projectiles/guns/projectile/automatic.dm +++ b/code/modules/projectiles/guns/projectile/automatic.dm @@ -6,11 +6,11 @@ can_suppress = 1 burst_size = 3 fire_delay = 2 - action_button_name = "Toggle Firemode" - + action_button_name = "Toggle Firemode" + /obj/item/weapon/gun/projectile/automatic/isHandgun() return 0 - + /obj/item/weapon/gun/projectile/automatic/proto name = "\improper Nanotrasen Saber SMG" desc = "A prototype three-round burst 9mm submachine gun, designated 'SABR'. Has a threaded barrel for suppressors." @@ -49,10 +49,10 @@ A.update_icon() update_icon() return 1 - + /obj/item/weapon/gun/projectile/automatic/ui_action_click() burst_select() - + /obj/item/weapon/gun/projectile/automatic/verb/burst_select() var/mob/living/carbon/human/user = usr select = !select @@ -102,14 +102,30 @@ icon_state = "c20r[magazine ? "-[Ceiling(get_ammo(0)/4)*4]" : ""][chambered ? "" : "-e"][silenced ? "-suppressed" : ""]" return +/obj/item/weapon/gun/projectile/automatic/wt550 + name = "security auto rifle" + desc = "An outdated personal defense weapon utilized by law enforcement. The WT-550 Automatic Rifle fires 4.6x30mm rounds." + icon_state = "wt550" + item_state = "arg" + mag_type = "/obj/item/ammo_box/magazine/wt550m9" + fire_delay = 2 + can_suppress = 0 + burst_size = 1 + action_button_name = null + +/obj/item/weapon/gun/projectile/automatic/wt550/update_icon() + ..() + icon_state = "wt550[magazine ? "-[Ceiling(get_ammo(0)/4)*4]" : ""]" + return + /obj/item/weapon/gun/projectile/automatic/mini_uzi name = "\improper 'Type U3' Uzi" desc = "A lightweight, burst-fire submachine gun, for when you really want someone dead. Uses 9mm rounds." icon_state = "mini-uzi" origin_tech = "combat=5;materials=2;syndicate=8" mag_type = "/obj/item/ammo_box/magazine/uzim9mm" - burst_size = 2 - + burst_size = 2 + /obj/item/weapon/gun/projectile/automatic/l6_saw name = "\improper L6 SAW" desc = "A heavily modified 7.62 light machine gun, designated 'L6 SAW'. Has 'Aussec Armoury - 2531' engraved on the reciever below the designation." @@ -125,7 +141,7 @@ can_suppress = 0 burst_size = 5 fire_delay = 3 - + /obj/item/weapon/gun/projectile/automatic/l6_saw/attack_self(mob/user as mob) cover_open = !cover_open user << "You [cover_open ? "open" : "close"] [src]'s cover." @@ -190,7 +206,7 @@ ..() empty_alarm() return - + /obj/item/weapon/gun/projectile/automatic/m90/attackby(var/obj/item/A, mob/user, params) if(istype(A, /obj/item/ammo_casing)) if(istype(A, text2path(underbarrel.magazine.ammo_type))) @@ -258,4 +274,3 @@ can_suppress = 0 burst_size = 3 fire_delay = 1 - \ No newline at end of file diff --git a/code/modules/projectiles/guns/projectile/shotgun.dm b/code/modules/projectiles/guns/projectile/shotgun.dm index 7c001f0203b..f69b903b3be 100644 --- a/code/modules/projectiles/guns/projectile/shotgun.dm +++ b/code/modules/projectiles/guns/projectile/shotgun.dm @@ -74,16 +74,6 @@ if (chambered) user << "A [chambered.BB ? "live" : "spent"] one is in the chamber." -// COMBAT SHOTGUN // - -/obj/item/weapon/gun/projectile/shotgun/combat - name = "combat shotgun" - desc = "A traditional shotgun with tactical furniture and an eight-shell capacity underneath." - icon_state = "cshotgun" - origin_tech = "combat=5;materials=2" - mag_type = "/obj/item/ammo_box/magazine/internal/shotcom" - w_class = 5 - // RIOT SHOTGUN // /obj/item/weapon/gun/projectile/shotgun/riot //for spawn in the armory @@ -237,7 +227,7 @@ return else sawn_state = SAWN_INTACT - + /obj/item/weapon/gun/projectile/automatic/shotgun/bulldog name = "\improper 'Bulldog' Shotgun" desc = "A compact, mag-fed semi-automatic shotgun for combat in narrow corridors, nicknamed 'Bulldog' by boarding parties. Compatible only with specialized 8-round drum magazines." @@ -273,3 +263,17 @@ ..() empty_alarm() return + +/obj/item/weapon/gun/projectile/shotgun/automatic/Fire(mob/living/user as mob|obj) + ..() + pump(user) + +// COMBAT SHOTGUN // + +/obj/item/weapon/gun/projectile/shotgun/automatic/combat + name = "combat shotgun" + desc = "A semi automatic shotgun with tactical furniture and a six-shell capacity underneath." + icon_state = "cshotgun" + origin_tech = "combat=5;materials=2" + mag_type = "/obj/item/ammo_box/magazine/internal/shotcom" + w_class = 5 \ No newline at end of file diff --git a/code/modules/reagents/Chemistry-Machinery.dm b/code/modules/reagents/Chemistry-Machinery.dm index 0e7199645c9..f9c8dead1b8 100644 --- a/code/modules/reagents/Chemistry-Machinery.dm +++ b/code/modules/reagents/Chemistry-Machinery.dm @@ -14,7 +14,7 @@ var/energy = 100 var/max_energy = 100 var/amount = 30 - var/beaker = null + var/obj/item/weapon/reagent_containers/beaker = null var/recharged = 0 var/hackedcheck = 0 var/list/dispensable_reagents = list("hydrogen","lithium","carbon","nitrogen","oxygen","fluorine", @@ -123,15 +123,15 @@ var beakerContents[0] var beakerCurrentVolume = 0 - if(beaker && beaker:reagents && beaker:reagents.reagent_list.len) - for(var/datum/reagent/R in beaker:reagents.reagent_list) + if(beaker && beaker.reagents && beaker.reagents.reagent_list.len) + for(var/datum/reagent/R in beaker.reagents.reagent_list) beakerContents.Add(list(list("name" = R.name, "id"=R.id, "volume" = R.volume))) // list in a list because Byond merges the first list... beakerCurrentVolume += R.volume data["beakerContents"] = beakerContents if (beaker) data["beakerCurrentVolume"] = beakerCurrentVolume - data["beakerMaxVolume"] = beaker:volume + data["beakerMaxVolume"] = beaker.volume else data["beakerCurrentVolume"] = null data["beakerMaxVolume"] = null @@ -385,7 +385,7 @@ icon_state = "mixer0" use_power = 1 idle_power_usage = 20 - var/beaker = null + var/obj/item/weapon/reagent_containers/beaker = null var/obj/item/weapon/storage/pill_bottle/loaded_pill_bottle = null var/mode = 0 var/condi = 0 @@ -483,7 +483,7 @@ P.info += "Time of analysis: [worldtime2text(world.time)]

" P.info += "Chemical name: [href_list["name"]]
" if(href_list["name"] == "Blood") - var/datum/reagents/R = beaker:reagents + var/datum/reagents/R = beaker.reagents var/datum/reagent/blood/G for(var/datum/reagent/F in R.reagent_list) if(F.name == href_list["name"]) @@ -499,7 +499,7 @@ src.printing = null if(beaker) - var/datum/reagents/R = beaker:reagents + var/datum/reagents/R = beaker.reagents if (href_list["analyze"]) var/dat = "" if(!condi) @@ -562,7 +562,7 @@ return else if (href_list["eject"]) if(beaker) - beaker:loc = src.loc + beaker.forceMove(get_turf(src)) beaker = null reagents.clear_reagents() icon_state = "mixer0" @@ -695,7 +695,7 @@ dat += "No pill bottle inserted.

" dat += "Close" else - var/datum/reagents/R = beaker:reagents + var/datum/reagents/R = beaker.reagents dat += "Eject beaker and Clear Buffer
" if(src.loaded_pill_bottle) dat += "Eject Pill Bottle \[[loaded_pill_bottle.contents.len]/[loaded_pill_bottle.storage_slots]\]

" @@ -759,6 +759,44 @@ name = "\improper CondiMaster 3000" condi = 1 +/obj/machinery/chem_master/constructable + name = "ChemMaster 2999" + desc = "Used to seperate chemicals and distribute them in a variety of forms." + +/obj/machinery/chem_master/constructable/New() + ..() + component_parts = list() + component_parts += new /obj/item/weapon/circuitboard/chem_master(null) + component_parts += new /obj/item/weapon/stock_parts/manipulator(null) + component_parts += new /obj/item/weapon/stock_parts/console_screen(null) + component_parts += new /obj/item/weapon/reagent_containers/glass/beaker(null) + component_parts += new /obj/item/weapon/reagent_containers/glass/beaker(null) + +/obj/machinery/chem_master/constructable/attackby(obj/item/B, mob/user, params) + + if(default_deconstruction_screwdriver(user, "mixer0_nopower", "mixer0", B)) + if(beaker) + beaker.forceMove(get_turf(src)) + beaker = null + reagents.clear_reagents() + if(loaded_pill_bottle) + loaded_pill_bottle.forceMove(get_turf(src)) + loaded_pill_bottle = null + return + + if(exchange_parts(user, B)) + return + + if(panel_open) + if(istype(B, /obj/item/weapon/crowbar)) + default_deconstruction_crowbar(B) + return 1 + else + user << "You can't use the [src.name] while it's panel is opened!" + return 1 + else + ..() + /obj/machinery/reagentgrinder name = "\improper All-In-One Grinder" diff --git a/code/modules/reagents/newchem/medicine.dm b/code/modules/reagents/newchem/medicine.dm index 8d6294b4156..432461bec93 100644 --- a/code/modules/reagents/newchem/medicine.dm +++ b/code/modules/reagents/newchem/medicine.dm @@ -1016,12 +1016,8 @@ datum/reagent/haloperidol/on_mob_life(var/mob/living/M as mob) if (!istype(T)) return src = null if(volume >= 1) - if(T.wet >= 2) //Clears lube! Fight back against the slipping, and WIN! - T.wet = 0 - if(T.wet_overlay) - T.overlays -= T.wet_overlay - T.wet_overlay = null - return + if(istype(T) && T.wet) + T.MakeDry(TURF_WET_LUBE) /datum/reagent/degreaser/on_mob_life(var/mob/living/M as mob) if(!M) M = holder.my_atom diff --git a/code/modules/reagents/oldchem/chemical_reaction/chemical_reaction_misc.dm b/code/modules/reagents/oldchem/chemical_reaction/chemical_reaction_misc.dm index 99f6e60a5e6..7b2cc0615b0 100644 --- a/code/modules/reagents/oldchem/chemical_reaction/chemical_reaction_misc.dm +++ b/code/modules/reagents/oldchem/chemical_reaction/chemical_reaction_misc.dm @@ -196,4 +196,11 @@ result = "lsd" required_reagents = list("diethylamine" = 1, "fungus" = 1) result_amount = 3 - mix_message = "The mixture turns a rather unassuming color and settles." \ No newline at end of file + mix_message = "The mixture turns a rather unassuming color and settles." + + drying_agent + name = "Drying agent" + id = "drying_agent" + result = "drying_agent" + required_reagents = list("plasma" = 2, "ethanol" = 1, "sodium" = 1) + result_amount = 3 \ No newline at end of file diff --git a/code/modules/reagents/oldchem/chemical_reaction/chemical_reaction_slime.dm b/code/modules/reagents/oldchem/chemical_reaction/chemical_reaction_slime.dm index e4726c4779c..4257b1c9be6 100644 --- a/code/modules/reagents/oldchem/chemical_reaction/chemical_reaction_slime.dm +++ b/code/modules/reagents/oldchem/chemical_reaction/chemical_reaction_slime.dm @@ -450,11 +450,25 @@ Z.loc = get_turf(holder.my_atom) Z.announce_to_ghosts() //Bluespace + slimefloor2 + name = "Bluespace Floor" + id = "m_floor2" + result = null + required_reagents = list("blood" = 1) + result_amount = 1 + required_container = /obj/item/slime_extract/bluespace + required_other = 1 + on_reaction(datum/reagents/holder, created_volume) + feedback_add_details("slime_cores_used","[type]") + var/obj/item/stack/tile/bluespace/P = new /obj/item/stack/tile/bluespace + P.amount = 25 + P.loc = get_turf(holder.my_atom) + slimecrystal name = "Slime Crystal" id = "m_crystal" result = null - required_reagents = list("blood" = 1) + required_reagents = list("plasma" = 1) result_amount = 1 required_container = /obj/item/slime_extract/bluespace required_other = 1 @@ -489,20 +503,23 @@ feedback_add_details("slime_cores_used","[replacetext(name," ","_")]") var/obj/item/device/camera/P = new /obj/item/device/camera P.loc = get_turf(holder.my_atom) + var/obj/item/device/camera_film/Z = new /obj/item/device/camera_film + Z.loc = get_turf(holder.my_atom) - - slimefilm - name = "Slime Film" - id = "m_film" + slimefloor + name = "Sepia Floor" + id = "m_floor" result = null required_reagents = list("blood" = 1) result_amount = 1 required_container = /obj/item/slime_extract/sepia required_other = 1 - on_reaction(var/datum/reagents/holder) - feedback_add_details("slime_cores_used","[replacetext(name," ","_")]") - var/obj/item/device/camera_film/P = new /obj/item/device/camera_film + on_reaction(datum/reagents/holder) + feedback_add_details("slime_cores_used","[type]") + var/obj/item/stack/tile/sepia/P = new /obj/item/stack/tile/sepia + P.amount = 25 P.loc = get_turf(holder.my_atom) + //Pyrite slimepaint name = "Slime Paint" diff --git a/code/modules/reagents/oldchem/reagents/reagents_food.dm b/code/modules/reagents/oldchem/reagents/reagents_food.dm index 42c15938f2c..da3244cbda2 100644 --- a/code/modules/reagents/oldchem/reagents/reagents_food.dm +++ b/code/modules/reagents/oldchem/reagents/reagents_food.dm @@ -281,21 +281,7 @@ if (!istype(T)) return src = null if(volume >= 3) - if(T.wet >= 1) return - T.wet = 1 - if(T.wet_overlay) - T.overlays -= T.wet_overlay - T.wet_overlay = null - T.wet_overlay = image('icons/effects/water.dmi',T,"wet_floor") - T.overlays += T.wet_overlay - - spawn(800) - if (!istype(T)) return - if(T.wet >= 2) return - T.wet = 0 - if(T.wet_overlay) - T.overlays -= T.wet_overlay - T.wet_overlay = null + T.MakeSlippery() var/hotspot = (locate(/obj/effect/hotspot) in T) if(hotspot) var/datum/gas_mixture/lowertemp = T.remove_air( T:air:total_moles() ) diff --git a/code/modules/reagents/oldchem/reagents/reagents_water.dm b/code/modules/reagents/oldchem/reagents/reagents_water.dm index 1db18dd1d41..eea7dfad6c4 100644 --- a/code/modules/reagents/oldchem/reagents/reagents_water.dm +++ b/code/modules/reagents/oldchem/reagents/reagents_water.dm @@ -31,21 +31,7 @@ if (!istype(T)) return src = null if(volume >= 3) - if(T.wet >= 1) return - T.wet = 1 - if(T.wet_overlay) - T.overlays -= T.wet_overlay - T.wet_overlay = null - T.wet_overlay = image('icons/effects/water.dmi',T,"wet_floor") - T.overlays += T.wet_overlay - - spawn(800) - if (!istype(T)) return - if(T.wet >= 2) return - T.wet = 0 - if(T.wet_overlay) - T.overlays -= T.wet_overlay - T.wet_overlay = null + T.MakeSlippery() for(var/mob/living/carbon/slime/M in T) M.apply_water() @@ -91,15 +77,7 @@ if (!istype(T)) return src = null if(volume >= 1) - if(T.wet >= 2) return - T.wet = 2 - spawn(800) - if (!istype(T)) return - T.wet = 0 - if(T.wet_overlay) - T.overlays -= T.wet_overlay - T.wet_overlay = null - return + T.MakeSlippery(TURF_WET_LUBE) /datum/reagent/space_cleaner @@ -122,7 +100,6 @@ if(volume >= 1) if(T) T.color = initial(T.color) - T.overlays.Cut() T.clean_blood() for(var/obj/effect/decal/cleanable/C in src) qdel(C) @@ -350,6 +327,23 @@ reagent_state = LIQUID color = "#FFFFD6" // very very light yellow +/datum/reagent/drying_agent + name = "Drying agent" + id = "drying_agent" + description = "Can be used to dry things." + reagent_state = LIQUID + color = "#A70FFF" + +/datum/reagent/drying_agent/reaction_turf(turf/simulated/T, reac_volume) + if(istype(T) && T.wet) + T.MakeDry(TURF_WET_WATER) + +/datum/reagent/drying_agent/reaction_obj(obj/O, reac_volume) + if(istype(O, /obj/item/clothing/shoes/galoshes)) + var/t_loc = get_turf(O) + qdel(O) + new /obj/item/clothing/shoes/galoshes/dry(t_loc) + /* /datum/reagent/vaccine //data must contain virus type diff --git a/code/modules/research/designs/machine_designs.dm b/code/modules/research/designs/machine_designs.dm index 8caa9af8b12..fb97c2b693c 100644 --- a/code/modules/research/designs/machine_designs.dm +++ b/code/modules/research/designs/machine_designs.dm @@ -152,6 +152,16 @@ build_path = /obj/item/weapon/circuitboard/chem_dispenser category = list("Medical Machinery") +/datum/design/chem_master + name = "Machine Design (Chem Master Board)" + desc = "The circuit board for a Chem Master 2999." + id = "chem_master" + req_tech = list("biotech" = 1, "materials" = 2, "programming" = 2) + build_type = IMPRINTER + materials = list(MAT_GLASS = 1000, "sacid" = 20) + build_path = /obj/item/weapon/circuitboard/chem_master + category = list("Medical Machinery") + /datum/design/chem_heater name = "Machine Design (Chemical Heater Board)" desc = "The circuit board for a chemical heater." diff --git a/code/modules/research/designs/weapon_designs.dm b/code/modules/research/designs/weapon_designs.dm index 4a9c5d0b455..01917cb8ba0 100644 --- a/code/modules/research/designs/weapon_designs.dm +++ b/code/modules/research/designs/weapon_designs.dm @@ -167,6 +167,39 @@ materials = list(MAT_METAL = 3000, MAT_GLASS = 200, MAT_URANIUM = 1000) build_path = /obj/item/ammo_box/magazine/smgm9mm/toxin +//WT550 Mags + +/datum/design/mag_oldsmg + name = "WT-550 Auto Gun Magazine (4.6×30mm)" + desc = "A 20 round magazine for the out of date security WT-550 Auto Rifle" + id = "mag_oldsmg" + req_tech = list("combat" = 1, "materials" = 1) + build_type = PROTOLATHE + materials = list(MAT_METAL = 4000) + build_path = /obj/item/ammo_box/magazine/wt550m9 + category = list("Weapons") + +/datum/design/mag_oldsmg/ap_mag + name = "WT-550 Auto Gun Armour Piercing Magazine (4.6×30mm AP)" + desc = "A 20 round armour piercing magazine for the out of date security WT-550 Auto Rifle" + id = "mag_oldsmg_ap" + materials = list(MAT_METAL = 6000, MAT_SILVER = 600) + build_path = /obj/item/ammo_box/magazine/wt550m9/wtap + +/datum/design/mag_oldsmg/ic_mag + name = "WT-550 Auto Gun Incendiary Magazine (4.6×30mm IC)" + desc = "A 20 round armour piercing magazine for the out of date security WT-550 Auto Rifle" + id = "mag_oldsmg_ic" + materials = list(MAT_METAL = 6000, MAT_SILVER = 600, MAT_GLASS = 1000) + build_path = /obj/item/ammo_box/magazine/wt550m9/wtic + +/datum/design/mag_oldsmg/tx_mag + name = "WT-550 Auto Gun Urnaium Magazine (4.6×30mm TX)" + desc = "A 20 round urnaium tipped magazine for the out of date security WT-550 Auto Rifle" + id = "mag_oldsmg_tx" + materials = list(MAT_METAL = 6000, MAT_SILVER = 600, MAT_URANIUM = 2000) + build_path = /obj/item/ammo_box/magazine/wt550m9/wttx + /datum/design/rapidsyringe name = "Rapid Syringe Gun" desc = "A gun that fires many syringes." diff --git a/code/modules/research/xenobiology/xenobiology.dm b/code/modules/research/xenobiology/xenobiology.dm new file mode 100644 index 00000000000..a0df8e2740a --- /dev/null +++ b/code/modules/research/xenobiology/xenobiology.dm @@ -0,0 +1,474 @@ + +/// Slime Extracts /// + +/obj/item/slime_extract + name = "slime extract" + desc = "Goo extracted from a slime. Legends claim these to have \"magical powers\"." + icon = 'icons/mob/slimes.dmi' + icon_state = "grey slime extract" + force = 1.0 + w_class = 1.0 + throwforce = 0 + throw_speed = 3 + throw_range = 6 + origin_tech = "biotech=4" + item_color = "grey" + var/Uses = 1 // uses before it goes inert + var/enhanced = 0 //has it been enhanced before? + + attackby(obj/item/O as obj, mob/user as mob, params) + if(istype(O, /obj/item/weapon/slimesteroid2)) + if(enhanced == 1) + user << " This extract has already been enhanced!" + return ..() + if(Uses == 0) + user << " You can't enhance a used extract!" + return ..() + user <<"You apply the enhancer. It now has triple the amount of uses." + Uses = 3 + enhanced = 1 + qdel(O) + if(istype(O,/obj/item/weapon/storage/bag)) + ..() + +/obj/item/slime_extract/New() + ..() + create_reagents(100) + + +/obj/item/slime_extract/grey + name = "grey slime extract" + icon_state = "grey slime extract" + item_color = "grey" + +/obj/item/slime_extract/gold + name = "gold slime extract" + icon_state = "gold slime extract" + item_color = "gold" + +/obj/item/slime_extract/silver + name = "silver slime extract" + icon_state = "silver slime extract" + item_color = "silver" + +/obj/item/slime_extract/metal + name = "metal slime extract" + icon_state = "metal slime extract" + item_color = "metal" + +/obj/item/slime_extract/purple + name = "purple slime extract" + icon_state = "purple slime extract" + item_color = "purple" + +/obj/item/slime_extract/darkpurple + name = "dark purple slime extract" + icon_state = "dark purple slime extract" + item_color = "darkpurple" + +/obj/item/slime_extract/orange + name = "orange slime extract" + icon_state = "orange slime extract" + item_color = "orange" + +/obj/item/slime_extract/yellow + name = "yellow slime extract" + icon_state = "yellow slime extract" + item_color = "yellow" + +/obj/item/slime_extract/red + name = "red slime extract" + icon_state = "red slime extract" + item_color = "red" + +/obj/item/slime_extract/blue + name = "blue slime extract" + icon_state = "blue slime extract" + item_color = "blue" + +/obj/item/slime_extract/darkblue + name = "dark blue slime extract" + icon_state = "dark blue slime extract" + item_color = "darkblue" + +/obj/item/slime_extract/pink + name = "pink slime extract" + icon_state = "pink slime extract" + item_color = "pink" + +/obj/item/slime_extract/green + name = "green slime extract" + icon_state = "green slime extract" + item_color = "green" + +/obj/item/slime_extract/lightpink + name = "light pink slime extract" + icon_state = "light pink slime extract" + item_color = "lightpink" + +/obj/item/slime_extract/black + name = "black slime extract" + icon_state = "black slime extract" + item_color = "black" + +/obj/item/slime_extract/oil + name = "oil slime extract" + icon_state = "oil slime extract" + item_color = "oil" + +/obj/item/slime_extract/adamantine + name = "adamantine slime extract" + icon_state = "adamantine slime extract" + item_color = "adamantine" + +/obj/item/slime_extract/bluespace + name = "bluespace slime extract" + icon_state = "bluespace slime extract" + +/obj/item/slime_extract/pyrite + name = "pyrite slime extract" + icon_state = "pyrite slime extract" + +/obj/item/slime_extract/cerulean + name = "cerulean slime extract" + icon_state = "cerulean slime extract" + +/obj/item/slime_extract/sepia + name = "sepia slime extract" + icon_state = "sepia slime extract" + +/obj/item/slime_extract/rainbow + name = "rainbow slime extract" + icon_state = "rainbow slime extract" + +////Pet Slime Creation/// + +/obj/item/weapon/slimepotion + name = "docility potion" + desc = "A potent chemical mix that will nullify a slime's powers, causing it to become docile and tame." + icon = 'icons/obj/chemical.dmi' + icon_state = "bottle19" + w_class = 1 + origin_tech = "biotech=4" + + attack(mob/living/carbon/slime/M as mob, mob/user as mob) + if(!istype(M, /mob/living/carbon/slime))//If target is not a slime. + user << " The potion only works on slimes!" + return ..() + if(M.stat) + user << " The slime is dead!" + return..() + if(M.mind) + user << " The slime resists!" + return ..() + if(M.is_adult) + var/mob/living/simple_animal/adultslime/pet = new /mob/living/simple_animal/adultslime(M.loc) + pet.icon_state = "[M.colour] adult slime" + pet.icon_living = "[M.colour] adult slime" + pet.icon_dead = "[M.colour] baby slime dead" + pet.colour = "[M.colour]" + qdel(M) + var/newname = sanitize(copytext(input(user, "Would you like to give the slime a name?", "Name your new pet", "pet slime") as null|text,1,MAX_NAME_LEN)) + + if (!newname) + newname = "pet slime" + pet.name = newname + pet.real_name = newname + qdel(src) + else + var/mob/living/simple_animal/slime/pet = new /mob/living/simple_animal/slime(M.loc) + pet.icon_state = "[M.colour] baby slime" + pet.icon_living = "[M.colour] baby slime" + pet.icon_dead = "[M.colour] baby slime dead" + pet.colour = "[M.colour]" + qdel(M) + var/newname = sanitize(copytext(input(user, "Would you like to give the slime a name?", "Name your new pet", "pet slime") as null|text,1,MAX_NAME_LEN)) + + if (!newname) + newname = "pet slime" + pet.name = newname + pet.real_name = newname + qdel(src) + user <<"You feed the slime the potion, removing it's powers and calming it." + +/obj/item/weapon/sentience_potion + name = "sentience potion" + desc = "A miraculous chemical mix that can raise the intelligence of creatures to human levels. Unlike normal slime potions, it can be absorbed by any nonsentient being." + icon = 'icons/obj/chemical.dmi' + icon_state = "bottle19" + origin_tech = "biotech=5" + var/list/not_interested = list() + var/being_used = 0 + w_class = 1 + + +/obj/item/weapon/sentience_potion/afterattack(mob/living/M, mob/user) + if(being_used || !ismob(M)) + return + if(!isslime(M) && !isanimal(M) || M.ckey) //only works on animals that aren't player controlled + user << "[M] is already too intelligent for this to work!" + return ..() + if(M.stat) + user << "[M] is dead!" + return..() + + user << "You offer the sentience potion to [M]..." + being_used = 1 + + var/list/candidates = get_candidates(ROLE_SENTIENT, ALIEN_AFK_BRACKET) + + shuffle(candidates) + + var/time_passed = world.time + var/list/consenting_candidates = list() + + for(var/candidate in candidates) + + if(candidate in not_interested) + continue + + spawn(0) + switch(alert(candidate, "Would you like to play as [M.name]? Please choose quickly!","Confirmation","Yes","No")) + if("Yes") + if((world.time-time_passed)>=50 || !src) + return + consenting_candidates += candidate + if("No") + if(!src) + return + not_interested += candidate + + sleep(50) + + if(!src) + return + + listclearnulls(consenting_candidates) //some candidates might have left during sleep(50) + + if(consenting_candidates.len) + var/client/C = null + C = pick(consenting_candidates) + M.key = C.key + M.universal_speak = 1 + M.faction |= "sentient" + M << "All at once it makes sense: you know what you are and who you are! Self awareness is yours!" + M << "You are grateful to be self aware and owe [user] a great debt. Serve [user], and assist them in completing their goals at any cost." + user << "[M] accepts the potion and suddenly becomes attentive and aware. It worked!" + if(isanimal(M)) + var/mob/living/simple_animal/S = M + S.master_commander = user + qdel(src) + else + user << "[M] looks interested for a moment, but then looks back down. Maybe you should try again later." + being_used = 0 + ..() + + +/obj/item/weapon/slimesteroid + name = "slime steroid" + desc = "A potent chemical mix that will cause a slime to generate more extract." + icon = 'icons/obj/chemical.dmi' + icon_state = "bottle16" + w_class = 1 + origin_tech = "biotech=4" + + + attack(mob/living/carbon/slime/M as mob, mob/user as mob) + if(!istype(M, /mob/living/carbon/slime))//If target is not a slime. + user << " The steroid only works on baby slimes!" + return ..() + if(M.is_adult) //Can't tame adults + user << " Only baby slimes can use the steroid!" + return..() + if(M.stat) + user << " The slime is dead!" + return..() + if(M.cores == 3) + user <<" The slime already has the maximum amount of extract!" + return..() + + user <<"You feed the slime the steroid. It now has triple the amount of extract." + M.cores = 3 + qdel(src) + +/obj/item/weapon/slimesteroid2 + name = "extract enhancer" + desc = "A potent chemical mix that will give a slime extract three uses." + icon = 'icons/obj/chemical.dmi' + icon_state = "bottle17" + w_class = 1 + origin_tech = "biotech=4" + + +/obj/item/weapon/slimespeed + name = "slime speed potion" + desc = "A potent chemical mix that will remove the slowdown from any item." + icon = 'icons/obj/chemical.dmi' + icon_state = "bottle3" + w_class = 1 + origin_tech = "biotech=4" + +/obj/item/weapon/slimespeed/afterattack(obj/item/C, mob/user) + ..() + if(!istype(C)) + user << "The potion can only be used on items!" + return + if(C.slowdown <= 0) + user << "The [C] can't be made any faster!" + return..() + user <<"You slather the red gunk over the [C], making it faster." + C.color = "#FF0000" + C.slowdown = 0 + qdel(src) + +/obj/item/weapon/slimefireproof + name = "slime chill potion" + desc = "A potent chemical mix that will fireproof any article of clothing. Has three uses." + icon = 'icons/obj/chemical.dmi' + icon_state = "bottle17" + var/uses = 3 + w_class = 1 + origin_tech = "biotech=4" + + +/obj/item/weapon/slimefireproof/afterattack(obj/item/clothing/C, mob/user) + ..() + if(!uses) + qdel(src) + return + if(!istype(C)) + user << "The potion can only be used on clothing!" + return + if(C.max_heat_protection_temperature == FIRE_IMMUNITY_SUIT_MAX_TEMP_PROTECT) + user << "The [C] is already fireproof!" + return..() + user <<"You slather the blue gunk over the [C], fireproofing it." + C.name = "fireproofed [C.name]" + C.color = "#000080" + C.max_heat_protection_temperature = FIRE_IMMUNITY_SUIT_MAX_TEMP_PROTECT + C.heat_protection = C.body_parts_covered + uses -- + if(!uses) + qdel(src) + +/obj/item/stack/tile/bluespace + name = "bluespace floor tile" + singular_name = "floor tile" + desc = "Through a series of micro-teleports, these tiles let people move at incredible speeds." + icon_state = "tile-bluespace" + w_class = 3 + force = 6 + materials = list(MAT_METAL=500) + throwforce = 10 + throw_speed = 3 + throw_range = 7 + flags = CONDUCT + max_amount = 60 + turf_type = /turf/simulated/floor/bluespace + + +/turf/simulated/floor/bluespace + slowdown = -1 + icon_state = "bluespace" + desc = "Through a series of micro-teleports, these tiles let people move at incredible speeds." + floor_tile = /obj/item/stack/tile/bluespace + + +/obj/item/stack/tile/sepia + name = "sepia floor tile" + singular_name = "floor tile" + desc = "Time seems to flow very slowly around these tiles." + icon_state = "tile-sepia" + w_class = 3 + force = 6 + materials = list(MAT_METAL=500) + throwforce = 10 + throw_speed = 3 + throw_range = 7 + flags = CONDUCT + max_amount = 60 + turf_type = /turf/simulated/floor/sepia + + +/turf/simulated/floor/sepia + slowdown = 2 + icon_state = "sepia" + desc = "Time seems to flow very slowly around these tiles." + floor_tile = /obj/item/stack/tile/sepia + +/obj/effect/goleRUNe + anchored = 1 + desc = "a strange rune used to create golems. It glows when spirits are nearby." + name = "rune" + icon = 'icons/obj/rune.dmi' + icon_state = "golem" + unacidable = 1 + layer = TURF_LAYER + var/list/mob/dead/observer/ghosts[0] + + New() + ..() + processing_objects.Add(src) + + process() + if(ghosts.len>0) + icon_state = "golem2" + else + icon_state = "golem" + + attack_hand(mob/living/user as mob) + var/mob/dead/observer/ghost + for(var/mob/dead/observer/O in src.loc) + if(!check_observer(O)) + O << "\red You are not eligible to become a golem." + continue + ghost = O + break + if(!ghost) + user << "The rune fizzles uselessly. There is no spirit nearby." + return + var/mob/living/carbon/human/golem/G = new /mob/living/carbon/human/golem + if(prob(50)) G.gender = "female" + G.loc = src.loc + G.key = ghost.key + G << "You are an adamantine golem. You move slowly, but are highly resistant to heat and cold as well as blunt trauma. You are unable to wear clothes, but can still use most tools. Serve [user], and assist them in completing their goals at any cost." + qdel(src) + + + proc/announce_to_ghosts() + for(var/mob/dead/observer/O in player_list) + if(O.client) + var/area/A = get_area(src) + if(A) + O << "\blue Golem rune created in [A.name]. (Teleport | Sign Up)" + + Topic(href,href_list) + if("signup" in href_list) + var/mob/dead/observer/O = locate(href_list["signup"]) + volunteer(O) + + attack_ghost(var/mob/dead/observer/O) + if(!O) return + volunteer(O) + + proc/check_observer(var/mob/dead/observer/O) + if(!O) + return 0 + if(!O.client) + return 0 + if(O.mind && O.mind.current && O.mind.current.stat != DEAD) + return 0 + if(O.has_enabled_antagHUD == 1 && config.antag_hud_restricted) + return 0 + return 1 + + proc/volunteer(var/mob/dead/observer/O) + if(O in ghosts) + ghosts.Remove(O) + O << "\red You are no longer signed up to be a golem." + else + if(!check_observer(O)) + O << "\red You are not eligible to become a golem." + return + ghosts.Add(O) + O << "\blue You are signed up to be a golem." \ No newline at end of file diff --git a/code/modules/virus2/effect.dm b/code/modules/virus2/effect.dm index eca8911f6ad..ef21731868d 100644 --- a/code/modules/virus2/effect.dm +++ b/code/modules/virus2/effect.dm @@ -556,19 +556,8 @@ if(istype(mob.loc,/turf/simulated)) var/turf/simulated/T = mob.loc - if(T.wet < 1) - T.wet = 1 - if(T.wet_overlay) - T.overlays -= T.wet_overlay - T.wet_overlay = null - T.wet_overlay = image('icons/effects/water.dmi',T,"wet_floor") - T.overlays += T.wet_overlay - spawn(800) - if (istype(T) && T.wet < 2) - T.wet = 0 - if(T.wet_overlay) - T.overlays -= T.wet_overlay - T.wet_overlay = null + if(T.wet < TURF_WET_WATER) + T.MakeSlippery() diff --git a/html/changelogs/Certhic-PR-3122.yml b/html/changelogs/Certhic-PR-3122.yml new file mode 100644 index 00000000000..2259255f75f --- /dev/null +++ b/html/changelogs/Certhic-PR-3122.yml @@ -0,0 +1,6 @@ +author: Certhic + +delete-after: True + +changes: + - bugfix: "Corrected some air alarms so that atmos computer can access them" diff --git a/html/changelogs/Tastyfish-PR-3120.yml b/html/changelogs/Tastyfish-PR-3120.yml new file mode 100644 index 00000000000..e5b28e0d983 --- /dev/null +++ b/html/changelogs/Tastyfish-PR-3120.yml @@ -0,0 +1,35 @@ +################################ +# Example Changelog File +# +# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb. +# +# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.) +# When it is, any changes listed below will disappear. +# +# Valid Prefixes: +# bugfix +# wip (For works in progress) +# tweak +# soundadd +# sounddel +# rscadd (general adding of nice things) +# rscdel (general deleting of nice things) +# imageadd +# imagedel +# spellcheck (typo fixes) +# experiment +################################# + +# Your name. Remove the quotation mark and put in your name when copy+pasting the example changelog. +author: Tastyfish + +# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again. +delete-after: True + +# Any changes you've made. See valid prefix list above. +# INDENT WITH TWO SPACES. NOT TABS. SPACES. +# SCREW THIS UP AND IT WON'T WORK. +# Also, this gets changed to [] after reading. Just remove the brackets when you add new shit. +# Please surround your changes in double quotes ("). It works without them, but if you use certain characters it screws up compiling. The quotes will not show up in the changelog. +changes: + - tweak: "Instruments now use NanoUI." \ No newline at end of file diff --git a/html/changelogs/Tastyfish-PR-3132.yml b/html/changelogs/Tastyfish-PR-3132.yml new file mode 100644 index 00000000000..88e27ab1992 --- /dev/null +++ b/html/changelogs/Tastyfish-PR-3132.yml @@ -0,0 +1,35 @@ +################################ +# Example Changelog File +# +# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb. +# +# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.) +# When it is, any changes listed below will disappear. +# +# Valid Prefixes: +# bugfix +# wip (For works in progress) +# tweak +# soundadd +# sounddel +# rscadd (general adding of nice things) +# rscdel (general deleting of nice things) +# imageadd +# imagedel +# spellcheck (typo fixes) +# experiment +################################# + +# Your name. Remove the quotation mark and put in your name when copy+pasting the example changelog. +author: Tastyfish + +# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again. +delete-after: True + +# Any changes you've made. See valid prefix list above. +# INDENT WITH TWO SPACES. NOT TABS. SPACES. +# SCREW THIS UP AND IT WON'T WORK. +# Also, this gets changed to [] after reading. Just remove the brackets when you add new shit. +# Please surround your changes in double quotes ("). It works without them, but if you use certain characters it screws up compiling. The quotes will not show up in the changelog. +changes: + - spellcheck: "Corrected the blueshield mission briefing." diff --git a/icons/effects/species.dmi b/icons/effects/species.dmi index 5db54c96885..e339fbbdce1 100644 Binary files a/icons/effects/species.dmi and b/icons/effects/species.dmi differ diff --git a/icons/effects/water.dmi b/icons/effects/water.dmi index 10e698a34ca..1bccfad7773 100644 Binary files a/icons/effects/water.dmi and b/icons/effects/water.dmi differ diff --git a/icons/mob/feet.dmi b/icons/mob/feet.dmi index 20dc03cbabb..b9cccb43949 100644 Binary files a/icons/mob/feet.dmi and b/icons/mob/feet.dmi differ diff --git a/icons/mob/human_face.dmi b/icons/mob/human_face.dmi index 34f7669cc85..ffecceda82e 100644 Binary files a/icons/mob/human_face.dmi and b/icons/mob/human_face.dmi differ diff --git a/icons/mob/human_races/r_def_vox.dmi b/icons/mob/human_races/r_def_vox.dmi index 5bf9cd8acce..a839aefb4d9 100644 Binary files a/icons/mob/human_races/r_def_vox.dmi and b/icons/mob/human_races/r_def_vox.dmi differ diff --git a/icons/mob/human_races/r_vox.dmi b/icons/mob/human_races/r_vox.dmi index 5bf9cd8acce..a839aefb4d9 100644 Binary files a/icons/mob/human_races/r_vox.dmi and b/icons/mob/human_races/r_vox.dmi differ diff --git a/icons/obj/ammo.dmi b/icons/obj/ammo.dmi index add4c667b0b..5e43710ed5f 100644 Binary files a/icons/obj/ammo.dmi and b/icons/obj/ammo.dmi differ diff --git a/icons/obj/clothing/shoes.dmi b/icons/obj/clothing/shoes.dmi index 36ec05a86f9..cab7cc16e7c 100644 Binary files a/icons/obj/clothing/shoes.dmi and b/icons/obj/clothing/shoes.dmi differ diff --git a/icons/obj/gun.dmi b/icons/obj/gun.dmi index 15ea68c087a..0ceb1f7d7f0 100644 Binary files a/icons/obj/gun.dmi and b/icons/obj/gun.dmi differ diff --git a/icons/obj/items.dmi b/icons/obj/items.dmi index 6ef95efd7e8..a5af5cd486d 100644 Binary files a/icons/obj/items.dmi and b/icons/obj/items.dmi differ diff --git a/icons/turf/floors.dmi b/icons/turf/floors.dmi index b3ce39511b5..18dd60eb768 100644 Binary files a/icons/turf/floors.dmi and b/icons/turf/floors.dmi differ diff --git a/nano/templates/song.tmpl b/nano/templates/song.tmpl new file mode 100644 index 00000000000..43ab61b75ef --- /dev/null +++ b/nano/templates/song.tmpl @@ -0,0 +1,89 @@ + + +
+
+
Playback
+
+ {{:helper.link('New', 'document', {'newsong': 1})}} + {{:helper.link('Import', 'folder-open', {'import': 1})}} + {{:helper.link('Play', 'play', {'play': 1}, data.lines.length > 0 ? (data.playing ? 'selected' : null) : 'disabled')}} + {{:helper.link('Stop', 'stop', {'stop': 1}, !data.playing ? 'selected' : null)}} +
+
+
+
Repeat Song:
+ {{:helper.link('-', null, {'repeat' : -10}, data.repeat > 0 && !data.playing ? null : 'disabled')}} + {{:helper.link('-', null, {'repeat' : -1}, data.repeat > 0 && !data.playing ? null : 'disabled')}} + {{:data.repeat}} + {{:helper.link('+', null, {'repeat' : 1}, data.repeat < data.maxRepeat && !data.playing ? null : 'disabled')}} + {{:helper.link('+', null, {'repeat' : 10}, data.repeat < data.maxRepeat && !data.playing ? null : 'disabled')}} +
+
+
Tempo:
+ {{:helper.link('-', null, {'tempo' : 10}, data.tempo < data.maxTempo ? null : 'disabled')}} + {{:helper.link('-', null, {'tempo' : 1}, data.tempo < data.maxTempo ? null : 'disabled')}} + {{:helper.round(600 / data.tempo)}} BPM + {{:helper.link('+', null, {'tempo' : -1}, data.tempo > data.minTempo ? null : 'disabled')}} + {{:helper.link('+', null, {'tempo' : -10}, data.tempo > data.minTempo ? null : 'disabled')}} +
+
+ +

Editor

+
+ {{for data.lines}} +
+
{{:index + 1}}: 
+
+ {{:helper.link('Edit', 'pencil', {'modifyline': index+1}, data.playing ? 'disabled' : null)}} + {{:helper.link('Insert', 'arrowreturn-1-n', {'insertline': index+1}, data.playing ? 'disabled' : null)}} + {{:helper.link('Delete', 'trash', {'deleteline': index+1}, data.playing ? 'disabled' : null)}} +
+
{{:value}}
+
+ {{/for}} +
+
+ {{:helper.link('Add Line', 'arrowreturn-1-s', {'insertline': data.lines.length + 1}, data.playing ? 'disabled' : null)}} +
+
+
+ +
+
+ {{:helper.link('Help', data.help ? 'close' : 'help', {'help': 1})}} +
+
+ {{if data.help}} +

+ Lines are a series of chords, separated by commas (,), each with notes seperated by hyphens (-). +
+ Every note in a chord will play together, with the chord timed by the tempo as defined above. +

+

+ Notes are played by the names of the note, and optionally, the accidental, and/or the octave number. +
+ By default, every note is natural and in octave 3. Defining a different state for either is remembered for each note. +

+

+

+ Chords can be played simply by seperating each note with a hyphon: A-C#,Cn-E,E-G#,Gn-B.
+ A pause may be denoted by an empty chord: C,E,,C,G. +
+ To make a chord be a different time, end it with /x, where the chord length will be length defined by tempo / x, eg: C,G/2,E/4. +

+

+ Combined, an example line is: E-E4/4,F#/2,G#/8,B/8,E3-E4/4. +

+

+ {{/if}} +
+
\ No newline at end of file diff --git a/paradise.dme b/paradise.dme index ddc9a9720dd..1ed8a8ef17d 100644 --- a/paradise.dme +++ b/paradise.dme @@ -690,7 +690,6 @@ #include "code\game\objects\items\stacks\sheets\mineral.dm" #include "code\game\objects\items\stacks\sheets\sheet_types.dm" #include "code\game\objects\items\stacks\sheets\sheets.dm" -#include "code\game\objects\items\stacks\tiles\light.dm" #include "code\game\objects\items\stacks\tiles\tile_types.dm" #include "code\game\objects\items\weapons\AI_modules.dm" #include "code\game\objects\items\weapons\alien_specific.dm" @@ -1380,16 +1379,16 @@ #include "code\modules\mob\living\carbon\human\species\shadow.dm" #include "code\modules\mob\living\carbon\human\species\species.dm" #include "code\modules\mob\living\carbon\human\species\station.dm" -#include "code\modules\mob\living\carbon\metroid\death.dm" -#include "code\modules\mob\living\carbon\metroid\emote.dm" -#include "code\modules\mob\living\carbon\metroid\examine.dm" -#include "code\modules\mob\living\carbon\metroid\life.dm" -#include "code\modules\mob\living\carbon\metroid\login.dm" -#include "code\modules\mob\living\carbon\metroid\metroid.dm" -#include "code\modules\mob\living\carbon\metroid\powers.dm" -#include "code\modules\mob\living\carbon\metroid\say.dm" -#include "code\modules\mob\living\carbon\metroid\subtypes.dm" -#include "code\modules\mob\living\carbon\metroid\update_icons.dm" +#include "code\modules\mob\living\carbon\slime\death.dm" +#include "code\modules\mob\living\carbon\slime\emote.dm" +#include "code\modules\mob\living\carbon\slime\examine.dm" +#include "code\modules\mob\living\carbon\slime\life.dm" +#include "code\modules\mob\living\carbon\slime\login.dm" +#include "code\modules\mob\living\carbon\slime\powers.dm" +#include "code\modules\mob\living\carbon\slime\say.dm" +#include "code\modules\mob\living\carbon\slime\slime.dm" +#include "code\modules\mob\living\carbon\slime\subtypes.dm" +#include "code\modules\mob\living\carbon\slime\update_icons.dm" #include "code\modules\mob\living\silicon\death.dm" #include "code\modules\mob\living\silicon\emote.dm" #include "code\modules\mob\living\silicon\laws.dm" @@ -1818,6 +1817,7 @@ #include "code\modules\research\xenoarchaeology\tools\tools_depthscanner.dm" #include "code\modules\research\xenoarchaeology\tools\tools_locater.dm" #include "code\modules\research\xenoarchaeology\tools\tools_pickaxe.dm" +#include "code\modules\research\xenobiology\xenobiology.dm" #include "code\modules\scripting\Errors.dm" #include "code\modules\scripting\Options.dm" #include "code\modules\scripting\AST\AST Nodes.dm"