diff --git a/_maps/RandomRuins/LavaRuins/lavaland_biodome_beach.dmm b/_maps/RandomRuins/LavaRuins/lavaland_biodome_beach.dmm index 299850722c0..0314b624a82 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_biodome_beach.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_biodome_beach.dmm @@ -1,76 +1,133 @@ -"a" = (/turf/template_noop,/area/template_noop) -"b" = (/turf/closed/wall/r_wall,/area/ruin/powered) -"c" = (/turf/open/floor/plating{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/powered) -"d" = (/obj/structure/grille,/obj/structure/window/fulltile,/turf/open/floor/plating{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/powered) -"e" = (/turf/open/floor/plating/beach/sand,/area/ruin/powered) -"f" = (/obj/effect/overlay/palmtree_l,/turf/open/floor/plating/beach/sand,/area/ruin/powered) -"g" = (/turf/closed/wall/mineral/sandstone,/area/ruin/powered) -"h" = (/obj/effect/overlay/palmtree_r,/obj/effect/overlay/coconut,/turf/open/floor/plating/beach/sand,/area/ruin/powered) -"i" = (/obj/structure/table,/obj/item/weapon/storage/box/drinkingglasses,/obj/item/weapon/storage/box/drinkingglasses,/obj/item/weapon/reagent_containers/food/drinks/shaker,/obj/item/weapon/storage/box/beakers,/turf/open/floor/wood,/area/ruin/powered) -"j" = (/obj/structure/table,/obj/machinery/reagentgrinder,/turf/open/floor/wood,/area/ruin/powered) -"k" = (/obj/machinery/vending/boozeomat{emagged = 1},/turf/open/floor/wood,/area/ruin/powered) -"l" = (/obj/structure/table,/obj/item/weapon/reagent_containers/glass/rag,/turf/open/floor/wood,/area/ruin/powered) -"m" = (/obj/effect/mob_spawn/human/cook{helmet = null; id_access = "Bartender"; id_job = "Bartender"; suit = /obj/item/clothing/suit/armor/vest; uniform = /obj/item/clothing/under/rank/bartender; death = 0; desc = "Looks secure."; flavour_text = "You are a bartender for the beach!"; icon = 'icons/obj/Cryogenic2.dmi'; icon_state = "sleeper"; mob_name = "Jerry Thomas"; name = "bartenders cryosleeper"; roundstart = 1},/turf/open/floor/wood,/area/ruin/powered) -"n" = (/turf/open/floor/wood,/area/ruin/powered) -"o" = (/obj/structure/table,/obj/machinery/microwave,/turf/open/floor/wood,/area/ruin/powered) -"p" = (/turf/open/floor/plating/beach/sand,/obj/structure/closet/crate/bin,/turf/open/floor/plasteel/sandeffect,/area/ruin/powered) -"q" = (/turf/open/floor/plating/beach/sand,/turf/open/floor/plasteel/sandeffect,/area/ruin/powered) -"r" = (/obj/structure/table,/turf/open/floor/wood,/area/ruin/powered) -"s" = (/turf/open/floor/plating/beach/sand,/obj/machinery/vending/cigarette,/turf/open/floor/plasteel/sandeffect,/area/ruin/powered) -"t" = (/obj/structure/table/wood,/turf/open/floor/wood,/area/ruin/powered) -"u" = (/obj/machinery/processor,/turf/open/floor/wood,/area/ruin/powered) -"v" = (/turf/open/floor/plating/beach/sand,/obj/machinery/vending/cola,/turf/open/floor/plasteel/sandeffect,/area/ruin/powered) -"w" = (/turf/open/floor/plating/beach/sand,/obj/structure/chair/stool,/turf/open/floor/plasteel/sandeffect,/area/ruin/powered) -"x" = (/obj/structure/closet/secure_closet/freezer/meat,/turf/open/floor/wood,/area/ruin/powered) -"y" = (/turf/open/floor/plating/beach/sand,/obj/machinery/vending/snack,/turf/open/floor/plasteel/sandeffect,/area/ruin/powered) -"z" = (/turf/open/floor/plating/beach/sand{density = 1; opacity = 1},/area/ruin/powered) -"A" = (/obj/machinery/door/airlock/sandstone,/turf/open/floor/wood,/area/ruin/powered) -"B" = (/obj/structure/closet/secure_closet/freezer/kitchen,/turf/open/floor/wood,/area/ruin/powered) -"C" = (/obj/structure/sign/barsign,/turf/closed/wall/mineral/sandstone,/area/ruin/powered) -"D" = (/mob/living/simple_animal/crab,/turf/open/floor/plating/beach/sand,/area/ruin/powered) -"E" = (/obj/effect/overlay/palmtree_l,/obj/effect/overlay/coconut,/turf/open/floor/plating/beach/sand,/area/ruin/powered) -"F" = (/turf/open/floor/plating/beach/sand,/obj/structure/closet/athletic_mixed,/turf/open/floor/plasteel/sandeffect,/area/ruin/powered) -"G" = (/turf/open/floor/plating/beach/sand,/obj/item/clothing/shoes/sandal,/obj/item/clothing/shoes/sandal,/obj/item/clothing/shoes/sandal,/obj/structure/closet/crate,/turf/open/floor/plasteel/sandeffect,/area/ruin/powered) -"H" = (/obj/machinery/door/airlock/hatch,/turf/open/floor/plating{baseturf = /turf/open/floor/plating/lava/smooth; blocks_air = 1},/area/ruin/powered) -"I" = (/obj/machinery/door/airlock/sandstone,/turf/open/floor/plating{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/powered) -"J" = (/obj/effect/overlay/coconut,/turf/open/floor/plating/beach/sand,/area/ruin/powered) -"K" = (/obj/item/toy/beach_ball,/turf/open/floor/plating/beach/sand,/area/ruin/powered) -"L" = (/obj/structure/chair,/turf/open/floor/plating/beach/sand,/area/ruin/powered) -"M" = (/obj/structure/chair,/mob/living/simple_animal/crab,/turf/open/floor/plating/beach/sand,/area/ruin/powered) -"N" = (/turf/open/floor/plating/beach/coastline_t,/area/ruin/powered) -"O" = (/turf/open/floor/plating/beach/coastline_b,/area/ruin/powered) -"P" = (/turf/open/floor/plating/beach/water,/area/ruin/powered) -"Q" = (/turf/closed/wall/r_wall{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/powered) +"aa" = (/turf/template_noop,/area/template_noop) +"ab" = (/turf/closed/wall/r_wall{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/powered) +"ac" = (/turf/closed/wall/r_wall,/area/ruin/powered) +"ad" = (/obj/structure/flora/ausbushes/leafybush,/turf/open/floor/plating/beach/sand,/area/ruin/powered) +"ae" = (/obj/structure/table,/obj/item/weapon/storage/toolbox/mechanical,/obj/item/stack/cable_coil,/turf/open/floor/plating{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/powered) +"af" = (/obj/structure/table,/turf/open/floor/plating{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/powered) +"ag" = (/obj/structure/reagent_dispensers/fueltank,/turf/open/floor/plating{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/powered) +"ah" = (/obj/machinery/power/smes,/turf/open/floor/plating{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/powered) +"ai" = (/obj/machinery/portable_atmospherics/canister/oxygen,/turf/open/floor/plating{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/powered) +"aj" = (/turf/closed/wall/mineral/sandstone{baseturf = /turf/open/floor/plating/beach/sand},/area/ruin/powered) +"ak" = (/turf/open/floor/plating{baseturf = /turf/open/floor/plating/lava/smooth},/obj/structure/toilet,/turf/open/floor/plasteel/sandeffect,/area/ruin/powered) +"al" = (/obj/structure/urinal{pixel_y = 32},/turf/open/floor/plating{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/powered) +"am" = (/turf/open/floor/plating{baseturf = /turf/open/floor/plating/lava/smooth},/obj/structure/urinal{pixel_y = 32},/turf/open/floor/plasteel/sandeffect,/area/ruin/powered) +"an" = (/obj/item/device/flashlight/lantern,/turf/open/floor/plating{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/powered) +"ao" = (/turf/open/floor/plating{baseturf = /turf/open/floor/plating/lava/smooth},/obj/structure/sink{dir = 4; icon_state = "sink"; pixel_x = 11; pixel_y = 0},/turf/open/floor/plasteel/sandeffect,/area/ruin/powered) +"ap" = (/obj/structure/flora/ausbushes/sparsegrass,/turf/open/floor/plating/beach/sand,/area/ruin/powered) +"aq" = (/obj/structure/flora/ausbushes/sunnybush,/turf/open/floor/plating/beach/sand,/area/ruin/powered) +"ar" = (/turf/open/floor/plating/beach/sand,/area/ruin/powered) +"as" = (/turf/open/floor/plating{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/powered) +"at" = (/obj/item/weapon/tank/internals/oxygen,/turf/open/floor/plating{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/powered) +"au" = (/turf/open/floor/plating{baseturf = /turf/open/floor/plating/lava/smooth},/turf/open/floor/plasteel/sandeffect,/area/ruin/powered) +"av" = (/obj/machinery/door/airlock/hatch,/turf/open/floor/plating{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/powered) +"aw" = (/obj/machinery/door/airlock/sandstone,/turf/open/floor/wood,/area/ruin/powered) +"ax" = (/obj/structure/extinguisher_cabinet,/turf/closed/wall/mineral/sandstone{baseturf = /turf/open/floor/plating/beach/sand},/area/ruin/powered) +"ay" = (/turf/open/floor/plating{baseturf = /turf/open/floor/plating/lava/smooth},/obj/machinery/door/airlock/hatch,/turf/open/floor/plasteel/sandeffect,/area/ruin/powered) +"az" = (/obj/item/clothing/tie/dope_necklace,/obj/item/weapon/reagent_containers/spray/spraytan,/turf/open/floor/plating/beach/sand,/area/ruin/powered) +"aA" = (/turf/open/floor/plating/beach/sand,/turf/open/floor/plasteel/sandeffect,/area/ruin/powered) +"aB" = (/turf/open/floor/plasteel/asteroid/warning{baseturf = /turf/open/floor/plating/beach/sand; dir = 1; icon_state = "asteroidwarning"; tag = "icon-asteroidwarning (NORTH)"},/area/ruin/powered) +"aC" = (/turf/open/floor/wood,/area/ruin/powered) +"aD" = (/obj/structure/table,/obj/item/weapon/storage/box/drinkingglasses,/obj/item/weapon/storage/box/drinkingglasses,/obj/item/weapon/reagent_containers/food/drinks/shaker,/obj/item/weapon/storage/box/beakers,/turf/open/floor/wood,/area/ruin/powered) +"aE" = (/obj/structure/table,/obj/machinery/reagentgrinder,/turf/open/floor/wood,/area/ruin/powered) +"aF" = (/obj/machinery/vending/boozeomat{emagged = 1},/turf/open/floor/wood,/area/ruin/powered) +"aG" = (/obj/structure/table,/obj/item/weapon/reagent_containers/glass/rag,/turf/open/floor/wood,/area/ruin/powered) +"aH" = (/obj/structure/table,/obj/item/weapon/storage/box/donkpockets,/turf/open/floor/wood,/area/ruin/powered) +"aI" = (/obj/structure/table,/obj/machinery/microwave,/turf/open/floor/wood,/area/ruin/powered) +"aJ" = (/obj/structure/closet/crate/bin,/obj/item/weapon/tank/internals/emergency_oxygen,/obj/item/trash/candy,/obj/item/toy/talking/owl,/turf/open/floor/plasteel/asteroid/warning{baseturf = /turf/open/floor/plating/beach/sand; dir = 1; icon_state = "asteroidwarning"; tag = "icon-asteroidwarning (NORTH)"},/area/ruin/powered) +"aK" = (/turf/open/floor/plasteel/asteroid{baseturf = /turf/open/floor/plating/beach/sand},/area/ruin/powered) +"aL" = (/obj/effect/mob_spawn/human/bartender/alive{name = "beach bum sleeper"},/turf/open/floor/wood,/area/ruin/powered) +"aM" = (/obj/structure/reagent_dispensers/beerkeg,/turf/open/floor/wood,/area/ruin/powered) +"aN" = (/obj/machinery/vending/cigarette,/turf/open/floor/plasteel/asteroid{baseturf = /turf/open/floor/plating/beach/sand},/area/ruin/powered) +"aO" = (/obj/structure/stacklifter,/turf/open/floor/plating/beach/sand,/area/ruin/powered) +"aP" = (/obj/structure/table/wood,/turf/open/floor/wood,/area/ruin/powered) +"aQ" = (/obj/structure/table/wood,/obj/item/device/flashlight/lamp,/turf/open/floor/wood,/area/ruin/powered) +"aR" = (/obj/structure/table/wood,/obj/item/weapon/reagent_containers/food/drinks/bottle/tequila,/turf/open/floor/wood,/area/ruin/powered) +"aS" = (/obj/machinery/processor,/turf/open/floor/wood,/area/ruin/powered) +"aT" = (/obj/machinery/vending/cola,/turf/open/floor/plasteel/asteroid{baseturf = /turf/open/floor/plating/beach/sand},/area/ruin/powered) +"aU" = (/obj/effect/overlay/palmtree_l,/turf/open/floor/plating/beach/sand,/area/ruin/powered) +"aV" = (/obj/effect/mob_spawn/human/beach/alive{flavour_text = "You're, like, totally a dudebro, bruh. Ch'yea. You came here, like, on spring break, hopin' to pick up some bangin' hot chicks, y'knaw?"; pocket2 = /obj/item/weapon/reagent_containers/food/snacks/pizzaslice/dank; uniform = /obj/item/clothing/under/pants/youngfolksjeans},/turf/open/floor/plating/beach/sand,/area/ruin/powered) +"aW" = (/obj/structure/chair/stool,/turf/open/floor/plasteel/asteroid/warning{baseturf = /turf/open/floor/plating/beach/sand; dir = 1; icon_state = "asteroidwarning"; tag = "icon-asteroidwarning (NORTH)"},/area/ruin/powered) +"aX" = (/obj/structure/closet/secure_closet/freezer/meat,/turf/open/floor/wood,/area/ruin/powered) +"aY" = (/obj/machinery/vending/snack,/turf/open/floor/plasteel/asteroid{baseturf = /turf/open/floor/plating/beach/sand},/area/ruin/powered) +"aZ" = (/obj/effect/overlay/coconut,/turf/open/floor/plating/beach/sand,/area/ruin/powered) +"ba" = (/obj/machinery/light{dir = 4; icon_state = "tube1"},/turf/open/floor/pod/dark{baseturf = /turf/open/floor/plating/asteroid/basalt},/area/ruin/powered) +"bb" = (/obj/structure/weightlifter,/turf/open/floor/plating/beach/sand,/area/ruin/powered) +"bc" = (/turf/open/floor/wood,/obj/machinery/door/airlock/sandstone,/turf/open/floor/plasteel/sandeffect,/area/ruin/powered) +"bd" = (/obj/structure/closet/secure_closet/freezer/kitchen,/turf/open/floor/wood,/area/ruin/powered) +"be" = (/obj/vehicle/scooter/skateboard{dir = 4},/turf/open/floor/plating/beach/sand,/area/ruin/powered) +"bf" = (/obj/machinery/light{icon_state = "tube1"; dir = 8},/turf/open/floor/pod/dark{baseturf = /turf/open/floor/plating/asteroid/basalt},/area/ruin/powered) +"bg" = (/obj/structure/sign/barsign,/turf/closed/wall/mineral/sandstone,/area/ruin/powered) +"bh" = (/turf/closed/wall/mineral/sandstone,/area/ruin/powered) +"bi" = (/turf/open/floor/plating/beach/sand{density = 1; opacity = 1},/area/ruin/powered) +"bj" = (/obj/structure/chair/wood/normal{icon_state = "wooden_chair"; dir = 4},/turf/open/floor/plasteel/asteroid{baseturf = /turf/open/floor/plating/beach/sand},/area/ruin/powered) +"bk" = (/obj/structure/table/wood,/obj/item/weapon/reagent_containers/food/snacks/pastatomato,/turf/open/floor/plasteel/asteroid{baseturf = /turf/open/floor/plating/beach/sand},/area/ruin/powered) +"bl" = (/obj/structure/chair/wood/normal{icon_state = "wooden_chair"; dir = 8},/turf/open/floor/plasteel/asteroid{baseturf = /turf/open/floor/plating/beach/sand},/area/ruin/powered) +"bm" = (/mob/living/simple_animal/crab,/turf/open/floor/plating/beach/sand{density = 1; opacity = 1},/area/ruin/powered) +"bn" = (/obj/structure/closet/athletic_mixed,/turf/open/floor/pod/dark{baseturf = /turf/open/floor/plating/asteroid/basalt},/area/ruin/powered) +"bo" = (/turf/open/floor/pod/dark{baseturf = /turf/open/floor/plating/asteroid/basalt},/obj/structure/rack,/obj/item/clothing/shoes/sandal,/obj/item/clothing/shoes/sandal,/turf/open/floor/plasteel/sandeffect,/area/ruin/powered) +"bp" = (/obj/structure/grille,/obj/structure/window/fulltile,/turf/open/floor/plating{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/powered) +"bq" = (/turf/open/floor/pod/dark{baseturf = /turf/open/floor/plating/asteroid/basalt},/obj/structure/closet/athletic_mixed,/turf/open/floor/plasteel/sandeffect,/area/ruin/powered) +"br" = (/turf/open/floor/pod/dark{baseturf = /turf/open/floor/plating/asteroid/basalt},/area/ruin/powered) +"bs" = (/turf/open/floor/pod/dark{baseturf = /turf/open/floor/plating/asteroid/basalt},/turf/open/floor/plasteel/sandeffect,/area/ruin/powered) +"bt" = (/obj/machinery/door/airlock/hatch,/obj/structure/fans/tiny,/turf/open/floor/pod/dark{baseturf = /turf/open/floor/plating/asteroid/basalt},/area/ruin/powered) +"bu" = (/turf/open/floor/pod/light{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/powered) +"bv" = (/turf/open/floor/pod/light{baseturf = /turf/open/floor/plating/lava/smooth},/turf/open/floor/plasteel/sandeffect,/area/ruin/powered) +"bw" = (/obj/machinery/door/airlock/sandstone,/turf/open/floor/pod/dark{baseturf = /turf/open/floor/plating/asteroid/basalt},/area/ruin/powered) +"bx" = (/obj/structure/flora/rock,/turf/open/floor/plating/beach/sand,/area/ruin/powered) +"by" = (/turf/open/floor/pod/dark{baseturf = /turf/open/floor/plating/asteroid/basalt},/obj/machinery/door/airlock/sandstone,/turf/open/floor/plasteel/sandeffect,/area/ruin/powered) +"bz" = (/mob/living/simple_animal/crab,/turf/open/floor/plating/beach/sand,/area/ruin/powered) +"bA" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/item/weapon/bikehorn/airhorn,/obj/structure/table/wood,/obj/item/weapon/storage/firstaid,/obj/item/weapon/storage/firstaid/brute,/turf/open/floor/wood,/area/ruin/powered) +"bB" = (/obj/structure/window/reinforced{dir = 4; pixel_x = 0},/obj/structure/window/reinforced{dir = 1; layer = 2.9},/obj/structure/chair/stool,/turf/open/floor/wood,/area/ruin/powered) +"bC" = (/obj/structure/table/wood,/obj/item/weapon/tank/internals/oxygen,/obj/item/weapon/pickaxe,/turf/open/floor/pod/dark{baseturf = /turf/open/floor/plating/asteroid/basalt},/area/ruin/powered) +"bD" = (/turf/open/floor/pod/dark{baseturf = /turf/open/floor/plating/asteroid/basalt},/obj/structure/dresser,/turf/open/floor/plasteel/sandeffect,/area/ruin/powered) +"bE" = (/obj/item/weapon/reagent_containers/spray/spraytan,/turf/open/floor/plating/beach/sand,/area/ruin/powered) +"bF" = (/obj/item/toy/beach_ball,/turf/open/floor/plating/beach/sand,/area/ruin/powered) +"bG" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/item/device/megaphone,/turf/open/floor/wood,/area/ruin/powered) +"bH" = (/obj/structure/window/reinforced{dir = 4; pixel_x = 0},/obj/effect/mob_spawn/human/beach/alive{flavour_text = "You're a spunky lifeguard! It's up to you to make sure nobody drowns or gets eaten by sharks and stuff."; has_id = 1; id_access = "Medical Doctor"; id_job = "Lifeguard"; mob_gender = "female"},/turf/open/floor/wood,/area/ruin/powered) +"bI" = (/obj/structure/dresser,/turf/open/floor/pod/dark{baseturf = /turf/open/floor/plating/asteroid/basalt},/area/ruin/powered) +"bJ" = (/obj/structure/chair,/turf/open/floor/plating/beach/sand,/area/ruin/powered) +"bK" = (/obj/item/weapon/storage/backpack/dufflebag,/turf/open/floor/plating/beach/sand,/area/ruin/powered) +"bL" = (/turf/open/floor/pod/light{baseturf = /turf/open/floor/plating/lava/smooth; density = 1},/obj/structure/lattice,/turf/open/floor/plasteel/sandeffect,/area/ruin/powered) +"bM" = (/turf/open/floor/plasteel/stairs/old,/area/ruin/powered) +"bN" = (/obj/structure/flora/ausbushes/reedbush,/turf/open/floor/plating/beach/sand,/area/ruin/powered) +"bO" = (/obj/item/weapon/reagent_containers/spray/spraytan,/obj/item/device/camera,/turf/open/floor/plating/beach/sand,/area/ruin/powered) +"bP" = (/obj/item/weapon/reagent_containers/food/drinks/beer,/turf/open/floor/plating/beach/sand,/area/ruin/powered) +"bQ" = (/obj/structure/flora/ausbushes/reedbush,/turf/open/floor/plating/beach/coastline_t,/area/ruin/powered) +"bR" = (/turf/open/floor/plating/beach/coastline_t,/area/ruin/powered) +"bS" = (/obj/structure/flora/ausbushes/sparsegrass,/turf/open/floor/plating/beach/coastline_t,/area/ruin/powered) +"bT" = (/turf/open/floor/plating/beach/coastline_b,/area/ruin/powered) +"bU" = (/turf/open/floor/plating/beach/water,/area/ruin/powered) +"bV" = (/obj/structure/flora/ausbushes/stalkybush,/turf/open/floor/plating/beach/water,/area/ruin/powered) (1,1,1) = {" -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb -bccccccccccccccccccccccccccccb -bcddddddddddddddddddddddddddcb -bcdeeeeeeeeeeeeeeeeeeeeeeeedcb -bcdeeeeefeeeeeeeeeeeeeeeeeedcb -bcdeeeeeegggggggggggeeeeheedcb -bcdeeeeeegijklmnnnogpqeeeeedcb -bcdeeeeeqgnnnnnnnnrgsqqqqqedcb -bcdeeeefqgttttttgnugvqqqqqedcb -bcdeeeeeqqwwwwwwgnxgyqeeeeedcb -bcdzzzzzqqqqqqqqAnBgqqzzzzedcb -bcdeeeeeeqqqqqqqgCggqeDeeeedcb -bcdeeeEeeeeeeqqqqqqqqeeeeeedcb -bcdeeeeeeeeeeqqqeeeeeeeeFGedcb -HcIeeeeeeeeeeqqqeeeeeeeeqqedcb -bcdeeDeeeeeeeeeeeeeeeeeeeeedcb -bcdeeeeefJeeeeeeeeeeeeeeeeedcb -bcdeeKLeeLeeMeeLeLeLeLeLefedcb -bcdeeeeeeeeeeeeeeeeeeeeeeeedcb -bcdNNNNNNNNNNNNNNNNNNNNNNNNdcb -bcdOOOOOOOOOOOOOOOOOOOOOOOOdcb -bcdPPPPPPPPPPPPPPPPPPPPPPPPdcb -bcdPPPPPPPPPPPPPPPPPPPPPPPPdcb -bcdPPPPPPPPPPPPPPPPPPPPPPPPdcb -bcdPPPPPPPPPPPPPPPPPPPPPPPPdcb -bcdPPPPPPPPPPPPPPPPPPPPPPPPdcb -bcddddddddddddddddddddddddddcb -bccccccccccccccccccccccccccccb -bbbbbQbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaabababacacacacacacacacacacacacabababaaaaaaaaaaaa +aaaaaaaaabababadabaeafagahaiajakajalamanaoabapabababaaaaaaaa +aaaaaaababaqararabasasasasatajauavasasauauabararaqababaaaaaa +aaaaababadaraparababajawajaxajajajajajajayabaraparapababaaaa +aaaaabapararazaraAaBajaCaDaEaFaGaHaIajaJaKaAararararadabaaaa +aaababarararararaAaKajaCaCaLaCaCaCaMajaNaKaAarararararababaa +aaabaparaOaraOaraAaKajaPaQaPaRajaCaSajaTaKaAaraUaraqarapabaa +aaabarararaVararaAaKaBaWaWaWaWajaCaXajaYaKaAararaZarararabaa +baabararbbarbbaraAaKaKaKaKaKaKbcaCbdajaKaKaAarararbearapabbf +aaabararararararaAaKaKaKaKaKaKajbgbhajaKaKaAararararararabaa +ababababbibibibiaAaKbjbkblaKaKaBaBaBaBaKaKaAbibmbibiabababab +acbnbobpararararaAaKaKaKaKaKaKaKaKaKaKaKaKaAararararbpbqboab +acbrbrbpararaUaraAaAaAaAaAaAaAaAaAaAaAaAaAaAararararbpbrbsab +btbubvbpaAaraZararararararararararararararararararaAbpbububt +abbvbvbwaAarararararararbxararararaZarararararararaAbybvbuab +btbububpaAarararararararararararaUararararararararaAbpbvbvbt +acbsbrbparbzarararbxarararararararararbAbBararaZararbpbsbrab +acbCbDbpararararararararararbEararbFarbGbHarararararbpbIbCab +ababababarbJarbJarbJarbJbKbJarbJarararbLbMarbJararaUabababab +aaabadapbNarararbOararararararararbzarararbPararararapbNabaa +baabbQbRbRbSbRbRbRbRbRbRbRbRbRbRbRbRbRbRbRbRbRbRbSbRbRbRabbf +aaabbTbTbTbTbTbTbTbTbTbTbTbTbTbTbTbTbTbTbTbTbTbTbTbTbTbTabaa +aaababbUbUbUbUbUbUbUbUbUbUbUbUbUbUbUbUbUbUbUbUbUbUbUbUababaa +aaaaabbUbUbUbUbUbUbUbUbUbUbUbUbUbVbUbUbUbUbUbUbUbUbUbUabaaaa +aaaaababbUbUbUbUbUbVbUbUbUbUbUbUbUbUbUbUbUbUbUbUbUbUababaaaa +aaaaaaababbUbUbUbUbUbUbUbUbUbUbUbUbUbUbUbUbVbUbUbUababaaaaaa +aaaaaaaaabababbUbUbUbUbUbUbUbUbUbUbUbUbUbUbUbUabababaaaaaaaa +aaaaaaaaaaaaababababababababababababababababababaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa "} diff --git a/_maps/RandomRuins/LavaRuins/lavaland_gym.dmm b/_maps/RandomRuins/LavaRuins/lavaland_gym.dmm index 207eabfa613..155236dd586 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_gym.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_gym.dmm @@ -5,48 +5,49 @@ "e" = (/obj/structure/closet,/mob/living/simple_animal/hostile/zombie,/turf/open/floor/plasteel/freezer{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/powered) "f" = (/obj/structure/punching_bag,/turf/open/floor/plasteel/freezer{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/powered) "g" = (/turf/open/floor/plasteel/freezer{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/powered) -"h" = (/obj/structure/window{icon_state = "window"; dir = 1},/obj/item/weapon/shard{icon_state = "medium"},/mob/living/simple_animal/hostile/zombie{name = "Boss of This Gym"},/turf/open/floor/plasteel/freezer{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/powered) -"i" = (/obj/structure/window{icon_state = "window"; dir = 1},/turf/open/floor/plasteel/freezer{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/powered) -"j" = (/obj/structure/window{icon_state = "window"; dir = 1},/obj/structure/window{icon_state = "window"; dir = 4},/turf/open/floor/plasteel/freezer{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/powered) +"h" = (/obj/structure/window{icon_state = "window";dir = 1},/obj/item/weapon/shard{icon_state = "medium"},/mob/living/simple_animal/hostile/zombie{name = "Boss of This Gym"},/turf/open/floor/plasteel/freezer{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/powered) +"i" = (/obj/structure/window{icon_state = "window";dir = 1},/turf/open/floor/plasteel/freezer{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/powered) +"j" = (/obj/structure/window{icon_state = "window";dir = 1},/obj/structure/window{icon_state = "window";dir = 4},/turf/open/floor/plasteel/freezer{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/powered) "k" = (/obj/effect/decal/cleanable/blood,/turf/open/floor/plasteel/freezer{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/powered) "l" = (/obj/structure/weightlifter,/turf/open/floor/plasteel/freezer{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/powered) -"m" = (/obj/structure/window{icon_state = "window"; dir = 8},/turf/open/floor/plasteel/freezer{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/powered) -"n" = (/obj/structure/window{icon_state = "window"; dir = 4},/turf/open/floor/plasteel/freezer{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/powered) +"m" = (/obj/structure/window{icon_state = "window";dir = 8},/turf/open/floor/plasteel/freezer{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/powered) +"n" = (/obj/structure/window{icon_state = "window";dir = 4},/turf/open/floor/plasteel/freezer{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/powered) "o" = (/obj/structure/stacklifter,/turf/open/floor/plasteel/freezer{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/powered) -"p" = (/obj/structure/window,/obj/structure/window{icon_state = "window"; dir = 8},/obj/effect/decal/cleanable/blood,/turf/open/floor/plasteel/freezer{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/powered) +"p" = (/obj/structure/window,/obj/structure/window{icon_state = "window";dir = 8},/obj/effect/decal/cleanable/blood,/turf/open/floor/plasteel/freezer{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/powered) "q" = (/obj/structure/window,/turf/open/floor/plasteel/freezer{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/powered) "r" = (/obj/structure/window,/obj/item/weapon/shard,/mob/living/simple_animal/hostile/zombie{name = "Leatherhead"},/turf/open/floor/plasteel/freezer{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/powered) -"s" = (/obj/effect/decal/cleanable/blood/tracks{tag = "icon-splatter4 (NORTH)"; icon_state = "splatter4"; dir = 1},/turf/open/floor/plating/asteroid/basalt/lava_land_surface,/area/lavaland/surface/outdoors) -"t" = (/obj/effect/decal/cleanable/blood/tracks{tag = "icon-splatter6 (EAST)"; icon_state = "splatter6"; dir = 4},/obj/effect/decal/cleanable/blood/tracks{tag = "icon-tracks (NORTH)"; icon_state = "tracks"; dir = 1},/obj/effect/decal/cleanable/blood/tracks{tag = "icon-gib3"; icon_state = "gib3"},/turf/open/floor/plating/asteroid/basalt/lava_land_surface,/area/lavaland/surface/outdoors) -"u" = (/obj/machinery/door/airlock/external,/turf/open/floor/plating/asteroid/basalt/lava_land_surface,/area/ruin/powered) -"v" = (/obj/effect/decal/cleanable/blood/tracks{tag = "icon-tracks (EAST)"; icon_state = "tracks"; dir = 4},/obj/effect/decal/cleanable/blood/tracks{tag = "icon-tracks (NORTHEAST)"; icon_state = "tracks"; dir = 5},/turf/open/floor/plating/asteroid/basalt/lava_land_surface,/area/lavaland/surface/outdoors) -"w" = (/obj/effect/decal/cleanable/blood/tracks{tag = "icon-tracks (EAST)"; icon_state = "tracks"; dir = 4},/obj/effect/decal/cleanable/blood/tracks{tag = "icon-tracks (SOUTHEAST)"; icon_state = "tracks"; dir = 6},/turf/open/floor/plating/asteroid/basalt/lava_land_surface,/area/lavaland/surface/outdoors) -"x" = (/obj/effect/decal/cleanable/blood/tracks{tag = "icon-splatter5"; icon_state = "splatter5"},/obj/effect/decal/cleanable/blood/tracks{tag = "icon-tracks (EAST)"; icon_state = "tracks"; dir = 4},/turf/open/floor/plating/asteroid/basalt/lava_land_surface,/area/lavaland/surface/outdoors) -"y" = (/obj/effect/decal/cleanable/blood/tracks{tag = "icon-splatter4 (NORTH)"; icon_state = "splatter4"; dir = 1},/obj/effect/decal/cleanable/blood/tracks{tag = "icon-splatter6 (NORTH)"; icon_state = "splatter6"; dir = 1},/turf/open/floor/plating/asteroid/basalt/lava_land_surface,/area/lavaland/surface/outdoors) -"z" = (/obj/effect/decal/cleanable/blood/tracks{tag = "icon-splatter5"; icon_state = "splatter5"},/turf/open/floor/plating/asteroid/basalt/lava_land_surface,/area/lavaland/surface/outdoors) +"s" = (/obj/effect/decal/cleanable/blood/tracks{tag = "icon-splatter4 (NORTH)";icon_state = "splatter4";dir = 1},/turf/open/floor/plating/asteroid/basalt/lava_land_surface,/area/lavaland/surface/outdoors) +"t" = (/obj/effect/decal/cleanable/blood/tracks{tag = "icon-splatter6 (EAST)";icon_state = "splatter6";dir = 4},/obj/effect/decal/cleanable/blood/tracks{tag = "icon-tracks (NORTH)";icon_state = "tracks";dir = 1},/obj/effect/decal/cleanable/blood/tracks{tag = "icon-gib3";icon_state = "gib3"},/turf/open/floor/plating/asteroid/basalt/lava_land_surface,/area/lavaland/surface/outdoors) +"u" = (/obj/machinery/door/airlock/external,/turf/open/floor/plasteel/freezer{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/powered) +"v" = (/obj/effect/decal/cleanable/blood/tracks{tag = "icon-tracks (EAST)";icon_state = "tracks";dir = 4},/obj/effect/decal/cleanable/blood/tracks{tag = "icon-tracks (NORTHEAST)";icon_state = "tracks";dir = 5},/turf/open/floor/plating/asteroid/basalt/lava_land_surface,/area/lavaland/surface/outdoors) +"w" = (/obj/effect/decal/cleanable/blood/tracks{tag = "icon-tracks (EAST)";icon_state = "tracks";dir = 4},/obj/effect/decal/cleanable/blood/tracks{tag = "icon-tracks (SOUTHEAST)";icon_state = "tracks";dir = 6},/turf/open/floor/plating/asteroid/basalt/lava_land_surface,/area/lavaland/surface/outdoors) +"x" = (/obj/effect/decal/cleanable/blood/tracks{tag = "icon-splatter5";icon_state = "splatter5"},/obj/effect/decal/cleanable/blood/tracks{tag = "icon-tracks (EAST)";icon_state = "tracks";dir = 4},/turf/open/floor/plating/asteroid/basalt/lava_land_surface,/area/lavaland/surface/outdoors) +"y" = (/obj/effect/decal/cleanable/blood/tracks{tag = "icon-splatter4 (NORTH)";icon_state = "splatter4";dir = 1},/obj/effect/decal/cleanable/blood/tracks{tag = "icon-splatter6 (NORTH)";icon_state = "splatter6";dir = 1},/turf/open/floor/plating/asteroid/basalt/lava_land_surface,/area/lavaland/surface/outdoors) +"z" = (/obj/effect/decal/cleanable/blood/tracks{tag = "icon-splatter5";icon_state = "splatter5"},/turf/open/floor/plating/asteroid/basalt/lava_land_surface,/area/lavaland/surface/outdoors) "A" = (/mob/living/simple_animal/hostile/zombie,/turf/open/floor/plasteel/freezer{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/powered) -"B" = (/obj/structure/window{icon_state = "window"; dir = 1},/obj/machinery/shower,/turf/open/floor/plasteel/freezer{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/powered) -"C" = (/obj/structure/window{icon_state = "window"; dir = 1},/obj/machinery/shower,/mob/living/simple_animal/hostile/zombie,/turf/open/floor/plasteel/freezer{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/powered) +"B" = (/obj/structure/window{icon_state = "window";dir = 1},/obj/machinery/shower,/turf/open/floor/plasteel/freezer{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/powered) +"C" = (/obj/structure/window{icon_state = "window";dir = 1},/obj/machinery/shower,/mob/living/simple_animal/hostile/zombie,/turf/open/floor/plasteel/freezer{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/powered) +"D" = (/turf/template_noop,/area/template_noop) (1,1,1) = {" -aaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaabab -aaaaaccccccccccccbbb -aaaaacdeddddddedcbbb -aaaaacfgghiijkglcbaa -aaaaacfggmgkngglcbbb -aaaaacfggmggnggocbbb -aaaaacfggpqqrggocstb -aaaaacgkgggggggkuvwx -aaaaacuucccccccccyzb -aaaaacgAgggggggAcbbb -aaaaacggggggAgggcbbb -aaaaacBCBBggBBBBcbaa -aaaaacgggggggAggcbaa -aaaaaccccccccccccbaa -aaaaaaaaaaaaaaaaaabb -aaaaaaaaaaaaaaaabbbb -aaaaaaaaaaaaaaaabbba +DDDDDDDDDDDDDDDDDDDD +DDDDDDDDDDDDDDDDDDDD +DDDDDDDDDDDDDDDDDDDD +DDDDDDDDDDDDDDDDDDDD +DDDccccccccccccDDDDD +DDDcdeddddddedcbDDDD +DDDcfgghiijkglcbaDDD +DDDcfggmgkngglcbbbDD +DDDcfggmggnggocbbbDD +DDDcfggpqqrggocstbbD +DDDcgkgggggggkuvwxbD +DDDcuucccccccccyzbbD +DDDcgAgggggggAcbbbbD +DDDcggggggAgggcbbbDD +DDDcBCBBggBBBBcbbDDD +DDDcgggggggAggcbDDDD +DDDccccccccccccbDDDD +DDDDDDDDDDDDDDDDDDDD +DDDDDDDDDDDDDDDDDDDD +DDDDDDDDDDDDDDDDDDDD "} diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_animal_hospital.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_animal_hospital.dmm index e90e8f60831..6249fddfb88 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_animal_hospital.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_animal_hospital.dmm @@ -7,11 +7,11 @@ "ag" = (/turf/open/floor/plasteel/bar{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface},/area/ruin/powered) "ah" = (/obj/structure/toilet,/turf/open/floor/plasteel/bar{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface},/area/ruin/powered) "ai" = (/obj/machinery/vending/coffee,/turf/open/floor/plasteel/cmo{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface},/area/ruin/powered) -"aj" = (/obj/structure/table/wood,/obj/item/weapon/storage/backpack/dufflebag/med,/turf/open/floor/plasteel/cmo{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface},/area/ruin/powered) +"aj" = (/obj/structure/table/wood,/obj/item/device/flashlight/lamp,/turf/open/floor/plasteel/cmo{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface},/area/ruin/powered) "ak" = (/obj/structure/table/wood,/obj/item/device/taperecorder,/obj/item/weapon/pen/blue,/turf/open/floor/plasteel/cmo{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface},/area/ruin/powered) "al" = (/obj/structure/table/wood,/obj/item/toy/carpplushie,/turf/open/floor/plasteel/cmo{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface},/area/ruin/powered) "am" = (/obj/machinery/vending/snack,/turf/open/floor/plasteel/cmo{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface},/area/ruin/powered) -"an" = (/obj/machinery/sleeper{icon_state = "sleeper-open"; dir = 4},/turf/open/floor/plasteel/white{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface},/area/ruin/powered) +"an" = (/obj/machinery/sleeper{icon_state = "sleeper-open";dir = 4},/turf/open/floor/plasteel/white{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface},/area/ruin/powered) "ao" = (/turf/open/floor/plasteel/white{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface},/area/ruin/powered) "ap" = (/obj/structure/table,/obj/item/weapon/circular_saw,/obj/item/weapon/scalpel{pixel_y = 12},/turf/open/floor/plasteel/white{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface},/area/ruin/powered) "aq" = (/obj/structure/table,/obj/item/weapon/cautery{pixel_x = 4},/obj/item/weapon/surgicaldrill,/turf/open/floor/plasteel/white{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface},/area/ruin/powered) @@ -19,11 +19,11 @@ "as" = (/turf/open/floor/plasteel/cmo{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface},/area/ruin/powered) "at" = (/obj/structure/chair/office/dark{dir = 1},/turf/open/floor/plasteel/cmo{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface},/area/ruin/powered) "au" = (/obj/structure/chair/office/dark{dir = 4},/turf/open/floor/plasteel/cmo{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface},/area/ruin/powered) -"av" = (/obj/structure/table/reinforced,/obj/item/clothing/gloves/color/latex,/obj/item/clothing/mask/surgical,/obj/item/clothing/suit/apron/surgical,/turf/open/floor/plasteel/white{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface},/area/ruin/powered) +"av" = (/obj/item/weapon/reagent_containers/glass/rag,/obj/item/weapon/reagent_containers/spray/cleaner,/turf/open/floor/plasteel{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface;dir = 8;icon_state = "blue"},/area/ruin/powered) "aw" = (/obj/structure/bed/roller,/turf/open/floor/plasteel/white{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface},/area/ruin/powered) "ax" = (/obj/structure/closet/crate/trashcart,/obj/item/weapon/storage/bag/trash,/obj/item/trash/cheesie,/obj/item/weapon/reagent_containers/syringe/antiviral,/obj/item/bodybag,/obj/item/weapon/reagent_containers/food/drinks/bottle/vodka,/turf/open/floor/grass{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface},/area/lavaland/surface/outdoors) -"ay" = (/obj/structure/sink{icon_state = "sink"; dir = 8; pixel_x = -12; pixel_y = 2},/obj/structure/mirror{pixel_x = -28},/turf/open/floor/plasteel/bar{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface},/area/ruin/powered) -"az" = (/obj/structure/noticeboard{dir = 1; pixel_y = -27},/obj/item/weapon/paper{info = "Nothing of interest to report."; name = "Important Notice - Mrs. Henderson"},/turf/open/floor/plasteel/cmo{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface},/area/ruin/powered) +"ay" = (/obj/structure/sink{icon_state = "sink";dir = 8;pixel_x = -12;pixel_y = 2},/obj/structure/mirror{pixel_x = -28},/turf/open/floor/plasteel/bar{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface},/area/ruin/powered) +"az" = (/obj/structure/noticeboard{dir = 1;pixel_y = -27},/obj/item/weapon/paper{info = "Nothing of interest to report.";name = "Important Notice - Mrs. Henderson"},/turf/open/floor/plasteel/cmo{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface},/area/ruin/powered) "aA" = (/obj/structure/closet/secure_closet/medical2,/turf/open/floor/plasteel/white{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface},/area/ruin/powered) "aB" = (/obj/machinery/computer/operating,/turf/open/floor/plasteel/white{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface},/area/ruin/powered) "aC" = (/obj/structure/table/optable,/turf/open/floor/plasteel/white{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface},/area/ruin/powered) @@ -35,14 +35,14 @@ "aI" = (/turf/closed/wall/shuttle/smooth,/area/ruin/powered) "aJ" = (/turf/open/floor/plasteel/grimy{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface},/area/lavaland/surface/outdoors) "aK" = (/turf/open/floor/plasteel{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface},/area/ruin/powered) -"aL" = (/turf/open/floor/plasteel{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface; dir = 1; icon_state = "blue"},/area/ruin/powered) -"aM" = (/obj/effect/mob_spawn/human/doctor/alive{flavour_text = "You were putting in your hours as a vet in the local animal hospital when a massive bluespace translocation shunted you across the galaxy. Can you survive on this desolate wasteland..?"; id_job = "Veterinarian"},/turf/open/floor/plasteel{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface; dir = 1; icon_state = "blue"},/area/ruin/powered) -"aN" = (/obj/structure/closet/crate/freezer,/obj/item/weapon/reagent_containers/blood/random,/obj/item/weapon/reagent_containers/blood/random,/obj/item/weapon/reagent_containers/blood/random,/obj/item/weapon/reagent_containers/blood/random,/turf/open/floor/plasteel{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface; dir = 1; icon_state = "blue"},/area/ruin/powered) -"aO" = (/obj/machinery/iv_drip,/turf/open/floor/plasteel{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface; dir = 1; icon_state = "blue"},/area/ruin/powered) -"aP" = (/turf/open/floor/plasteel{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface; dir = 0; icon_state = "blue"},/area/ruin/powered) -"aQ" = (/turf/open/floor/plasteel{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface; dir = 8; icon_state = "bluecorner"},/area/ruin/powered) -"aR" = (/turf/open/floor/plasteel{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface; dir = 4; icon_state = "blue"},/area/ruin/powered) -"aS" = (/turf/open/floor/plasteel{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface; dir = 8; icon_state = "blue"},/area/ruin/powered) +"aL" = (/turf/open/floor/plasteel{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface;dir = 1;icon_state = "blue"},/area/ruin/powered) +"aM" = (/obj/effect/mob_spawn/human/doctor/alive{flavour_text = "You were putting in your hours as a vet in the local animal hospital when a massive bluespace translocation shunted you across the galaxy. Can you survive on this desolate wasteland..?";id_job = "Veterinarian"},/turf/open/floor/plasteel{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface;dir = 1;icon_state = "blue"},/area/ruin/powered) +"aN" = (/obj/structure/closet/crate/freezer,/obj/item/weapon/reagent_containers/blood/random,/obj/item/weapon/reagent_containers/blood/random,/obj/item/weapon/reagent_containers/blood/random,/obj/item/weapon/reagent_containers/blood/random,/turf/open/floor/plasteel{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface;dir = 1;icon_state = "blue"},/area/ruin/powered) +"aO" = (/obj/machinery/iv_drip,/turf/open/floor/plasteel{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface;dir = 1;icon_state = "blue"},/area/ruin/powered) +"aP" = (/turf/open/floor/plasteel{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface;dir = 0;icon_state = "blue"},/area/ruin/powered) +"aQ" = (/turf/open/floor/plasteel{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface;dir = 8;icon_state = "bluecorner"},/area/ruin/powered) +"aR" = (/turf/open/floor/plasteel{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface;dir = 4;icon_state = "blue"},/area/ruin/powered) +"aS" = (/turf/open/floor/plasteel{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface;dir = 8;icon_state = "blue"},/area/ruin/powered) "aT" = (/obj/structure/closet,/obj/effect/decal/cleanable/cobweb,/obj/item/ammo_casing/shotgun/dart,/obj/item/ammo_casing/shotgun/dart,/obj/item/weapon/gun/projectile/revolver/doublebarrel{desc = "For putting critters out to pasture."},/obj/item/ammo_casing/shotgun/buckshot,/obj/item/weapon/storage/box/bodybags,/turf/open/floor/plating{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface},/area/ruin/powered) "aU" = (/turf/open/floor/plating{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface},/area/ruin/powered) "aV" = (/obj/structure/closet/secure_closet/medical1,/turf/open/floor/plasteel/white{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface},/area/ruin/powered) @@ -50,7 +50,7 @@ "aX" = (/obj/item/stack/cable_coil/random,/turf/open/floor/plating{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface},/area/ruin/powered) "aY" = (/obj/structure/bodycontainer/morgue,/turf/open/floor/plating{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface},/area/ruin/powered) "aZ" = (/obj/effect/decal/cleanable/ash,/turf/open/floor/plating{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface},/area/ruin/powered) -"ba" = (/obj/structure/table/glass,/obj/item/weapon/storage/belt/medical,/obj/item/weapon/reagent_containers/glass/beaker,/turf/open/floor/plasteel/white{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface},/area/ruin/powered) +"ba" = (/obj/structure/table/glass,/obj/item/weapon/reagent_containers/glass/beaker,/obj/item/weapon/storage/backpack/dufflebag/med,/turf/open/floor/plasteel/white{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface},/area/ruin/powered) "bb" = (/obj/structure/table/reinforced,/obj/item/device/laser_pointer,/turf/open/floor/plasteel/white{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface},/area/ruin/powered) "bc" = (/obj/structure/table/reinforced,/obj/item/weapon/storage/firstaid/regular,/turf/open/floor/plasteel/white{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface},/area/ruin/powered) "bd" = (/obj/structure/table/glass,/obj/item/weapon/storage/box/gloves,/turf/open/floor/plasteel/white{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface},/area/ruin/powered) @@ -61,63 +61,72 @@ "bi" = (/obj/item/toy/cattoy,/turf/open/floor/plasteel/white{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface},/area/ruin/powered) "bj" = (/obj/structure/table/glass,/obj/item/weapon/lazarus_injector,/turf/open/floor/plasteel/white{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface},/area/ruin/powered) "bk" = (/obj/structure/reagent_dispensers/fueltank,/turf/open/floor/plating{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface},/area/ruin/powered) -"bl" = (/obj/structure/table,/obj/item/weapon/reagent_containers/food/snacks/cookie{name = "doggie biscuit"},/obj/item/weapon/reagent_containers/food/snacks/cookie{name = "doggie biscuit"},/obj/item/weapon/reagent_containers/food/snacks/cookie{name = "doggie biscuit"},/obj/item/weapon/reagent_containers/food/snacks/cookie{name = "doggie biscuit"},/obj/item/weapon/reagent_containers/food/snacks/cookie{name = "doggie biscuit"},/obj/item/weapon/reagent_containers/food/snacks/cookie{name = "doggie biscuit"},/turf/open/floor/plasteel{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface; dir = 1; icon_state = "blue"},/area/ruin/powered) -"bm" = (/obj/structure/chair/comfy/teal{dir = 8},/turf/open/floor/plasteel{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface; dir = 1; icon_state = "blue"},/area/ruin/powered) +"bl" = (/obj/structure/table,/obj/item/weapon/reagent_containers/food/snacks/cookie{name = "doggie biscuit"},/obj/item/weapon/reagent_containers/food/snacks/cookie{name = "doggie biscuit"},/obj/item/weapon/reagent_containers/food/snacks/cookie{name = "doggie biscuit"},/obj/item/weapon/reagent_containers/food/snacks/cookie{name = "doggie biscuit"},/obj/item/weapon/reagent_containers/food/snacks/cookie{name = "doggie biscuit"},/obj/item/weapon/reagent_containers/food/snacks/cookie{name = "doggie biscuit"},/turf/open/floor/plasteel{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface;dir = 1;icon_state = "blue"},/area/ruin/powered) +"bm" = (/obj/structure/chair/comfy/teal{dir = 8},/turf/open/floor/plasteel{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface;dir = 1;icon_state = "blue"},/area/ruin/powered) "bn" = (/obj/structure/bed/dogbed,/turf/open/floor/plasteel/white{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface},/area/ruin/powered) "bo" = (/obj/item/weapon/reagent_containers/glass/bowl,/obj/item/weapon/reagent_containers/food/snacks/cheesewedge,/obj/item/weapon/reagent_containers/food/snacks/cheesewedge,/turf/open/floor/plasteel/white{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface},/area/ruin/powered) -"bp" = (/obj/structure/closet/crate/bin,/obj/item/trash/pistachios,/obj/item/weapon/lipstick/random,/obj/item/seeds/apple,/turf/open/floor/plasteel{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface; dir = 8; icon_state = "blue"},/area/ruin/powered) +"bp" = (/obj/structure/closet/crate/bin,/obj/item/trash/pistachios,/obj/item/weapon/lipstick/random,/obj/item/seeds/apple,/turf/open/floor/plasteel{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface;dir = 8;icon_state = "blue"},/area/ruin/powered) "bq" = (/obj/structure/filingcabinet/chestdrawer/wheeled,/turf/open/floor/plasteel{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface},/area/ruin/powered) "br" = (/obj/structure/chair/office/dark,/turf/open/floor/plasteel{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface},/area/ruin/powered) "bs" = (/obj/structure/table/reinforced,/obj/item/weapon/phone,/turf/open/floor/plasteel{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface},/area/ruin/powered) "bt" = (/obj/structure/flora/kirbyplants,/turf/open/floor/plasteel{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface},/area/ruin/powered) -"bu" = (/obj/structure/chair/comfy/teal{dir = 8},/turf/open/floor/plasteel{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface; dir = 4; icon_state = "blue"},/area/ruin/powered) -"bv" = (/obj/effect/mob_spawn/mouse{dir = 4; flavour_text = "You're a mousey! You're getting pretty old as mice go, and you haven't been feeling well as of late. Your master loves you a lot so he took you to this place so you can get better! You can't wait to see him again!"; mob_name = "Stallman Jr."},/turf/open/floor/plasteel/white{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface},/area/ruin/powered) +"bu" = (/obj/structure/chair/comfy/teal{dir = 8},/turf/open/floor/plasteel{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface;dir = 4;icon_state = "blue"},/area/ruin/powered) +"bv" = (/obj/effect/mob_spawn/mouse{dir = 4;flavour_text = "You're a mousey! You're getting pretty old as mice go, and you haven't been feeling well as of late. Your master loves you a lot so he took you to this place so you can get better! You can't wait to see him again!";mob_name = "Stallman Jr."},/turf/open/floor/plasteel/white{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface},/area/ruin/powered) "bw" = (/obj/effect/decal/cleanable/dirt,/turf/open/floor/plasteel/white{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface},/area/ruin/powered) -"bx" = (/obj/machinery/door/airlock/medical{name = "Patient Room"; req_access_txt = "5"},/turf/open/floor/plating{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface},/area/ruin/powered) -"by" = (/obj/structure/table/reinforced,/obj/item/device/flashlight/lamp,/turf/open/floor/plasteel{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface; dir = 8; icon_state = "blue"},/area/ruin/powered) +"bx" = (/obj/machinery/door/airlock/medical{name = "Patient Room";req_access_txt = "5"},/turf/open/floor/plating{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface},/area/ruin/powered) +"by" = (/obj/structure/table/reinforced,/obj/item/device/flashlight/lamp,/turf/open/floor/plasteel{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface;dir = 8;icon_state = "blue"},/area/ruin/powered) "bz" = (/obj/structure/table/reinforced,/obj/item/clothing/glasses/regular,/turf/open/floor/plasteel{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface},/area/ruin/powered) "bA" = (/obj/structure/table/reinforced,/obj/item/weapon/paper_bin,/obj/item/weapon/pen/fourcolor,/turf/open/floor/plasteel{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface},/area/ruin/powered) "bB" = (/obj/structure/table/reinforced,/obj/item/weapon/storage/box/hug,/turf/open/floor/plasteel{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface},/area/ruin/powered) "bC" = (/obj/structure/chair/office/light{dir = 1},/turf/open/floor/plasteel/white{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface},/area/ruin/powered) -"bD" = (/obj/structure/table/glass,/obj/item/weapon/reagent_containers/glass/bottle/cyanide{desc = "A cocktail of chemotherpy drugs intended to treat bladder cancer."; name = "MVAC regimen"},/obj/item/weapon/reagent_containers/syringe,/turf/open/floor/plasteel/white{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface},/area/ruin/powered) -"bE" = (/obj/structure/closet/crate/critter,/turf/open/floor/plasteel{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface; dir = 8; icon_state = "blue"},/area/ruin/powered) -"bF" = (/turf/open/floor/plasteel{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface; dir = 10; icon_state = "blue"},/area/ruin/powered) -"bG" = (/obj/structure/chair/comfy/teal{dir = 8},/turf/open/floor/plasteel{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface; dir = 6; icon_state = "blue"},/area/ruin/powered) -"bH" = (/obj/item/weapon/reagent_containers/glass/rag,/obj/structure/table,/obj/item/weapon/reagent_containers/spray/cleaner,/turf/open/floor/plasteel{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface; dir = 8; icon_state = "blue"},/area/ruin/powered) +"bD" = (/obj/structure/table/glass,/obj/item/weapon/reagent_containers/glass/bottle/cyanide{desc = "A cocktail of chemotherpy drugs intended to treat bladder cancer.";name = "MVAC regimen"},/obj/item/weapon/reagent_containers/syringe,/turf/open/floor/plasteel/white{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface},/area/ruin/powered) +"bE" = (/obj/structure/closet/crate/critter,/turf/open/floor/plasteel{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface;dir = 8;icon_state = "blue"},/area/ruin/powered) +"bF" = (/turf/open/floor/plasteel{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface;dir = 10;icon_state = "blue"},/area/ruin/powered) +"bG" = (/obj/structure/chair/comfy/teal{dir = 8},/turf/open/floor/plasteel{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface;dir = 6;icon_state = "blue"},/area/ruin/powered) +"bH" = (/obj/structure/table,/obj/item/weapon/tank/internals/oxygen,/obj/item/weapon/tank/internals/oxygen,/turf/open/floor/plasteel{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface;dir = 8;icon_state = "blue"},/area/ruin/powered) "bI" = (/obj/structure/sign/bluecross_2{name = "animal hospital"},/turf/closed/wall/shuttle/smooth{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface},/area/ruin/powered) "bJ" = (/obj/machinery/door/airlock/glass_large,/turf/open/floor/plating{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface},/area/ruin/powered) "bK" = (/obj/item/weapon/reagent_containers/glass/bowl,/obj/item/weapon/reagent_containers/food/snacks/grown/wheat,/obj/item/weapon/reagent_containers/food/snacks/grown/wheat,/obj/item/weapon/reagent_containers/food/snacks/grown/wheat,/obj/effect/decal/cleanable/dirt,/turf/open/floor/plasteel/white{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface},/area/ruin/powered) "bL" = (/obj/vehicle/scooter/skateboard{dir = 4},/turf/open/floor/grass{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface},/area/lavaland/surface/outdoors) "bM" = (/obj/structure/flora/ausbushes/sunnybush,/turf/open/floor/grass{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface},/area/lavaland/surface/outdoors) -"bN" = (/obj/effect/mob_spawn/cow{dir = 4; flavour_text = "You're a cow. You've lived a pampered life as a prized show heifer, a real blue-ribbon winner. After showing signs of a minor respiratory infection, your master took you to the hospital right away. He'd better come back soon, you're getting quite impatient."; mob_name = "Flossie"},/turf/open/floor/plasteel/white{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface},/area/ruin/powered) +"bN" = (/obj/effect/mob_spawn/cow{dir = 4;flavour_text = "You're a cow. You've lived a pampered life as a prized show heifer, a real blue-ribbon winner. After showing signs of a minor respiratory infection, your master took you to the hospital right away. He'd better come back soon, you're getting quite impatient.";mob_name = "Flossie"},/turf/open/floor/plasteel/white{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface},/area/ruin/powered) "bO" = (/obj/structure/flora/ausbushes/ppflowers,/turf/open/floor/grass{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface},/area/lavaland/surface/outdoors) "bP" = (/obj/structure/chair/office/light{dir = 4},/obj/effect/decal/cleanable/dirt,/turf/open/floor/plasteel/white{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface},/area/ruin/powered) "bQ" = (/obj/structure/table/glass,/obj/item/clothing/tie/petcollar,/obj/item/weapon/pen/blue,/turf/open/floor/plasteel/white{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface},/area/ruin/powered) -"bR" = (/obj/structure/table,/obj/machinery/cell_charger,/obj/item/weapon/melee/baton/cattleprod,/obj/item/weapon/stock_parts/cell/high,/turf/open/floor/plasteel{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface; dir = 10; icon_state = "blue"},/area/ruin/powered) -"bS" = (/obj/structure/closet,/obj/item/weapon/defibrillator/loaded,/obj/item/weapon/storage/belt/medical,/obj/item/clothing/glasses/hud/health,/turf/open/floor/plasteel{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface; dir = 6; icon_state = "blue"},/area/ruin/powered) +"bR" = (/obj/structure/table,/obj/machinery/cell_charger,/obj/item/weapon/melee/baton/cattleprod,/obj/item/weapon/stock_parts/cell/high,/turf/open/floor/plasteel{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface;dir = 10;icon_state = "blue"},/area/ruin/powered) +"bS" = (/obj/structure/closet,/obj/item/weapon/defibrillator/loaded,/obj/item/weapon/storage/belt/medical,/obj/item/clothing/glasses/hud/health,/turf/open/floor/plasteel{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface;dir = 6;icon_state = "blue"},/area/ruin/powered) "bT" = (/obj/item/weapon/pickaxe,/obj/effect/decal/cleanable/blood/old,/turf/open/floor/plating/asteroid/basalt/lava_land_surface,/area/lavaland/surface/outdoors) "bU" = (/obj/effect/decal/remains/human,/turf/open/floor/plating/asteroid/basalt/lava_land_surface,/area/lavaland/surface/outdoors) "bV" = (/obj/effect/decal/cleanable/blood/old,/turf/open/floor/plating/asteroid/basalt/lava_land_surface,/area/lavaland/surface/outdoors) "bW" = (/turf/open/floor/grass,/area/lavaland/surface/outdoors) +"cf" = (/obj/machinery/sleeper{icon_state = "sleeper-open";dir = 4},/turf/open/floor/plasteel{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface;dir = 1;icon_state = "blue"},/area/ruin/powered) +"ce" = (/obj/machinery/atmospherics/components/unary/portables_connector/visible{dir = 1},/obj/machinery/portable_atmospherics/pump,/turf/open/floor/plasteel/white{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface},/area/ruin/powered) +"cd" = (/obj/structure/table/reinforced,/obj/item/clothing/gloves/color/latex,/obj/item/clothing/mask/surgical,/obj/item/clothing/suit/apron/surgical,/turf/open/floor/plasteel/white{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface},/area/space) +"cc" = (/obj/machinery/atmospherics/pipe/simple/general/visible,/turf/closed/wall/shuttle/smooth{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface},/area/ruin/powered) +"cb" = (/obj/machinery/atmospherics/components/binary/valve,/turf/open/floor/grass{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface},/area/lavaland/surface/outdoors) +"ca" = (/obj/machinery/atmospherics/components/unary/tank/air{dir = 4},/turf/open/floor/grass{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface},/area/lavaland/surface/outdoors) +"bZ" = (/obj/machinery/atmospherics/pipe/simple/general/visible{dir = 10},/turf/open/floor/grass{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface},/area/lavaland/surface/outdoors) +"bY" = (/obj/machinery/atmospherics/pipe/manifold/general/visible{dir = 1},/turf/open/floor/grass{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface},/area/lavaland/surface/outdoors) +"bX" = (/obj/machinery/atmospherics/pipe/simple/general/visible{dir = 6},/turf/open/floor/grass{baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface},/area/lavaland/surface/outdoors) (1,1,1) = {" aaaaaaaaaaaaaaaaabababababababaaaaaaaaaaaa -aaaaaaaaaaaaababababacacabacababaaaaaaaaaa -aaaaaaaaaaaaababacabacacacababababaaaaaaaa -aaaaaaaaaaababacacacacadacacacababaaaaaaaa -aaaaaaaaaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaa -aaaaababaeagahaeaiajakalamaeanaoapaqaraeaa -aaaaababaeagagaeasatasauasaeavaoaoaoawaeaa +aaaaaaaaaaaaababababacacabacabababaaaaaaaa +aaaaaaaaaaaaababacabacacacbXbYbZabababaaaa +aaaaaaaaaaababacacacacadaccacacbacacababaa +aaaaaaaaaeaeaeaeaeafafafaeaeaeccaeaeaeaeaa +aaaaababaeagahaeaiajakalamaecdceapaqaraeaa +aaaaababaeagagaeasatasauasaeanaoaoaoawaeaa aaababaxaeayagaeasasazasasaeaAaoaBaCaDaeaa abababacaEaeaFaGaFaeaeaeaFaHaeaFaIaIaIaeaa -ababaJaJaFaKaKaLaKaMaMaMaKaLaLaKaLaNaOaeaa +ababaJaJaFaKaKaLaKaMaMaMaKaLcfaKaLaNaOaeaa abababacaeaKaKaPaPaKaPaKaPaPaPaKaPaQaRaeaa aaababaeaEaFaEaeaeaFaeaFaeaeaEaFaeaSaRaeaa ababacaeaTaUaeaVaWaoaeaoaWaVaeaXaeaSaRaeaa aaababaeaYaZaebaaobbaebcaobdaebeaeaSaRaeaa aaaaaaaebfbgaebhbiaoaeaoaobjaebkaeaSaRaeaa aaaaaaaeaEaFaEaGaeaFaeaFaeaeaeaeaEaSaRaeaa -aaaaaaaaaeaKaLaLaLaKblaKbmaebnboafaSaRaeaa +aaaaaaaaaeaKaLaLaLaKblaKbmaebnboafavaRaeaa aaaaaaaaaebpbqbrbsaKbtaKbuaebvbwbxaKaRaeaa aaaaaaaaaebybzbAbBaKaKaKbuaebCbDaebEaRaeaa aaaaaaaaaebFaPaPaPaKaKaPbGaeaeaeaEbHaRaeaa diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_ash_walker1.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_ash_walker1.dmm index 91d2e091cae..0d13efc45a1 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_ash_walker1.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_ash_walker1.dmm @@ -11,19 +11,19 @@ "k" = (/obj/effect/mob_spawn/human/corpse/damaged,/turf/open/floor/engine/cult{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/unpowered) "l" = (/obj/structure/closet/crate/radiation,/obj/item/device/flashlight/lantern,/obj/item/device/flashlight/lantern,/obj/item/device/flashlight/lantern,/obj/item/device/flashlight/flare,/turf/open/floor/engine/cult{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/unpowered) "m" = (/obj/structure/closet/crate/medical,/obj/item/device/malf_upgrade,/turf/open/floor/engine/cult{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/unpowered) -"n" = (/obj/structure/closet/crate/hydroponics,/obj/item/weapon/storage/belt,/obj/item/weapon/scythe,/turf/open/floor/engine/cult{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/unpowered) +"n" = (/obj/structure/closet/crate/hydroponics,/obj/item/weapon/storage/belt,/obj/item/weapon/scythe,/obj/item/seeds/glowshroom,/obj/item/seeds/glowshroom,/obj/item/weapon/reagent_containers/glass/bucket,/turf/open/floor/engine/cult{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/unpowered) "o" = (/obj/item/device/flashlight/lantern,/turf/open/floor/engine/cult{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/unpowered) "p" = (/obj/item/device/flashlight/seclite,/obj/item/device/flashlight,/obj/structure/closet/crate,/obj/item/device/flashlight,/obj/item/device/flashlight,/obj/item/device/flashlight,/turf/open/floor/engine/cult{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/unpowered) "q" = (/obj/item/device/flashlight/flare,/obj/item/device/flashlight/seclite,/obj/item/device/flashlight/seclite,/obj/item/device/flashlight,/obj/structure/closet/crate,/obj/item/device/flashlight,/obj/item/device/flashlight,/obj/item/device/flashlight,/turf/open/floor/engine/cult{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/unpowered) "r" = (/turf/closed/wall/mineral/iron{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/unpowered) "s" = (/obj/item/weapon/twohanded/spear,/obj/structure/mineral_door/iron,/turf/open/floor/engine/cult{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/unpowered) "t" = (/obj/structure/mineral_door/iron,/turf/open/floor/engine/cult{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/unpowered) -"u" = (/obj/structure/closet/crate,/obj/item/weapon/rcd/loaded,/turf/open/floor/engine/cult{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/unpowered) -"v" = (/obj/structure/closet/crate,/obj/item/weapon/storage/firstaid/regular,/obj/item/weapon/storage/firstaid/regular,/turf/open/floor/engine/cult{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/unpowered) +"u" = (/obj/structure/closet/crate/engineering,/obj/item/weapon/rcd/loaded,/turf/open/floor/engine/cult{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/unpowered) +"v" = (/obj/structure/closet/crate/medical,/obj/item/weapon/storage/firstaid/regular,/obj/item/weapon/reagent_containers/blood/random,/turf/open/floor/engine/cult{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/unpowered) "w" = (/obj/machinery/the_singularitygen,/turf/open/floor/engine/cult{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/unpowered) -"x" = (/obj/structure/rack{icon = 'icons/obj/stationobjs.dmi'; icon_state = "minibar_left"; name = "skeletal minibar"},/turf/open/floor/engine/cult{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/unpowered) -"y" = (/obj/structure/rack{icon = 'icons/obj/stationobjs.dmi'; icon_state = "minibar_right"; name = "skeletal minibar"},/obj/item/clothing/head/helmet/roman/legionaire,/turf/open/floor/engine/cult{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/unpowered) -"z" = (/obj/item/weapon/shovel,/turf/open/floor/engine/cult{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/unpowered) +"x" = (/obj/structure/rack{icon = 'icons/obj/stationobjs.dmi';icon_state = "minibar_left";name = "skeletal minibar"},/obj/item/stack/sheet/cloth/ten,/turf/open/floor/engine/cult{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/unpowered) +"y" = (/obj/structure/rack{icon = 'icons/obj/stationobjs.dmi';icon_state = "minibar_right";name = "skeletal minibar"},/obj/item/clothing/head/helmet/roman/legionaire,/turf/open/floor/engine/cult{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/unpowered) +"z" = (/obj/item/weapon/shovel,/obj/effect/decal/cleanable/cobweb2,/turf/open/floor/engine/cult{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/unpowered) "A" = (/obj/structure/closet/crate,/obj/item/weapon/storage/firstaid/regular,/obj/item/weapon/storage/firstaid/o2,/turf/open/floor/engine/cult{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/unpowered) "B" = (/obj/structure/table_frame,/turf/open/floor/engine/cult{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/unpowered) "C" = (/obj/structure/table/optable,/turf/open/floor/engine/cult{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/unpowered) @@ -32,12 +32,16 @@ "F" = (/obj/structure/closet/crate/miningcar,/turf/open/floor/plating/asteroid/basalt/lava_land_surface,/area/lavaland/surface/outdoors) "G" = (/obj/item/weapon/twohanded/spear,/obj/structure/rack,/obj/item/weapon/twohanded/spear,/obj/item/weapon/twohanded/spear,/obj/item/weapon/twohanded/spear,/turf/open/floor/engine/cult{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/unpowered) "H" = (/obj/item/weapon/twohanded/spear,/obj/structure/rack,/turf/open/floor/engine/cult{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/unpowered) -"I" = (/obj/structure/mineral_door/iron,/turf/open/floor/engine/cult{baseturf = /turf/open/floor/plating/lava/smooth; blocks_air = 1},/area/ruin/unpowered) +"I" = (/obj/structure/mineral_door/iron,/turf/open/floor/engine/cult{baseturf = /turf/open/floor/plating/lava/smooth;blocks_air = 1},/area/ruin/unpowered) "J" = (/turf/closed/wall/cult{baseturf = /turf/open/floor/plating/lava/smooth},/area/lavaland/surface/outdoors) -"K" = (/turf/open/floor/engine/cult{baseturf = /turf/open/floor/plating/lava/smooth; initial_gas_mix = "o2=13;n2=24;TEMP=300"},/area/lavaland/surface/outdoors) +"K" = (/turf/open/floor/engine/cult{baseturf = /turf/open/floor/plating/lava/smooth;initial_gas_mix = "o2=13;n2=24;TEMP=300"},/area/lavaland/surface/outdoors) "L" = (/obj/item/weapon/twohanded/spear,/obj/structure/table,/turf/open/floor/engine/cult{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/unpowered) -"M" = (/obj/item/weapon/pickaxe,/turf/open/floor/engine/cult{baseturf = /turf/open/floor/plating/lava/smooth; initial_gas_mix = "o2=13;n2=24;TEMP=300"},/area/lavaland/surface/outdoors) +"M" = (/obj/item/weapon/pickaxe,/turf/open/floor/engine/cult{baseturf = /turf/open/floor/plating/lava/smooth;initial_gas_mix = "o2=13;n2=24;TEMP=300"},/area/lavaland/surface/outdoors) "N" = (/obj/structure/ore_box,/turf/open/floor/plating/asteroid/basalt/lava_land_surface,/area/lavaland/surface/outdoors) +"R" = (/mob/living/simple_animal/hostile/asteroid/gutlunch/gubbuck,/turf/open/floor/engine/cult{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/unpowered) +"Q" = (/mob/living/simple_animal/hostile/asteroid/gutlunch/guthen,/turf/open/floor/engine/cult{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/unpowered) +"P" = (/obj/machinery/iv_drip,/turf/open/floor/engine/cult{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/unpowered) +"O" = (/obj/item/weapon/reagent_containers/glass/bowl,/turf/open/floor/engine/cult{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/unpowered) (1,1,1) = {" aabaaaaaaaaabb @@ -45,13 +49,13 @@ aaaaaaaaaaaabb aaaaccccccaaab aaaacdefgcaaab aaaacehifcaaab -baaccifffccaaa +baacciffOccaaa baacjfkfflcaaa aaacmnfopqcaaa aaccrrstrrccaa aacuvwffxyzcaa -aacAfffkffBcaa -aacCfDffffEcaa +aacAPffkQfBcaa +aacCRDffffEcaa bFrGfHrIrrrraa JKrLLHrKbKMNaa JKrrrrrbbbbbaa diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_biodome_winter.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_biodome_winter.dmm index 64e43646095..fbf9af94e17 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_biodome_winter.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_biodome_winter.dmm @@ -1,62 +1,103 @@ -"a" = (/turf/open/floor/plating/asteroid/basalt/lava_land_surface,/area/lavaland/surface/outdoors) -"b" = (/turf/closed/wall/r_wall,/area/ruin/powered/snow_biodome) -"c" = (/turf/open/floor/plating{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/powered/snow_biodome) -"d" = (/obj/structure/grille,/obj/structure/window/fulltile,/turf/open/floor/plating{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/powered/snow_biodome) -"e" = (/turf/open/floor/plating/ice,/area/ruin/powered/snow_biodome) -"f" = (/turf/open/floor/plating/asteroid/snow{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/powered/snow_biodome) -"g" = (/obj/structure/flora/rock/icy,/turf/open/floor/plating/asteroid/snow{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/powered/snow_biodome) -"h" = (/obj/structure/flora/bush,/turf/open/floor/plating/asteroid/snow{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/powered/snow_biodome) -"i" = (/turf/closed/wall/mineral/wood,/area/ruin/powered/snow_biodome) -"j" = (/obj/structure/dresser,/turf/open/floor/wood{baseturf = /turf/open/floor/plating/lava/smooth; name = "floor"},/area/ruin/powered/snow_biodome) -"k" = (/obj/structure/bed,/turf/open/floor/wood{baseturf = /turf/open/floor/plating/lava/smooth; name = "floor"},/area/ruin/powered/snow_biodome) -"l" = (/obj/structure/bookcase/random,/turf/open/floor/wood{baseturf = /turf/open/floor/plating/lava/smooth; name = "floor"},/area/ruin/powered/snow_biodome) -"m" = (/obj/structure/flora/tree/pine,/turf/open/floor/plating/asteroid/snow{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/powered/snow_biodome) -"n" = (/obj/structure/flora/grass/both,/turf/open/floor/plating/asteroid/snow{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/powered/snow_biodome) -"o" = (/turf/open/floor/wood{baseturf = /turf/open/floor/plating/lava/smooth; name = "floor"},/area/ruin/powered/snow_biodome) -"p" = (/obj/structure/flora/tree/dead,/turf/open/floor/plating/asteroid/snow{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/powered/snow_biodome) -"q" = (/obj/machinery/door/airlock/wood,/turf/open/floor/wood{baseturf = /turf/open/floor/plating/lava/smooth; name = "floor"},/area/ruin/powered/snow_biodome) -"r" = (/obj/structure/chair/comfy/brown{tag = "icon-comfychair (EAST)"; icon_state = "comfychair"; dir = 4},/turf/open/floor/wood{baseturf = /turf/open/floor/plating/lava/smooth; name = "floor"},/area/ruin/powered/snow_biodome) -"s" = (/obj/structure/table/wood,/turf/open/floor/wood{baseturf = /turf/open/floor/plating/lava/smooth; name = "floor"},/area/ruin/powered/snow_biodome) -"t" = (/obj/structure/chair/comfy/brown{tag = "icon-comfychair (WEST)"; icon_state = "comfychair"; dir = 8},/turf/open/floor/wood{baseturf = /turf/open/floor/plating/lava/smooth; name = "floor"},/area/ruin/powered/snow_biodome) -"u" = (/turf/closed/wall/mineral/wood{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/powered/snow_biodome) -"v" = (/obj/structure/displaycase/captain,/turf/open/floor/wood{baseturf = /turf/open/floor/plating/lava/smooth; name = "floor"},/area/ruin/powered/snow_biodome) -"w" = (/obj/structure/bed/dogbed,/turf/open/floor/wood{baseturf = /turf/open/floor/plating/lava/smooth; name = "floor"},/area/ruin/powered/snow_biodome) -"x" = (/obj/structure/flora/tree/pine/xmas,/turf/open/floor/plating/asteroid/snow{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/powered/snow_biodome) -"y" = (/obj/machinery/door/airlock/hatch,/turf/open/floor/plating{baseturf = /turf/open/floor/plating/lava/smooth; blocks_air = 1},/area/ruin/powered/snow_biodome) -"z" = (/obj/machinery/door/airlock/silver,/turf/open/floor/plating{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/powered/snow_biodome) -"A" = (/obj/structure/flora/rock/pile/icy,/turf/open/floor/plating/asteroid/snow{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/powered/snow_biodome) -"B" = (/turf/open/floor/wood{baseturf = /turf/open/floor/plating/lava/smooth; name = "bridge"},/area/ruin/powered/snow_biodome) -"C" = (/turf/closed/wall/r_wall{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/powered/snow_biodome) +"aa" = (/turf/template_noop,/area/template_noop) +"ab" = (/turf/closed/wall/r_wall{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/powered/snow_biodome) +"ac" = (/obj/item/stack/medical/ointment,/obj/structure/table,/obj/item/stack/medical/bruise_pack,/turf/open/floor/plating{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/powered/snow_biodome) +"ad" = (/obj/structure/table,/obj/item/stack/medical/gauze,/obj/item/stack/medical/gauze,/turf/open/floor/plating{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/powered/snow_biodome) +"ae" = (/obj/machinery/power/smes,/turf/open/floor/plating{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/powered/snow_biodome) +"af" = (/turf/open/floor/plating{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/powered/snow_biodome) +"ag" = (/obj/structure/reagent_dispensers/beerkeg,/turf/open/floor/plating{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/powered/snow_biodome) +"ah" = (/obj/item/weapon/reagent_containers/food/drinks/mug,/turf/open/floor/plating{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/powered/snow_biodome) +"ai" = (/obj/machinery/shower,/turf/open/floor/plating{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/powered/snow_biodome) +"aj" = (/obj/structure/sink,/turf/open/floor/plating{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/powered/snow_biodome) +"ak" = (/turf/open/floor/plating/asteroid/snow{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/powered/snow_biodome) +"al" = (/obj/effect/decal/cleanable/oil,/turf/open/floor/plating{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/powered/snow_biodome) +"am" = (/obj/machinery/door/airlock/hatch,/turf/open/floor/plating{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/powered/snow_biodome) +"an" = (/obj/structure/toilet{dir = 8},/turf/open/floor/plating{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/powered/snow_biodome) +"ao" = (/turf/open/floor/plating/ice,/area/ruin/powered/snow_biodome) +"ap" = (/obj/structure/flora/rock/icy,/turf/open/floor/plating/asteroid/snow{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/powered/snow_biodome) +"aq" = (/turf/closed/wall/mineral/wood,/area/ruin/powered/snow_biodome) +"ar" = (/obj/machinery/door/airlock/wood,/turf/open/floor/plating{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/powered/snow_biodome) +"as" = (/obj/structure/fans,/turf/closed/wall/mineral/wood,/area/ruin/powered/snow_biodome) +"at" = (/turf/open/floor/wood{baseturf = /turf/open/floor/plating/lava/smooth; name = "floor"},/area/ruin/powered/snow_biodome) +"au" = (/obj/structure/bed,/obj/item/weapon/bedsheet/blue,/turf/open/floor/wood{baseturf = /turf/open/floor/plating/lava/smooth; name = "floor"},/area/ruin/powered/snow_biodome) +"av" = (/obj/structure/bookcase/random,/turf/open/floor/wood{baseturf = /turf/open/floor/plating/lava/smooth; name = "floor"},/area/ruin/powered/snow_biodome) +"aw" = (/obj/structure/table/wood,/turf/open/floor/wood{baseturf = /turf/open/floor/plating/lava/smooth; name = "floor"},/area/ruin/powered/snow_biodome) +"ax" = (/obj/structure/table/wood,/obj/item/weapon/reagent_containers/food/snacks/beans,/turf/open/floor/wood{baseturf = /turf/open/floor/plating/lava/smooth; name = "floor"},/area/ruin/powered/snow_biodome) +"ay" = (/obj/structure/closet/crate/trashcart,/obj/item/trash/semki,/obj/item/trash/candy,/turf/open/floor/plating/asteroid/snow{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/powered/snow_biodome) +"az" = (/obj/structure/flora/tree/pine,/turf/open/floor/plating/asteroid/snow{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/powered/snow_biodome) +"aA" = (/obj/structure/chair/comfy/brown{tag = "icon-comfychair (EAST)"; icon_state = "comfychair"; dir = 4},/turf/open/floor/wood{baseturf = /turf/open/floor/plating/lava/smooth; name = "floor"},/area/ruin/powered/snow_biodome) +"aB" = (/obj/structure/flora/rock/pile/icy,/turf/open/floor/plating/asteroid/snow{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/powered/snow_biodome) +"aC" = (/obj/structure/flora/tree/dead,/turf/open/floor/plating/asteroid/snow{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/powered/snow_biodome) +"aD" = (/obj/machinery/door/airlock/wood,/turf/open/floor/wood{baseturf = /turf/open/floor/plating/lava/smooth; name = "floor"},/area/ruin/powered/snow_biodome) +"aE" = (/obj/structure/extinguisher_cabinet,/turf/closed/wall/mineral/wood,/area/ruin/powered/snow_biodome) +"aF" = (/obj/structure/table/wood,/obj/item/weapon/reagent_containers/food/drinks/mug/coco,/turf/open/floor/wood{baseturf = /turf/open/floor/plating/lava/smooth; name = "floor"},/area/ruin/powered/snow_biodome) +"aG" = (/obj/structure/chair/comfy/brown{tag = "icon-comfychair (WEST)"; icon_state = "comfychair"; dir = 8},/turf/open/floor/wood{baseturf = /turf/open/floor/plating/lava/smooth; name = "floor"},/area/ruin/powered/snow_biodome) +"aH" = (/mob/living/simple_animal/hostile/skeleton/eskimo,/turf/open/floor/wood{baseturf = /turf/open/floor/plating/lava/smooth; name = "floor"},/area/ruin/powered/snow_biodome) +"aI" = (/obj/structure/flora/bush,/turf/open/floor/plating/asteroid/snow{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/powered/snow_biodome) +"aJ" = (/obj/vehicle/atv,/turf/open/floor/plating/asteroid/snow{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/powered/snow_biodome) +"aK" = (/turf/closed/wall/mineral/wood{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/powered/snow_biodome) +"aL" = (/obj/structure/displaycase/captain,/turf/open/floor/wood{baseturf = /turf/open/floor/plating/lava/smooth; name = "floor"},/area/ruin/powered/snow_biodome) +"aM" = (/turf/open/floor/carpet{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/powered/snow_biodome) +"aN" = (/obj/structure/bed/dogbed,/turf/open/floor/wood{baseturf = /turf/open/floor/plating/lava/smooth; name = "floor"},/area/ruin/powered/snow_biodome) +"aO" = (/obj/machinery/door/airlock/glass_large,/obj/structure/fans/tiny,/turf/open/floor/pod/dark,/area/ruin/powered/snow_biodome) +"aP" = (/obj/structure/fans/tiny,/turf/open/floor/pod/dark,/area/ruin/powered/snow_biodome) +"aQ" = (/obj/structure/flora/grass/both,/turf/open/floor/plating/asteroid/snow{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/powered/snow_biodome) +"aR" = (/obj/structure/flora/tree/pine/xmas,/turf/open/floor/plating/asteroid/snow{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/powered/snow_biodome) +"aS" = (/obj/structure/rack,/obj/item/clothing/suit/hooded/wintercoat/science,/obj/item/clothing/shoes/winterboots,/obj/item/clothing/gloves/fingerless,/turf/open/floor/pod/dark,/area/ruin/powered/snow_biodome) +"aT" = (/obj/structure/grille,/obj/structure/window/fulltile,/turf/open/floor/plating{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/powered/snow_biodome) +"aU" = (/obj/machinery/vending/coffee,/turf/open/floor/pod/dark,/area/ruin/powered/snow_biodome) +"aV" = (/obj/structure/closet/secure_closet/freezer/fridge,/turf/open/floor/pod/dark,/area/ruin/powered/snow_biodome) +"aW" = (/turf/open/floor/pod/dark,/area/ruin/powered/snow_biodome) +"aX" = (/turf/open/floor/pod/light,/area/ruin/powered/snow_biodome) +"aY" = (/obj/structure/chair/stool,/turf/open/floor/pod/dark,/area/ruin/powered/snow_biodome) +"aZ" = (/obj/machinery/door/airlock/hatch,/obj/structure/fans/tiny,/turf/open/floor/pod/dark,/area/ruin/powered/snow_biodome) +"ba" = (/obj/machinery/door/airlock/silver,/turf/open/floor/pod/dark,/area/ruin/powered/snow_biodome) +"bb" = (/obj/machinery/door/airlock/silver,/turf/open/floor/plating{baseturf = /turf/open/floor/plating/lava/smooth},/area/ruin/powered/snow_biodome) +"bc" = (/obj/structure/table,/turf/open/floor/pod/dark,/area/ruin/powered/snow_biodome) +"bd" = (/obj/structure/table,/obj/item/weapon/pen,/obj/item/weapon/paper_bin,/turf/open/floor/pod/dark,/area/ruin/powered/snow_biodome) +"be" = (/obj/structure/table,/obj/machinery/microwave,/turf/open/floor/pod/dark,/area/ruin/powered/snow_biodome) +"bf" = (/obj/effect/decal/cleanable/oil,/turf/open/floor/pod/dark,/area/ruin/powered/snow_biodome) +"bg" = (/obj/item/weapon/twohanded/required/chainsaw,/obj/structure/closet,/turf/open/floor/pod/dark,/area/ruin/powered/snow_biodome) +"bh" = (/obj/structure/filingcabinet,/turf/open/floor/pod/dark,/area/ruin/powered/snow_biodome) +"bi" = (/obj/machinery/computer/monitor,/turf/open/floor/pod/dark,/area/ruin/powered/snow_biodome) +"bj" = (/obj/item/weapon/storage/toolbox/mechanical,/turf/open/floor/pod/dark,/area/ruin/powered/snow_biodome) +"bk" = (/obj/structure/reagent_dispensers/fueltank,/turf/open/floor/pod/dark,/area/ruin/powered/snow_biodome) +"bl" = (/turf/open/floor/wood{baseturf = /turf/open/floor/plating/lava/smooth; name = "bridge"},/area/ruin/powered/snow_biodome) +"bm" = (/turf/open/floor/plating/asteroid/basalt/lava_land_surface,/area/ruin/powered/snow_biodome) +"bn" = (/obj/item/clothing/mask/balaclava,/turf/open/floor/pod/dark,/area/ruin/powered/snow_biodome) +"bo" = (/obj/structure/table,/obj/item/weapon/storage/fancy/cigarettes/cigpack_carp,/turf/open/floor/pod/dark,/area/ruin/powered/snow_biodome) +"bp" = (/obj/structure/table,/obj/item/weapon/pen,/obj/item/weapon/paper,/turf/open/floor/pod/dark,/area/ruin/powered/snow_biodome) +"bq" = (/obj/machinery/light/built{dir = 1},/turf/open/floor/pod/dark,/area/ruin/powered/snow_biodome) +"br" = (/obj/structure/fans/tiny,/obj/machinery/door/airlock/glass_large,/turf/open/floor/pod/dark,/area/ruin/powered/snow_biodome) (1,1,1) = {" -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb -bccccccccccccccccccccccccccccb -bcddddddddddddddddddddddddddcb -bcdeefgfffffffffhiiiiiiiiiidcb -bcdfeeffffhfffffhijkilllllidcb -bcdfeeeemfffmffnfiooioooooidcb -bcdpfeeeffpffffffiqiiorstoidcb -bcdfheeeefffhffffioooorstoidcb -bcdhfffeefffhmhfnuvoooooowidcb -bcdffhfeeefffffffiiiiqqiiiidcb -bcdfffffeeffffgffffffffffffdcb -bcdfmfffeeemffffhffffffffxfdcb -bcdfffffeeeffpfnfffffffffffdcb -bcdnfffffeeeefffffmfffmhhffdcb -yczfAfmffeeeeeffffffpffffffdcb -bcdffffffffeeffmfffhffngfffdcb -bcdfffpffhfeeefffffffffffmfdcb -bcdfmffffmfeeeeffffmffpffffdcb -bcdffffgffBBBBBBfpffffffnffdcb -bcdffnhhffBBBBBBffffgfhffffdcb -bcdfffhfffffeeeffffffhfffffdcb -bcdffffnpfhfffeeefffffmfAmfdcb -bcdffffffffffhffeefmffhhfffdcb -bcdhfmfffhfmffffeefffnhhffhdcb -bcdfffffffffhhfhfeeeffffpffdcb -bcdhhffmfffffpfffffeeffffffdcb -bcddddddddddddddddddddddddddcb -bccccccccccccccccccccccccccccb -bbbbbCbbbbbbbbbbbbbbbbbbbbbbbb +aaaaaaaaaaaaaaaaaaababababababababababababaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaababababacadaeafaeagahabaiajababababaaaaaaaaaaaa +aaaaaaaaabababakabafafafafalafahafamafafanabakabababaaaaaaaa +aaaaaaababaoapakababaqaraqaqaqasaqaqaqaqababakakapababaaaaaa +aaaaababaoaoakakakakaqatauaqavawaxavavaqayakazakakakababaaaa +aaaaabakaoaoaoakazakaqatauaqataAawatataqakakakaBakakakabaaaa +aaababaCakaoaoakakakaqaDaqaEataAaFaGaHaqakaIaJakakazakababaa +aaabakakaIaoaoaoakakaqatatataHatatatataqakakakakakakakakabaa +aaabakakakakaoaoaoakaKaLatataMaMatataNaqakapakaCakakakakabaa +aaabakakakaIakaoaoakaqaqaqaqaOaPaqaqaqaqakakakakaQakakakabaa +ababababakakakaoaoakakakakakapakakaRakakakakakakakakabababab +abaSaSaTazakakakaoaoaoazakakakakaIakakakakakakakakakaTaUaVab +abaWaWaTakakakakaoaoaoakakaCakaQakakakakakakakakakakaTaWaWab +abaWaWaTaBakakakakaoaoaoaoakakakakakazakakakazaIaIakaTaXaYab +aZaXaXbaakakazakakaoaoaoaoaoakakakakakakaCakakakakakbbaXbcab +abaWbdaTakakakakakakaoaoaoakakazakakakaIakakaQapakakaTaXbeab +abaWaYaTakakaCakakaIakaoaoaoakakakakakakakakakakakazaTbfbgab +abbhbiaTaIakakakakazakaoaoaoaoakakakakazakakaCakakakaTbjbkab +ababababakakakapakakblblblblblblakaCakakakakakakaQakabababab +ababakakakaQaIaIakakblblblblblblakakakakapakaIakakakakakabaa +ababakakakakaIakakakakakaoaoaoakakakakakakaIakakakakakakabaa +aaabakakakakakaQaCakaIakakaoaoaoaoakakakakakazakaBazakakabaa +aaababakakakakakakakakakakaIakaoaoaoakazakakaIaIakakakababaa +aaaaabakakazakakakaIakazakakakakaoaoaoakakaQaIaIakakakabaaaa +aaaaababakakakakakakakakaIakakakakaoaoaoakakakakaCakababaaaa +aaaabmababakakazakakababababaOaPababababakakakakakababbmaaaa +aaaabmbmabababakakakabaSbnaXaXaXaXaWboabakakakabababbmbmaaaa +aaaaaabmbmbmabababababaSaWaXaXaXaXaWbpabababababbmbmbmaaaaaa +aaaaaaaabmbmbmbmbqbmababababbraPababababbmbqbmbmbmaaaaaaaaaa +aaaaaaaaaaaaaabmbmbmbmbmbmbmbmbmbmbmbmbmbmbmbmaaaaaaaaaaaaaa "} diff --git a/_maps/map_files/BirdStation/BirdStation.dmm b/_maps/map_files/BirdStation/BirdStation.dmm index a0912232dcc..5ecccfef356 100644 --- a/_maps/map_files/BirdStation/BirdStation.dmm +++ b/_maps/map_files/BirdStation/BirdStation.dmm @@ -2781,7 +2781,7 @@ "bbA" = (/obj/structure/grille,/obj/structure/cable/cyan{icon_state = "0-8"},/obj/structure/cable/cyan{icon_state = "4-8"},/obj/structure/cable/cyan{icon_state = "2-4"},/obj/structure/cable/cyan{icon_state = "1-4"},/turf/open/floor/plating,/area/maintenance/asmaint2) "bbB" = (/obj/structure/cable/cyan{icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/cyan/hidden,/turf/open/floor/plating,/area/maintenance/asmaint2) "bbC" = (/obj/structure/cable/cyan{icon_state = "1-8"},/turf/open/floor/plating,/area/maintenance/asmaint2) -"bbD" = (/obj/effect/spawner/lootdrop{loot = list(/obj/item/organ/internal/gland/bloody = 7, /obj/item/organ/internal/gland/bodysnatch = 4, /obj/item/organ/internal/gland/egg = 7, /obj/item/organ/internal/gland/emp = 3, /obj/item/organ/internal/gland/mindshock = 5, /obj/item/organ/internal/gland/plasma = 7, /obj/item/organ/internal/gland/pop = 5, /obj/item/organ/internal/gland/slime = 4, /obj/item/organ/internal/gland/spiderman = 5, /obj/item/organ/internal/gland/ventcrawling = 1, /obj/item/organ/internal/body_egg/alien_embryo = 1, /obj/item/organ/internal/hivelord_core = 2); lootcount = 3; name = "organ spawner"},/obj/structure/closet/secure_closet{name = "xenobiology research materials locker"; req_access_txt = "55"},/turf/open/floor/plasteel/white,/area/toxins/xenobiology) +"bbD" = (/obj/effect/spawner/lootdrop{loot = list(/obj/item/organ/gland/bloody = 7, /obj/item/organ/gland/bodysnatch = 4, /obj/item/organ/gland/egg = 7, /obj/item/organ/gland/emp = 3, /obj/item/organ/gland/mindshock = 5, /obj/item/organ/gland/plasma = 7, /obj/item/organ/gland/pop = 5, /obj/item/organ/gland/slime = 4, /obj/item/organ/gland/spiderman = 5, /obj/item/organ/gland/ventcrawling = 1, /obj/item/organ/body_egg/alien_embryo = 1, /obj/item/organ/hivelord_core = 2); lootcount = 3; name = "organ spawner"},/obj/structure/closet/secure_closet{name = "xenobiology research materials locker"; req_access_txt = "55"},/turf/open/floor/plasteel/white,/area/toxins/xenobiology) "bbE" = (/mob/living/simple_animal/mouse/brown,/turf/open/floor/wood,/area/maintenance/fore{name = "Security Maintenance"}) "bbF" = (/obj/effect/spawner/lootdrop/crate_spawner,/turf/open/floor/plating,/area/maintenance/fore{name = "Security Maintenance"}) "bbG" = (/obj/structure/closet/crate{name = "solar pack crate"},/obj/item/solar_assembly,/obj/item/solar_assembly,/obj/item/solar_assembly,/obj/item/solar_assembly,/obj/item/solar_assembly,/obj/item/solar_assembly,/obj/item/solar_assembly,/obj/item/solar_assembly,/obj/item/solar_assembly,/obj/item/solar_assembly,/obj/item/solar_assembly,/obj/item/solar_assembly,/obj/item/solar_assembly,/obj/item/weapon/circuitboard/solar_control,/obj/item/weapon/electronics/tracker,/obj/item/weapon/paper/solar,/turf/open/floor/plating,/area/maintenance/fore{name = "Security Maintenance"}) diff --git a/_maps/map_files/BirdStation/z5.dmm b/_maps/map_files/BirdStation/z5.dmm index 3466e3566b1..95e62d3e425 100644 --- a/_maps/map_files/BirdStation/z5.dmm +++ b/_maps/map_files/BirdStation/z5.dmm @@ -56,7 +56,7 @@ "bd" = (/turf/closed/mineral/diamond,/area/mine/unexplored) "be" = (/mob/living/simple_animal/hostile/asteroid/basilisk,/turf/open/floor/plating/asteroid/airless,/area/mine/explored) "bf" = (/obj/structure/alien/weeds,/turf/open/floor/plating/asteroid/airless,/area/mine/explored) -"bg" = (/obj/effect/spawner/lootdrop{loot = list(/obj/item/organ/internal/body_egg/alien_embryo = 5, /obj/structure/alien/egg = 1); name = "xeno egg spawner2"},/turf/open/floor/plating/asteroid/airless,/area/mine/explored) +"bg" = (/obj/effect/spawner/lootdrop{loot = list(/obj/item/organ/body_egg/alien_embryo = 5, /obj/structure/alien/egg = 1); name = "xeno egg spawner2"},/turf/open/floor/plating/asteroid/airless,/area/mine/explored) "bh" = (/mob/living/simple_animal/hostile/asteroid/fugu,/turf/open/floor/plating/asteroid/airless,/area/mine/explored) "bi" = (/turf/closed/mineral/random/high_chance,/area/mine/explored) "bj" = (/turf/closed/mineral/clown,/area/mine/explored) diff --git a/_maps/map_files/MetaStation/MetaStation.v41I.dmm b/_maps/map_files/MetaStation/MetaStation.v41I.dmm index dd60f599a3f..9a976b2f168 100644 --- a/_maps/map_files/MetaStation/MetaStation.v41I.dmm +++ b/_maps/map_files/MetaStation/MetaStation.v41I.dmm @@ -60283,9 +60283,7 @@ pixel_y = 0 }, /obj/item/weapon/folder/blue, -/obj/item/clothing/head/collectable/HoS{ - desc = "It's your turn to demand excessive paperwork, signatures, stamps, and hire more clowns! Papers, please!"; - icon_state = "hopcap"; +/obj/item/clothing/head/collectable/HoP{ name = "novelty HoP hat" }, /obj/machinery/light/small{ @@ -90522,7 +90520,7 @@ /obj/item/weapon/nullrod{ pixel_x = 4 }, -/obj/item/organ/internal/heart, +/obj/item/organ/heart, /obj/item/device/soulstone/anybody, /obj/effect/landmark{ name = "revenantspawn" diff --git a/_maps/map_files/TgStation/tgstation.2.1.3.dmm b/_maps/map_files/TgStation/tgstation.2.1.3.dmm index 93ee4f95305..4b6ad4ccfca 100644 --- a/_maps/map_files/TgStation/tgstation.2.1.3.dmm +++ b/_maps/map_files/TgStation/tgstation.2.1.3.dmm @@ -52505,7 +52505,9 @@ /area/solar/port) "ccY" = ( /obj/structure/table, -/obj/item/weapon/storage/fancy/cigarettes, +/obj/item/weapon/kitchen/rollingpin, +/obj/item/weapon/reagent_containers/food/condiment/enzyme, +/obj/item/weapon/reagent_containers/food/condiment/sugar, /turf/open/floor/plating, /area/maintenance/aft) "ccZ" = ( @@ -53384,9 +53386,11 @@ /turf/open/floor/plating, /area/maintenance/asmaint2) "ceV" = ( -/obj/item/clothing/under/rank/vice, /obj/structure/closet, -/obj/item/clothing/shoes/jackboots, +/obj/effect/spawner/lootdrop/maintenance{ + lootcount = 2; + name = "2maintenance loot spawner" + }, /turf/open/floor/plating, /area/maintenance/aft) "ceW" = ( @@ -63979,8 +63983,9 @@ /turf/open/floor/plating/airless, /area/space/nearstation) "cAy" = ( +/obj/structure/closet/secure_closet/freezer/kitchen/maintenance, /turf/open/floor/plating, -/area/maintenance/electrical) +/area/maintenance/aft) "cAz" = ( /obj/structure/disposalpipe/segment{ dir = 1; @@ -63994,39 +63999,42 @@ }, /area/chapel/office) "cAA" = ( -/turf/open/floor/wood, -/area/crew_quarters/bar) -"cAB" = ( -/obj/structure/disposalpipe/segment, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/open/floor/plasteel{ - icon_state = "showroomfloor" - }, -/area/crew_quarters/kitchen) -"cAC" = ( -/turf/open/floor/plasteel{ - icon_state = "cafeteria" - }, -/area/crew_quarters/kitchen) -"cAD" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/turf/open/floor/plating{ - icon_state = "warnplate"; +/obj/machinery/light/small{ dir = 1 }, -/area/maintenance/disposal) +/turf/open/floor/plating, +/area/maintenance/aft) +"cAB" = ( +/obj/structure/table, +/obj/machinery/microwave, +/turf/open/floor/plating, +/area/maintenance/aft) +"cAC" = ( +/obj/structure/sink/kitchen{ + dir = 8; + pixel_x = 11 + }, +/turf/open/floor/plating, +/area/maintenance/aft) +"cAD" = ( +/obj/structure/table, +/obj/item/weapon/kitchen/knife, +/obj/item/weapon/storage/box/donkpockets, +/turf/open/floor/plating, +/area/maintenance/aft) "cAE" = ( -/obj/structure/cable{ - d1 = 1; - d2 = 2; - icon_state = "1-2" +/obj/structure/table/glass, +/obj/item/weapon/reagent_containers/food/condiment/saltshaker{ + pixel_y = 2 }, -/turf/open/floor/plasteel{ - icon_state = "dark" +/obj/item/weapon/reagent_containers/food/condiment/peppermill{ + pixel_x = 2 }, -/area/medical/morgue) +/obj/item/weapon/reagent_containers/food/snacks/mint{ + pixel_y = 9 + }, +/turf/open/floor/plating, +/area/maintenance/aft) "cAF" = ( /turf/open/floor/plating, /area/maintenance/disposal) @@ -64049,10 +64057,9 @@ /turf/open/floor/plating, /area/crew_quarters/heads) "cAH" = ( -/turf/open/floor/plasteel{ - icon_state = "dark" - }, -/area/medical/morgue) +/obj/machinery/processor, +/turf/open/floor/plating, +/area/maintenance/aft) "cAI" = ( /obj/machinery/conveyor_switch/oneway{ convdir = -1; @@ -64066,8 +64073,9 @@ /turf/open/floor/plating, /area/maintenance/disposal) "cAK" = ( +/obj/machinery/light/small, /turf/open/floor/plating, -/area/maintenance/asmaint2) +/area/maintenance/aft) "cAL" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /mob/living/simple_animal/hostile/lizard{ @@ -83662,10 +83670,10 @@ apQ aaf bCq bCq -bLv -bLv bCq -aaf +bCq +bCq +bCq cfx cfx chO @@ -83918,11 +83926,11 @@ bXv bLv aaf bCq -bHE -ccd +cAy +cAB ccY -bLv -aaf +cAD +cAH cfw cgA chP @@ -84175,11 +84183,11 @@ bHE bLv aaf bCq +cAA bHE bHE ccZ -bCq -bCq +cAK cfw cgC chR @@ -84433,9 +84441,9 @@ bLv bLv bCq bHE -bCq -bCq -bCq +cAC +ccZ +cAE ceV cfw cgB @@ -84689,9 +84697,9 @@ bHE bYu bZk bCq -bHE +bTz +bCq bCq -bSq bCq bCq cfw @@ -84948,7 +84956,7 @@ bZj bCq bHE bCq -bHE +bSq cdW ceW bCq diff --git a/_maps/map_files/generic/z6.dmm b/_maps/map_files/generic/z6.dmm index ebde3b06dfa..82a78c133c6 100644 --- a/_maps/map_files/generic/z6.dmm +++ b/_maps/map_files/generic/z6.dmm @@ -41,8 +41,8 @@ "aO" = (/obj/machinery/computer/operating,/obj/structure/cable{d2 = 8; icon_state = "0-8"},/turf/open/floor/plating/airless,/area/awaymission/BMPship/Aft) "aP" = (/turf/closed/wall/shuttle{icon_state = "swall3"},/area/awaymission/BMPship/Aft) "aQ" = (/turf/open/floor/plating{icon_state = "warnplate"; dir = 9},/area/awaymission/BMPship/Aft) -"aR" = (/obj/structure/closet/crate/freezer,/obj/item/organ/internal/appendix,/obj/item/weapon/reagent_containers/food/snacks/meat/slab,/obj/item/weapon/reagent_containers/food/snacks/meat/slab/human/mutant/golem,/turf/open/floor/plating{icon_state = "warnplate"; dir = 1},/area/awaymission/BMPship/Aft) -"aS" = (/obj/structure/closet/crate/freezer,/obj/item/organ/internal/brain,/obj/item/organ/internal/appendix,/obj/item/weapon/reagent_containers/food/snacks/meat/slab,/obj/item/weapon/reagent_containers/food/snacks/meat/slab/human/mutant/slime,/turf/open/floor/plating{icon_state = "warnplate"; dir = 1},/area/awaymission/BMPship/Aft) +"aR" = (/obj/structure/closet/crate/freezer,/obj/item/organ/appendix,/obj/item/weapon/reagent_containers/food/snacks/meat/slab,/obj/item/weapon/reagent_containers/food/snacks/meat/slab/human/mutant/golem,/turf/open/floor/plating{icon_state = "warnplate"; dir = 1},/area/awaymission/BMPship/Aft) +"aS" = (/obj/structure/closet/crate/freezer,/obj/item/organ/brain,/obj/item/weapon/reagent_containers/food/snacks/meat/slab,/obj/item/weapon/reagent_containers/food/snacks/meat/slab/human/mutant/slime,/turf/open/floor/plating{icon_state = "warnplate"; dir = 1},/area/awaymission/BMPship/Aft) "aT" = (/obj/structure/table,/obj/item/stack/packageWrap,/turf/open/floor/plating{icon_state = "warnplate"; dir = 1},/area/awaymission/BMPship/Aft) "aU" = (/obj/structure/table,/obj/item/weapon/storage/box,/obj/machinery/light/small{dir = 1},/turf/open/floor/plating{icon_state = "warnplate"; dir = 1},/area/awaymission/BMPship/Aft) "aV" = (/turf/open/floor/plating{icon_state = "warnplate"; dir = 1},/area/awaymission/BMPship/Aft) @@ -118,7 +118,7 @@ "cn" = (/obj/structure/kitchenspike,/turf/open/floor/plating{dir = 2; icon_state = "warnplate"},/area/awaymission/BMPship/Aft) "co" = (/obj/structure/closet/crate,/obj/item/device/analyzer,/obj/item/stack/spacecash/c10,/turf/open/floor/plating{dir = 2; icon_state = "warnplate"},/area/awaymission/BMPship/Aft) "cp" = (/obj/structure/closet/crate,/obj/item/stack/spacecash/c1000,/obj/item/stack/spacecash/c200,/obj/item/stack/spacecash/c500,/turf/open/floor/plating{dir = 2; icon_state = "warnplate"},/area/awaymission/BMPship/Aft) -"cq" = (/obj/structure/closet/crate/freezer,/obj/item/weapon/reagent_containers/food/snacks/hugemushroomslice,/obj/item/organ/internal/appendix,/obj/item/weapon/reagent_containers/food/snacks/meat/slab,/obj/item/weapon/reagent_containers/food/snacks/meat/slab/human/mutant/golem/adamantine,/turf/open/floor/plating{dir = 2; icon_state = "warnplate"},/area/awaymission/BMPship/Aft) +"cq" = (/obj/structure/closet/crate/freezer,/obj/item/weapon/reagent_containers/food/snacks/hugemushroomslice,/obj/item/organ/appendix,/obj/item/weapon/reagent_containers/food/snacks/meat/slab,/obj/item/weapon/reagent_containers/food/snacks/meat/slab/human/mutant/golem/adamantine,/turf/open/floor/plating{dir = 2; icon_state = "warnplate"},/area/awaymission/BMPship/Aft) "cr" = (/obj/machinery/button/door{id = "packerCargo"; pixel_y = -24},/obj/machinery/light/small,/turf/open/floor/plating{dir = 2; icon_state = "warnplate"},/area/awaymission/BMPship/Aft) "cs" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/open/floor/plating{dir = 2; icon_state = "warnplate"},/area/awaymission/BMPship/Aft) "ct" = (/turf/open/floor/plating{icon_state = "warnplate"; dir = 6},/area/awaymission/BMPship/Aft) @@ -379,43 +379,43 @@ "ho" = (/turf/open/floor/plating/airless,/area/awaymission) "hp" = (/turf/open/floor/plating/airless{broken = 1; icon_state = "platingdmg1"},/area/awaymission) "hq" = (/obj/machinery/light/small{dir = 1},/turf/open/floor/plating/airless,/area/awaymission) -"hr" = (/turf/open/floor/plating/airless{broken = 1; icon_state = "platingdmg2"},/area/awaymission) -"hs" = (/obj/item/wallframe/apc,/turf/open/floor/plating/airless,/area/awaymission) -"ht" = (/obj/structure/ore_box,/obj/machinery/light/small{dir = 1},/turf/open/floor/plating/airless,/area/awaymission) -"hu" = (/obj/item/stack/cable_coil{amount = 5},/turf/open/floor/plating/airless,/area/awaymission) -"hv" = (/obj/structure/ore_box,/turf/open/floor/plating/airless,/area/awaymission) -"hw" = (/obj/machinery/computer/arcade,/turf/open/floor/plasteel,/area/awaymission/BMPship/Aft) -"hx" = (/obj/effect/decal/remains/human,/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/open/floor/plasteel,/area/awaymission/BMPship/Aft) -"hy" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0},/turf/open/floor/plasteel,/area/awaymission/BMPship/Aft) -"hz" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/open/floor/plasteel,/area/awaymission/BMPship/Aft) -"hA" = (/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/item/wallframe/apc,/turf/open/floor/plasteel,/area/awaymission/BMPship/Aft) -"hB" = (/obj/effect/decal/remains/human,/obj/item/clothing/head/helmet/space/syndicate/green/dark,/obj/effect/gibspawner/generic,/turf/open/floor/plating/asteroid/airless,/area/awaymission) -"hC" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/grille,/obj/item/weapon/shard{icon_state = "small"},/turf/open/floor/plating/airless,/area/awaymission/BMPship/Fore) -"hD" = (/obj/machinery/door/unpowered/shuttle,/turf,/area/awaymission/BMPship/Fore) -"hE" = (/turf/open/floor/plating/airless,/area/awaymission/BMPship/Fore) -"hF" = (/obj/effect/gibspawner/robot,/turf/open/floor/plasteel/airless{icon_state = "floorscorched2"},/area/awaymission/BMPship/Fore) -"hG" = (/obj/effect/gibspawner/robot,/turf/open/floor/plating/airless,/area/awaymission) -"hH" = (/obj/structure/mecha_wreckage/ripley,/turf/open/floor/plating/airless,/area/awaymission) -"hI" = (/obj/structure/bed,/turf/open/floor/plasteel,/area/awaymission/BMPship/Aft) -"hJ" = (/obj/structure/bed,/obj/item/weapon/bedsheet,/obj/item/weapon/storage/wallet/random,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/open/floor/plasteel,/area/awaymission/BMPship/Aft) -"hK" = (/obj/structure/closet,/obj/item/clothing/under/lawyer/bluesuit,/obj/item/clothing/suit/apron,/turf/open/floor/plasteel,/area/awaymission/BMPship/Aft) -"hL" = (/obj/item/clothing/suit/space/syndicate/green/dark,/turf/open/floor/plating/asteroid/airless,/area/awaymission) -"hM" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/grille,/turf/open/floor/plating/airless,/area/awaymission/BMPship/Fore) -"hN" = (/turf/open/floor/plating/airless{broken = 1; icon_state = "panelscorched"},/area/awaymission) -"hO" = (/obj/structure/cable{icon_state = "0-4"; d2 = 4},/turf/open/floor/plating/airless,/area/awaymission) -"hP" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/open/floor/plating/airless,/area/awaymission) -"hQ" = (/obj/machinery/door/unpowered/shuttle,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/open/floor/plating,/area/awaymission/BMPship/Aft) -"hR" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/open/floor/plasteel,/area/awaymission/BMPship/Aft) -"hS" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/open/floor/plasteel,/area/awaymission/BMPship/Aft) -"hT" = (/obj/item/weapon/shard{icon_state = "medium"},/turf/open/space,/area/space) -"hU" = (/turf/closed/wall/shuttle{icon_state = "swall13"},/area/awaymission/BMPship/Fore) -"hV" = (/turf/closed/wall/shuttle,/area/awaymission/BMPship/Fore) -"hW" = (/turf/open/floor/plating/airless{broken = 1; icon_state = "platingdmg3"},/area/awaymission) -"hX" = (/obj/effect/decal/remains/human,/turf/open/floor/plasteel,/area/awaymission/BMPship/Aft) -"hY" = (/obj/structure/bed,/obj/item/weapon/bedsheet,/turf/open/floor/plasteel,/area/awaymission/BMPship/Aft) -"hZ" = (/obj/machinery/door/unpowered/shuttle,/turf/open/floor/plasteel{icon_state = "cafeteria"; dir = 2},/area/awaymission/BMPship/Aft) -"ia" = (/obj/structure/mirror{pixel_y = 28},/turf/open/floor/plasteel{icon_state = "cafeteria"; dir = 2},/area/awaymission/BMPship/Aft) -"ib" = (/obj/structure/toilet{dir = 8},/obj/machinery/light/small{dir = 1},/turf/open/floor/plasteel{icon_state = "cafeteria"; dir = 2},/area/awaymission/BMPship/Aft) +"hr" = (/obj/item/wallframe/apc,/turf/open/floor/plating/airless,/area/awaymission) +"hs" = (/obj/structure/ore_box,/obj/machinery/light/small{dir = 1},/turf/open/floor/plating/airless,/area/awaymission) +"ht" = (/obj/item/stack/cable_coil{amount = 5},/turf/open/floor/plating/airless,/area/awaymission) +"hu" = (/obj/structure/ore_box,/turf/open/floor/plating/airless,/area/awaymission) +"hv" = (/obj/machinery/computer/arcade,/turf/open/floor/plasteel,/area/awaymission/BMPship/Aft) +"hw" = (/obj/effect/decal/remains/human,/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/open/floor/plasteel,/area/awaymission/BMPship/Aft) +"hx" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0},/turf/open/floor/plasteel,/area/awaymission/BMPship/Aft) +"hy" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/open/floor/plasteel,/area/awaymission/BMPship/Aft) +"hz" = (/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/item/wallframe/apc,/turf/open/floor/plasteel,/area/awaymission/BMPship/Aft) +"hA" = (/obj/effect/decal/remains/human,/obj/item/clothing/head/helmet/space/syndicate/green/dark,/obj/effect/gibspawner/generic,/turf/open/floor/plating/asteroid/airless,/area/awaymission) +"hB" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/grille,/obj/item/weapon/shard{icon_state = "small"},/turf/open/floor/plating/airless,/area/awaymission/BMPship/Fore) +"hC" = (/obj/machinery/door/unpowered/shuttle,/turf,/area/awaymission/BMPship/Fore) +"hD" = (/turf/open/floor/plating/airless,/area/awaymission/BMPship/Fore) +"hE" = (/obj/effect/gibspawner/robot,/turf/open/floor/plasteel/airless{icon_state = "floorscorched2"},/area/awaymission/BMPship/Fore) +"hF" = (/turf/open/floor/plating/airless{broken = 1; icon_state = "platingdmg2"},/area/awaymission) +"hG" = (/obj/structure/mecha_wreckage/ripley,/turf/open/floor/plating/airless,/area/awaymission) +"hH" = (/obj/structure/bed,/turf/open/floor/plasteel,/area/awaymission/BMPship/Aft) +"hI" = (/obj/structure/bed,/obj/item/weapon/bedsheet,/obj/item/weapon/storage/wallet/random,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/open/floor/plasteel,/area/awaymission/BMPship/Aft) +"hJ" = (/obj/structure/closet,/obj/item/clothing/under/lawyer/bluesuit,/obj/item/clothing/suit/apron,/turf/open/floor/plasteel,/area/awaymission/BMPship/Aft) +"hK" = (/obj/item/clothing/suit/space/syndicate/green/dark,/turf/open/floor/plating/asteroid/airless,/area/awaymission) +"hL" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/grille,/turf/open/floor/plating/airless,/area/awaymission/BMPship/Fore) +"hM" = (/obj/effect/gibspawner/robot,/turf/open/floor/plating/airless,/area/awaymission) +"hN" = (/obj/structure/cable{icon_state = "0-4"; d2 = 4},/turf/open/floor/plating/airless,/area/awaymission) +"hO" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/open/floor/plating/airless,/area/awaymission) +"hP" = (/obj/machinery/door/unpowered/shuttle,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/open/floor/plating,/area/awaymission/BMPship/Aft) +"hQ" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/open/floor/plasteel,/area/awaymission/BMPship/Aft) +"hR" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/open/floor/plasteel,/area/awaymission/BMPship/Aft) +"hS" = (/obj/item/weapon/shard{icon_state = "medium"},/turf/open/space,/area/space) +"hT" = (/turf/closed/wall/shuttle{icon_state = "swall13"},/area/awaymission/BMPship/Fore) +"hU" = (/turf/closed/wall/shuttle,/area/awaymission/BMPship/Fore) +"hV" = (/turf/open/floor/plating/airless{broken = 1; icon_state = "panelscorched"},/area/awaymission) +"hW" = (/obj/effect/decal/remains/human,/turf/open/floor/plasteel,/area/awaymission/BMPship/Aft) +"hX" = (/obj/structure/bed,/obj/item/weapon/bedsheet,/turf/open/floor/plasteel,/area/awaymission/BMPship/Aft) +"hY" = (/obj/machinery/door/unpowered/shuttle,/turf/open/floor/plasteel{icon_state = "cafeteria"; dir = 2},/area/awaymission/BMPship/Aft) +"hZ" = (/obj/structure/mirror{pixel_y = 28},/turf/open/floor/plasteel{icon_state = "cafeteria"; dir = 2},/area/awaymission/BMPship/Aft) +"ia" = (/obj/structure/toilet{dir = 8},/obj/machinery/light/small{dir = 1},/turf/open/floor/plasteel{icon_state = "cafeteria"; dir = 2},/area/awaymission/BMPship/Aft) +"ib" = (/turf/open/floor/plating/airless{broken = 1; icon_state = "platingdmg3"},/area/awaymission) "ic" = (/obj/item/weapon/caution,/turf/open/floor/plating/airless,/area/awaymission) "id" = (/obj/machinery/portable_atmospherics/canister/air,/turf/open/floor/plating/airless,/area/awaymission) "ie" = (/obj/structure/closet/crate,/obj/item/stack/spacecash/c10,/obj/item/stack/spacecash/c200,/turf/open/floor/plasteel,/area/awaymission/BMPship/Aft) @@ -433,7 +433,7 @@ "iq" = (/turf/open/floor/plating,/turf/closed/wall/shuttle{icon_state = "swall_f6"; dir = 2},/area/awaymission/BMPship/Fore) "ir" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/structure/grille,/turf/open/floor/engine,/area/awaymission/BMPship/Fore) "is" = (/turf/closed/mineral/diamond,/area/awaymission) -"it" = (/turf/closed/wall/shuttle{icon_state = "wall3"},/area/awaymission) +"it" = (/turf/closed/mineral/clown,/area/awaymission) "iu" = (/turf/closed/mineral,/area/awaymission) "iv" = (/turf/closed/wall/r_wall,/area/awaymission/listeningpost) "iw" = (/turf/open/floor/plating,/area/awaymission/listeningpost) @@ -444,33 +444,33 @@ "iB" = (/obj/structure/table,/turf/open/floor/plasteel,/area/awaymission/listeningpost) "iC" = (/turf/open/floor/plasteel,/area/awaymission/listeningpost) "iD" = (/obj/machinery/door/airlock/external,/turf/open/floor/plating,/area/awaymission/listeningpost) -"iE" = (/turf/open/floor/plating/asteroid/airless,/area/mine/explored) -"iF" = (/obj/machinery/computer/message_monitor,/turf/open/floor/plasteel,/area/awaymission/listeningpost) -"iG" = (/obj/structure/chair{dir = 4},/mob/living/simple_animal/hostile/syndicate{desc = "A weary looking syndicate operative."},/turf/open/floor/plasteel,/area/awaymission/listeningpost) -"iH" = (/obj/structure/table,/obj/item/weapon/paper{info = "Nothing of interest to report."; name = "november report"},/obj/item/weapon/pen,/turf/open/floor/plasteel,/area/awaymission/listeningpost) -"iI" = (/obj/item/device/radio/intercom{desc = "Talk through this. Evilly"; freerange = 1; frequency = 1213; name = "Syndicate Intercom"; pixel_x = 32; subspace_transmission = 1; syndie = 1},/turf/open/floor/plasteel,/area/awaymission/listeningpost) -"iJ" = (/obj/structure/rack,/obj/item/clothing/suit/space/syndicate,/obj/item/clothing/mask/gas,/obj/item/clothing/head/helmet/space/syndicate,/turf/open/floor/plasteel,/area/awaymission/listeningpost) -"iK" = (/obj/machinery/door/airlock,/obj/structure/safe/floor,/obj/item/weapon/paper{info = "I wonder how much longer they will accept my empty reports. They will cancel the case soon without results. When the pickup comes, I will tell them I have lost faith in our cause, and beg them to consider a diplomatic solution. How many nuclear teams have been dispatched with those nukes? I must try and prevent more from ever being sent. If they will not listen to reason, I will detonate the warehouse myself. Maybe some day in the immediate future, space will be peaceful, though I don't intend to live to see it. And that is why I write this down- it is my sacrifice that stabilised your worlds, traveller. Spare a thought for me, and please attempt to prevent nuclear proliferation, should it ever rear it's ugly head again. -Donk Co. Operative #451"; name = "odd report"},/obj/item/weapon/gun/projectile/automatic/pistol,/turf/open/floor/plasteel,/area/awaymission/listeningpost) -"iL" = (/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/turf/closed/mineral,/area/awaymission) -"iM" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/closed/mineral,/area/awaymission) -"iN" = (/obj/structure/disposaloutlet{dir = 4},/obj/structure/disposalpipe/trunk{dir = 8},/turf/open/floor/plating/airless,/area/space) -"iO" = (/obj/structure/bed,/obj/item/weapon/bedsheet/brown,/turf/open/floor/plasteel,/area/awaymission/listeningpost) -"iP" = (/obj/structure/table,/obj/item/device/flashlight/lamp,/turf/open/floor/plasteel,/area/awaymission/listeningpost) -"iQ" = (/obj/machinery/vending/snack,/turf/open/floor/plasteel,/area/awaymission/listeningpost) -"iR" = (/obj/structure/disposalpipe/segment,/turf/closed/mineral,/area/awaymission) -"iS" = (/obj/machinery/vending/cola,/turf/open/floor/plasteel,/area/awaymission/listeningpost) -"iT" = (/obj/structure/closet,/obj/item/clothing/gloves/boxing,/turf/open/floor/plasteel,/area/awaymission/listeningpost) -"iU" = (/obj/structure/filingcabinet,/obj/item/weapon/paper{info = "A good start to the operation: intercepted Nanotrasen military communications. A convoy is scheduled to transfer nuclear warheads to a new military base. This is as good a chance as any to get our hands on some heavy weaponry, I suggest we take it."; name = "april report"},/obj/item/weapon/paper{info = "Nothing of real interest to report this month. I have intercepted faint transmissions from what appears to be some sort of pirate radio station. They do not appear to be relevant to my assignment."; name = "may report"},/obj/item/weapon/paper{info = "Nanotrasen communications have been noticably less frequent recently. The pirate radio station I found last month has been transmitting pro-Nanotrasen propaganda. I will continue to monitor it."; name = "june report"},/obj/item/weapon/paper{info = "Nothing of interest to report."; name = "july report"},/obj/item/weapon/paper{info = "Nothing of interest to report."; name = "august report"},/obj/item/weapon/paper{info = "Nothing of interest to report."; name = "september report"},/obj/item/weapon/paper{info = "Nothing of interest to report."; name = "october report"},/obj/item/weapon/paper{info = "1 x Stechtkin pistol - $600
1 x silencer - $200
shipping charge - $4360
total - $5160"; name = "receipt"},/turf/open/floor/plasteel,/area/awaymission/listeningpost) -"iV" = (/obj/structure/table,/obj/item/weapon/paper{info = "Mission Details: You have been assigned to a newly constructed listening post constructed within an asteroid in Nanotrasen space to monitor their plasma mining operations. Accurate intel is crucial to the success of our operatives onboard, do not fail us."; name = "mission briefing"},/turf/open/floor/plasteel,/area/awaymission/listeningpost) -"iW" = (/obj/machinery/disposal/bin,/obj/structure/disposalpipe/trunk{dir = 4},/turf/open/floor/plasteel,/area/awaymission/listeningpost) -"iX" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/closed/wall/r_wall,/area/awaymission/listeningpost) -"iY" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/turf/closed/mineral,/area/awaymission) -"iZ" = (/obj/machinery/door/airlock{name = "Toilet"},/turf/open/floor/plasteel,/area/awaymission/listeningpost) -"ja" = (/turf/open/floor/plasteel{icon_state = "freezerfloor"},/area/awaymission/listeningpost) -"jb" = (/obj/machinery/shower{icon_state = "shower"; dir = 8},/turf/open/floor/plasteel{icon_state = "freezerfloor"},/area/awaymission/listeningpost) -"jc" = (/obj/structure/toilet{icon_state = "toilet00"; dir = 8},/turf/open/floor/plasteel{icon_state = "freezerfloor"},/area/awaymission/listeningpost) -"jd" = (/turf/closed/mineral/clown,/area/awaymission) -"je" = (/turf/open/floor/plasteel/airless{icon_state = "gcircuit"},/area/awaymission) +"iE" = (/obj/machinery/computer/message_monitor,/turf/open/floor/plasteel,/area/awaymission/listeningpost) +"iF" = (/obj/structure/chair{dir = 4},/mob/living/simple_animal/hostile/syndicate{desc = "A weary looking syndicate operative."},/turf/open/floor/plasteel,/area/awaymission/listeningpost) +"iG" = (/obj/structure/table,/obj/item/weapon/paper{info = "Nothing of interest to report."; name = "november report"},/obj/item/weapon/pen,/turf/open/floor/plasteel,/area/awaymission/listeningpost) +"iH" = (/obj/item/device/radio/intercom{desc = "Talk through this. Evilly"; freerange = 1; frequency = 1213; name = "Syndicate Intercom"; pixel_x = 32; subspace_transmission = 1; syndie = 1},/turf/open/floor/plasteel,/area/awaymission/listeningpost) +"iI" = (/obj/structure/rack,/obj/item/clothing/suit/space/syndicate,/obj/item/clothing/mask/gas,/obj/item/clothing/head/helmet/space/syndicate,/turf/open/floor/plasteel,/area/awaymission/listeningpost) +"iJ" = (/obj/machinery/door/airlock,/obj/structure/safe/floor,/obj/item/weapon/paper{info = "I wonder how much longer they will accept my empty reports. They will cancel the case soon without results. When the pickup comes, I will tell them I have lost faith in our cause, and beg them to consider a diplomatic solution. How many nuclear teams have been dispatched with those nukes? I must try and prevent more from ever being sent. If they will not listen to reason, I will detonate the warehouse myself. Maybe some day in the immediate future, space will be peaceful, though I don't intend to live to see it. And that is why I write this down- it is my sacrifice that stabilised your worlds, traveller. Spare a thought for me, and please attempt to prevent nuclear proliferation, should it ever rear it's ugly head again. -Donk Co. Operative #451"; name = "odd report"},/obj/item/weapon/gun/projectile/automatic/pistol,/turf/open/floor/plasteel,/area/awaymission/listeningpost) +"iK" = (/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/turf/closed/mineral,/area/awaymission) +"iL" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/closed/mineral,/area/awaymission) +"iM" = (/obj/structure/disposaloutlet{dir = 4},/obj/structure/disposalpipe/trunk{dir = 8},/turf/open/floor/plating/airless,/area/space) +"iN" = (/obj/structure/bed,/obj/item/weapon/bedsheet/brown,/turf/open/floor/plasteel,/area/awaymission/listeningpost) +"iO" = (/obj/structure/table,/obj/item/device/flashlight/lamp,/turf/open/floor/plasteel,/area/awaymission/listeningpost) +"iP" = (/obj/machinery/vending/snack,/turf/open/floor/plasteel,/area/awaymission/listeningpost) +"iQ" = (/obj/structure/disposalpipe/segment,/turf/closed/mineral,/area/awaymission) +"iR" = (/obj/machinery/vending/cola,/turf/open/floor/plasteel,/area/awaymission/listeningpost) +"iS" = (/obj/structure/closet,/obj/item/clothing/gloves/boxing,/turf/open/floor/plasteel,/area/awaymission/listeningpost) +"iT" = (/obj/structure/filingcabinet,/obj/item/weapon/paper{info = "A good start to the operation: intercepted Nanotrasen military communications. A convoy is scheduled to transfer nuclear warheads to a new military base. This is as good a chance as any to get our hands on some heavy weaponry, I suggest we take it."; name = "april report"},/obj/item/weapon/paper{info = "Nothing of real interest to report this month. I have intercepted faint transmissions from what appears to be some sort of pirate radio station. They do not appear to be relevant to my assignment."; name = "may report"},/obj/item/weapon/paper{info = "Nanotrasen communications have been noticably less frequent recently. The pirate radio station I found last month has been transmitting pro-Nanotrasen propaganda. I will continue to monitor it."; name = "june report"},/obj/item/weapon/paper{info = "Nothing of interest to report."; name = "july report"},/obj/item/weapon/paper{info = "Nothing of interest to report."; name = "august report"},/obj/item/weapon/paper{info = "Nothing of interest to report."; name = "september report"},/obj/item/weapon/paper{info = "Nothing of interest to report."; name = "october report"},/obj/item/weapon/paper{info = "1 x Stechtkin pistol - $600
1 x silencer - $200
shipping charge - $4360
total - $5160"; name = "receipt"},/turf/open/floor/plasteel,/area/awaymission/listeningpost) +"iU" = (/obj/structure/table,/obj/item/weapon/paper{info = "Mission Details: You have been assigned to a newly constructed listening post constructed within an asteroid in Nanotrasen space to monitor their plasma mining operations. Accurate intel is crucial to the success of our operatives onboard, do not fail us."; name = "mission briefing"},/turf/open/floor/plasteel,/area/awaymission/listeningpost) +"iV" = (/obj/machinery/disposal/bin,/obj/structure/disposalpipe/trunk{dir = 4},/turf/open/floor/plasteel,/area/awaymission/listeningpost) +"iW" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/closed/wall/r_wall,/area/awaymission/listeningpost) +"iX" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/turf/closed/mineral,/area/awaymission) +"iY" = (/obj/machinery/door/airlock{name = "Toilet"},/turf/open/floor/plasteel,/area/awaymission/listeningpost) +"iZ" = (/turf/open/floor/plasteel{icon_state = "freezerfloor"},/area/awaymission/listeningpost) +"ja" = (/obj/machinery/shower{icon_state = "shower"; dir = 8},/turf/open/floor/plasteel{icon_state = "freezerfloor"},/area/awaymission/listeningpost) +"jb" = (/obj/structure/toilet{icon_state = "toilet00"; dir = 8},/turf/open/floor/plasteel{icon_state = "freezerfloor"},/area/awaymission/listeningpost) +"jc" = (/turf/closed/wall/shuttle{icon_state = "wall3"},/area/awaymission) +"jd" = (/turf/open/floor/plasteel/airless{icon_state = "gcircuit"},/area/awaymission) +"je" = (/turf/open/floor/plating/asteroid/airless,/area/mine/explored) (1,1,1) = {" aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -551,22 +551,22 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaasgvgwghgxgygzczcHcHcHcHcHcHcHcHgAcHdMcHgBeeeeeeeeeeeedOdOdOescHdbgCdddddddddQgDgEaPdBgFbcgGayaxazfdaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacaaaaasaaaaaaaagHgIgJgigzczcHgKcHcHcHcHgLcHgMgLcIcHgKcHcHcHgKcHcHcHcHgKcHcHcRaxaAgNaCaAgOaCaxazaAgPaCcifdaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagQgQgQacaaasaagRasaagSagaggTgUgVcgcgcgcgcgcgcggWgXgYgZcgcgcgcgcgcgcgcgcgcgcgcgcgbPdldldldlhadkhbhchdhaekheaPaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagQgQgQgQacaaaaaaaaaahfakhgcdhhhihjhkgghlgihmgQgQgQgQhnacachohpachqhoachphshthuhvaPhwdlbcdldlhxhyhyhyhyhzhAaPaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagQgQgQgQhBaaaaaaaaaahCalalhDhEgvhEhjhFhEhjgQgQgQgQgQgQhmachrhHhoachphohohohohohobahbdldlhIdlhJdlhIdldldlhKaPaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagQachLaaaaaaaaaahMakalbOgigihjgghjgihjhmgQgQgQhmgQgQgQachGachohohohohohohOhPhQhRhRhRhRhRhSdldldlaCaxaxbPaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaahTacafagaghUaghVgQhjhmgQgQgQgQgQgQgQgQgQgQgQhphrhohoachohohNhohobGdldlhXhYdlhIdlhIdlhZiaibaPaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQhmachrhohohWicicicidaPieifdlbcdldldldldlbGigihfdaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagQgQgQgQacaaaaaaaaaahfakhgcdhhhihjhkgghlgihmgQgQgQgQhnacachohpachqhoachphrhshthuaPhvdlbcdldlhwhxhxhxhxhyhzaPaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagQgQgQgQhAaaaaaaaaaahBalalhChDgvhDhjhEhDhjgQgQgQgQgQgQhmachFhGhoachphohohohohohobahbdldlhHdlhIdlhHdldldlhJaPaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagQachKaaaaaaaaaahLakalbOgigihjgghjgihjhmgQgQgQhmgQgQgQachMachohohohohohohNhOhPhQhQhQhQhQhRdldldlaCaxaxbPaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaahSacafagaghTaghUgQhjhmgQgQgQgQgQgQgQgQgQgQgQhphFhohoachohohVhohobGdldlhWhXdlhHdlhHdlhYhZiaaPaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQhmachFhohoibicicicidaPieifdlbcdldldldldlbGigihfdaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiiacacacgQgQgQgQgQgQgQgQgQgQgQhmgQgQgQgQgQgQgQgQhmijikikikikikikikazaxaxaxayaAgNaCayayazaxfdaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQacacaaaaaaaaaailakhgcdimarinavioaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQacacaaaaaaaaaaapalalaqaripiqioaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQacacaaaaaaaaaairakalbOaniqioaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacgQgQacacgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQacacaaaaaaaaaaafagaghUagioaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacgQgQacacgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQacacaaaaaaaaaaafagaghTagioaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagQgQgQacacacgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagQgQgQgQgQacacgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagQgQgQgQgQacacacgQgQisgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagQgQgQgQgQacacacgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagQgQgQgQgQacacacgQgQgQgQgQgQjdgQgQgQgQgQgQgQgQgQgQgQacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagQgQgQgQgQacacacgQgQgQjdgQgQjdgQgQgQgQgQgQgQgQgQacacacacgQgQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagQgQgQgQgQacacacgQgQgQgQgQgQitgQgQgQgQgQgQgQgQgQgQgQacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagQgQgQgQgQacacacgQgQgQitgQgQitgQgQgQgQgQgQgQgQgQacacacacgQgQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagQgQgQgQacacacacgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQacacgQgQgQgQgQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagQgQacacacacacacgQgQgQgQgQgQgQgQgQgQgQgQacacacacgQgQgQgQgQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacacgQgQgQgQgQgQgQgQacacacacaaaaaagQgQgQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -620,16 +620,16 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiviwixiviuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiviviviyizivivivivaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiviviAiBiCiCiDiwiwiDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaciuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiviFiGiHiCiCiDiwiwiDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuaaaciuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiviviIiBiCiCivivivivaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuacaciuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiviCiCiCiJiviuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuaciuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiviviviviKiziziziviuiLiMiMiNaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiviOiPiziCiCiCiQiviuiRiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiviCiCiyiCiCiCiSiviuiRiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiviTiUiziViCiWiXiXiMiYiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiviviviviviZiziviuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuivjajbiviuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuivjajciviuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaciuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiviEiFiGiCiCiDiwiwiDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuaaaciuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiviviHiBiCiCivivivivaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuacaciuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiviCiCiCiIiviuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuaciuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiviviviviJiziziziviuiKiLiLiMaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiviNiOiziCiCiCiPiviuiQiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiviCiCiyiCiCiCiRiviuiQiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiviSiTiziUiCiViWiWiLiXiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiviviviviviYiziviuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiviZjaiviuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiviZjbiviuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiviviviviuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -639,30 +639,30 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuacacaciuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiujdjdiuiuiuiuiuiuiuacacaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiujdiuiujdiuiuiuacacacaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiujdiuiuiuiuiuiuiuiuiuiuiuiuacaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiujdjdiuiuiuiuiuiuiuiuiuiuiuacaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiujdjdiuiuiuiuiuiuiuiuiuiuiuacaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiujdiuiuiuiuiuiuaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuititiuiuiuiuiuiuiuacacaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuitiuiuitiuiuiuacacacaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuitiuiuiuiuiuiuiuiuiuiuiuiuacaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuititiuiuiuiuiuiuiuiuiuiuiuacaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuititiuiuiuiuiuiuiuiuiuiuiuacaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuitiuiuiuiuiuiuaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiujdjdiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiujdiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiujdiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuititiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuitiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuitiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiujdjdiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuititiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuacacacacaciuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuacaaaaaaaaiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuacaciuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuitititititititiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuacjejejejejeitiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiujejejejejeitiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiujejejejeitiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiEiuiuiuiuiuiuiuiuiuiuiuiuiuiujejejejejeitiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiEiEiuiuiuiuiuiuiuiuiuiuiuiuiuacjejejejeitiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaiEiuiuiuiuiuiuiuiuiuiuiuiuacacitititititiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiujcjcjcjcjcjcjciuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuacjdjdjdjdjdjciuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiujdjdjdjdjdjciuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiujdjdjdjdjciuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiujeiuiuiuiuiuiuiuiuiuiuiuiuiuiujdjdjdjdjdjciuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiujejeiuiuiuiuiuiuiuiuiuiuiuiuiuacjdjdjdjdjciuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaaajeiuiuiuiuiuiuiuiuiuiuiuiuacacjcjcjcjcjciuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -729,4 +729,3 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa "} - diff --git a/code/__DEFINES/clothing.dm b/code/__DEFINES/clothing.dm index fabe22f95c4..dd8ce2bdb96 100644 --- a/code/__DEFINES/clothing.dm +++ b/code/__DEFINES/clothing.dm @@ -13,19 +13,7 @@ #define SLOT_POCKET 2048 //this is to allow items with a w_class of 3 or 4 to fit in pockets. #define SLOT_DENYPOCKET 4096 //this is to deny items with a w_class of 2 or 1 to fit in pockets. -//Bit flags for the flags_inv variable, which determine when a piece of clothing hides another. IE a helmet hiding glasses. -#define HIDEGLOVES 1 -#define HIDESUITSTORAGE 2 -#define HIDEJUMPSUIT 4 //these first four are only used in exterior suits -#define HIDESHOES 8 -#define HIDEMASK 16 //these last six are only used in masks and headgear. -#define HIDEEARS 32 // (ears means headsets and such) -#define HIDEEYES 64 // Whether eyes and glasses are hidden -#define HIDEFACE 128 // Whether we appear as unknown. -#define HIDEHAIR 256 -#define HIDEFACIALHAIR 512 - -//slots +//SLOTS #define slot_back 1 #define slot_wear_mask 2 #define slot_handcuffed 3 @@ -49,6 +37,49 @@ #define slots_amt 20 // Keep this up to date! +//I hate that this has to exist +/proc/slotdefine2slotbit(slotdefine) //Keep this up to date with the value of SLOT BITMASKS and SLOTS (the two define sections above) + . = 0 + switch(slotdefine) + if(slot_back) + . = SLOT_BACK + if(slot_wear_mask) + . = SLOT_MASK + if(slot_belt) + . = SLOT_BELT + if(slot_wear_id) + . = SLOT_ID + if(slot_ears) + . = SLOT_EARS + if(slot_glasses) + . = SLOT_EYES + if(slot_gloves) + . = SLOT_GLOVES + if(slot_head) + . = SLOT_HEAD + if(slot_shoes) + . = SLOT_FEET + if(slot_wear_suit) + . = SLOT_OCLOTHING + if(slot_w_uniform) + . = SLOT_ICLOTHING + if(slot_l_store, slot_r_store) + . = SLOT_POCKET + + +//Bit flags for the flags_inv variable, which determine when a piece of clothing hides another. IE a helmet hiding glasses. +#define HIDEGLOVES 1 +#define HIDESUITSTORAGE 2 +#define HIDEJUMPSUIT 4 //these first four are only used in exterior suits +#define HIDESHOES 8 +#define HIDEMASK 16 //these last six are only used in masks and headgear. +#define HIDEEARS 32 // (ears means headsets and such) +#define HIDEEYES 64 // Whether eyes and glasses are hidden +#define HIDEFACE 128 // Whether we appear as unknown. +#define HIDEHAIR 256 +#define HIDEFACIALHAIR 512 + + //Cant seem to find a mob bitflags area other than the powers one // bitflags for clothing parts - also used for limbs diff --git a/code/__DEFINES/flags.dm b/code/__DEFINES/flags.dm index 9d0840adf36..d5c37b89886 100644 --- a/code/__DEFINES/flags.dm +++ b/code/__DEFINES/flags.dm @@ -55,8 +55,8 @@ #define FACEHAIR 4 #define EYECOLOR 8 #define LIPS 16 -#define COLDRES 32 -#define HEATRES 64 +#define RESISTCOLD 32 +#define RESISTHEAT 64 #define RADIMMUNE 128 #define NOBREATH 256 #define NOGUNS 512 diff --git a/code/__DEFINES/genetics.dm b/code/__DEFINES/genetics.dm index dd3b99c0e86..4cf307dbf34 100644 --- a/code/__DEFINES/genetics.dm +++ b/code/__DEFINES/genetics.dm @@ -80,7 +80,7 @@ #define TR_KEEPSRC 128 #define TR_KEEPORGANS 256 -//Organ stuff, It's here because "Genetics" is the most relevant file for organs +//Organ stuff, It's here because "Genetics" is the most relevant file for organs and bodyparts #define ORGAN_ORGANIC 1 #define ORGAN_ROBOTIC 2 diff --git a/code/__DEFINES/is_helpers.dm b/code/__DEFINES/is_helpers.dm index 0a62f085b66..f05b74117d9 100644 --- a/code/__DEFINES/is_helpers.dm +++ b/code/__DEFINES/is_helpers.dm @@ -60,7 +60,7 @@ #define isguardian(A) (istype(A, /mob/living/simple_animal/hostile/guardian)) -#define islimb(A) (istype(A, /obj/item/organ/limb)) +#define islimb(A) (istype(A, /obj/item/bodypart)) #define isbot(A) (istype(A, /mob/living/simple_animal/bot)) diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm index a83f410d5ff..e13ea1a5174 100644 --- a/code/__DEFINES/misc.dm +++ b/code/__DEFINES/misc.dm @@ -23,13 +23,13 @@ #define FRIDAY_13TH "Friday the 13th" //Human Overlays Indexes///////// -#define SPECIES_LAYER 27 // mutantrace colors... these are on a seperate layer in order to prvent -#define MUTATIONS_LAYER 26 //mutations. Hulk, Tk headglows, etc -#define BODY_BEHIND_LAYER 25 -#define BODY_LAYER 24 //underwear, undershirts, socks, eyes, lips(makeup) -#define BODY_ADJ_LAYER 23 -#define AUGMENTS_LAYER 22 -#define FRONT_MUTATIONS_LAYER 21 //mutations that should appear above body and augments layer (e.g. laser eyes) +#define MUTATIONS_LAYER 27 //mutations. Tk headglows, cold resistance glow, etc +#define SPECIES_LAYER 26 // mutantrace colors... these are on a seperate layer in order to prvent +#define BODY_BEHIND_LAYER 25 //certain mutantrace features (tail when looking south) that must appear behind the body parts +#define BODYPARTS_LAYER 24 //Initially "AUGMENTS", this was repurposed to be a catch-all bodyparts flag +#define BODY_ADJ_LAYER 23 //certain mutantrace features (snout, body markings) that must appear above the body parts +#define BODY_LAYER 22 //underwear, undershirts, socks, eyes, lips(makeup) +#define FRONT_MUTATIONS_LAYER 21 //mutations that should appear above body, body_adj and bodyparts layer (e.g. laser eyes) #define DAMAGE_LAYER 20 //damage indicators (cuts and burns) #define UNIFORM_LAYER 19 #define ID_LAYER 18 @@ -60,7 +60,7 @@ #define UNDER_BODY_LAYER BODY_LAYER+1 #define UNDER_BODY_ADJ_LAYER BODY_ADJ_LAYER+1 #define UNDER_MUTATIONS_LAYER MUTATIONS_LAYER+1 -#define UNDER_AUGMENTS_LAYER AUGMENTS_LAYER+1 +#define UNDER_BODYPARTS_LAYER BODYPARTS_LAYER+1 #define UNDER_DAMAGE_LAYER DAMAGE_LAYER+1 #define UNDER_UNIFORM_LAYER UNIFORM_LAYER+1 #define UNDER_ID_LAYER ID_LAYER+1 @@ -88,7 +88,7 @@ #define ABOVE_BODY_LAYER BODY_LAYER-1 #define ABOVE_BODY_ADJ_LAYER BODY_ADJ_LAYER-1 #define ABOVE_MUTATIONS_LAYER MUTATIONS_LAYER-1 -#define ABOVE_AUGMENTS_LAYER AUGMENTS_LAYER-1 +#define ABOVE_BODYPARTS_LAYER BODYPARTS_LAYER-1 #define ABOVE_DAMAGE_LAYER DAMAGE_LAYER-1 #define ABOVE_UNIFORM_LAYER UNIFORM_LAYER-1 #define ABOVE_ID_LAYER ID_LAYER-1 @@ -283,6 +283,7 @@ var/list/bloody_footprints_cache = list() #define TURF_WET_WATER 1 #define TURF_WET_LUBE 2 #define TURF_WET_ICE 3 +#define TURF_WET_PERMAFROST 4 //Object/Item sharpness #define IS_BLUNT 0 diff --git a/code/_globalvars/configuration.dm b/code/_globalvars/configuration.dm index ded24179173..7f5b1709a6c 100644 --- a/code/_globalvars/configuration.dm +++ b/code/_globalvars/configuration.dm @@ -26,6 +26,9 @@ var/Debug2 = 0 var/global/comms_key = "default_pwd" var/global/comms_allowed = 0 //By default, the server does not allow messages to be sent to it, unless the key is strong enough (this is to prevent misconfigured servers from becoming vulnerable) +//Cross server communications +var/global/cross_address = "byond://" //This needs to be global as the message sent contains the comms key. +var/global/cross_allowed = 0 //Don't bother attempting to send if the address wasn't set. //This was a define, but I changed it to a variable so it can be changed in-game.(kept the all-caps definition because... code...) -Errorage var/MAX_EX_DEVESTATION_RANGE = 3 diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm index 26838de68c3..826a61fb9ab 100644 --- a/code/_onclick/click.dm +++ b/code/_onclick/click.dm @@ -58,6 +58,9 @@ return var/list/modifiers = params2list(params) + if(modifiers["shift"] && modifiers["middle"]) + ShiftMiddleClickOn(A) + return if(modifiers["shift"] && modifiers["ctrl"]) CtrlShiftClickOn(A) return @@ -264,6 +267,10 @@ A.CtrlShiftClick(src) return +/mob/proc/ShiftMiddleClickOn(atom/A) + src.pointed(A) + return + /atom/proc/CtrlShiftClick(mob/user) return diff --git a/code/_onclick/hud/screen_objects.dm b/code/_onclick/hud/screen_objects.dm index 2fc47ab95be..ef8ecf90a8b 100644 --- a/code/_onclick/hud/screen_objects.dm +++ b/code/_onclick/hud/screen_objects.dm @@ -81,6 +81,7 @@ /obj/screen/inventory/hand var/image/active_overlay var/image/handcuff_overlay + var/image/blocked_overlay /obj/screen/inventory/hand/update_icon() ..() @@ -89,6 +90,8 @@ if(!handcuff_overlay) var/state = (slot_id == slot_r_hand) ? "markus" : "gabrielle" handcuff_overlay = image("icon"='icons/mob/screen_gen.dmi', "icon_state"=state) + if(!blocked_overlay) + blocked_overlay = image("icon"='icons/mob/screen_gen.dmi', "icon_state"="blocked") overlays.Cut() @@ -97,6 +100,12 @@ var/mob/living/carbon/C = hud.mymob if(C.handcuffed) overlays += handcuff_overlay + if(slot_id == slot_r_hand) + if(!C.has_right_hand()) + overlays += blocked_overlay + else if(slot_id == slot_l_hand) + if(!C.has_left_hand()) + overlays += blocked_overlay if(slot_id == slot_l_hand && hud.mymob.hand) overlays += active_overlay diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm index 374b077d67a..d981f93f573 100644 --- a/code/_onclick/item_attack.dm +++ b/code/_onclick/item_attack.dm @@ -23,7 +23,7 @@ return I.attack(src, user) -/obj/item/proc/attack(mob/living/M, mob/living/user, def_zone) +/obj/item/proc/attack(mob/living/M, mob/living/user) if(flags & NOBLUDGEON) return if(!force) @@ -34,7 +34,7 @@ user.lastattacked = M M.lastattacker = user - M.attacked_by(src, user, def_zone) + M.attacked_by(src, user) add_logs(user, M, "attacked", src.name, "(INTENT: [uppertext(user.a_intent)]) (DAMTYPE: [uppertext(damtype)])") add_fingerprint(user) @@ -57,11 +57,11 @@ if(I.force) user.visible_message("[user] has hit [src] with [I]!", "You hit [src] with [I]!") -/mob/living/attacked_by(obj/item/I, mob/living/user, def_zone) +/mob/living/attacked_by(obj/item/I, mob/living/user) if(user != src) user.do_attack_animation(src) - if(send_item_attack_message(I, user, def_zone)) - if(apply_damage(I.force, I.damtype, def_zone)) + if(send_item_attack_message(I, user)) + if(apply_damage(I.force, I.damtype)) if(I.damtype == BRUTE) if(prob(33)) var/turf/location = get_turf(src) diff --git a/code/_onclick/observer.dm b/code/_onclick/observer.dm index 8f818f47a88..7a561b426ee 100644 --- a/code/_onclick/observer.dm +++ b/code/_onclick/observer.dm @@ -17,12 +17,15 @@ loc = get_turf(A) /mob/dead/observer/ClickOn(var/atom/A, var/params) - + if(client.click_intercept) if(call(client.click_intercept,"InterceptClickOn")(src,params,A)) return var/list/modifiers = params2list(params) + if(modifiers["shift"] && modifiers["middle"]) + ShiftMiddleClickOn(A) + return if(modifiers["middle"]) MiddleClickOn(A) return diff --git a/code/_onclick/other_mobs.dm b/code/_onclick/other_mobs.dm index a053de3efa2..5ca614626ff 100644 --- a/code/_onclick/other_mobs.dm +++ b/code/_onclick/other_mobs.dm @@ -5,11 +5,15 @@ Otherwise pretty standard. */ /mob/living/carbon/human/UnarmedAttack(atom/A, proximity) - var/obj/item/clothing/gloves/G = gloves // not typecast specifically enough in defines + + if(!has_active_hand()) //can't attack without a hand. + src << "You look at your arm and sigh." + return // Special glove functions: // If the gloves do anything, have them return 1 to stop // normal attack_hand() here. + var/obj/item/clothing/gloves/G = gloves // not typecast specifically enough in defines if(proximity && istype(G) && G.Touch(A,1)) return @@ -89,9 +93,10 @@ return var/mob/living/carbon/ML = A var/dam_zone = pick("chest", "l_hand", "r_hand", "l_leg", "r_leg") - var/obj/item/organ/limb/affecting = null - if(ishuman(ML)) // why the hell is this not more general - affecting = ML:get_organ(ran_zone(dam_zone)) + var/obj/item/bodypart/affecting = null + if(ishuman(ML)) + var/mob/living/carbon/human/H = ML + affecting = H.get_bodypart(ran_zone(dam_zone)) var/armor = ML.run_armor_check(affecting, "melee") if(prob(75)) ML.apply_damage(rand(1,3), BRUTE, affecting, armor) diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm index 743d1328a13..067730d32bf 100644 --- a/code/controllers/configuration.dm +++ b/code/controllers/configuration.dm @@ -202,6 +202,7 @@ var/client_error_version = 0 var/client_error_message = "Your version of byond is too old, may have issues, and is blocked from accessing this server." + var/cross_name = "Other server" /datum/configuration/New() var/list/L = subtypesof(/datum/game_mode) @@ -359,6 +360,12 @@ global.comms_key = value if(value != "default_pwd" && length(value) > 6) //It's the default value or less than 6 characters long, warn badmins global.comms_allowed = 1 + if("cross_server_address") + global.cross_address = value + if(value != "byond:\\address:port") + global.cross_allowed = 1 + if("cross_comms_name") + cross_name = value if("see_own_notes") config.see_own_notes = 1 if("soft_popcap") diff --git a/code/controllers/master.dm b/code/controllers/master.dm index 424ddf8f9c8..d48be2c82c4 100644 --- a/code/controllers/master.dm +++ b/code/controllers/master.dm @@ -69,6 +69,15 @@ var/global/datum/controller/master/Master = new() return world << "Initializing subsystems..." + var/tally = 0 + var/obj/effect/spawner/lootdrop/maintenance/L = new() + // Grab it before it gets deleted + var/list/loot = L.loot.Copy() + for(var/item in loot) + tally += loot[item] + world.log << "There are [tally] items in the \ + maintenance loot table." + preloadTemplates() // Pick a random away mission. createRandomZlevel() diff --git a/code/controllers/subsystem.dm b/code/controllers/subsystem.dm index dea6e9645a0..7decbd16a22 100644 --- a/code/controllers/subsystem.dm +++ b/code/controllers/subsystem.dm @@ -92,4 +92,5 @@ /datum/subsystem/on_varedit(edited_var) if (edited_var == "can_fire" && can_fire) next_fire = world.time + wait + ..() diff --git a/code/controllers/subsystem/voting.dm b/code/controllers/subsystem/voting.dm index 0549457940e..6279e25fc84 100644 --- a/code/controllers/subsystem/voting.dm +++ b/code/controllers/subsystem/voting.dm @@ -145,9 +145,19 @@ var/datum/subsystem/vote/SSvote /datum/subsystem/vote/proc/initiate_vote(vote_type, initiator_key) if(!mode) - if(started_time != null) + if(started_time) var/next_allowed_time = (started_time + config.vote_delay) - if(next_allowed_time > world.time) + if(mode) + usr << "There is already a vote in progress! please wait for it to finish." + return 0 + + var/admin = FALSE + var/ckey = ckey(initiator_key) + if((admin_datums[ckey]) || (ckey in deadmins)) + admin = TRUE + + if(next_allowed_time > world.time && !admin) + usr << "A vote was initiated recently, you must wait roughly [(next_allowed_time-world.time)/10] seconds before a new vote can be started!" return 0 reset() diff --git a/code/datums/action.dm b/code/datums/action.dm index 59976843017..677ccc18254 100644 --- a/code/datums/action.dm +++ b/code/datums/action.dm @@ -270,18 +270,21 @@ check_flags = AB_CHECK_CONSCIOUS /datum/action/item_action/organ_action/IsAvailable() - var/obj/item/organ/internal/I = target + var/obj/item/organ/I = target if(!I.owner) return 0 return ..() -/datum/action/item_action/organ_action/toggle - /datum/action/item_action/organ_action/toggle/New(Target) ..() name = "Toggle [target.name]" button.name = name +/datum/action/item_action/organ_action/use/New(Target) + ..() + name = "Use [target.name]" + button.name = name + diff --git a/code/datums/datumvars.dm b/code/datums/datumvars.dm index a436272faae..1908392d673 100644 --- a/code/datums/datumvars.dm +++ b/code/datums/datumvars.dm @@ -1,6 +1,10 @@ // reference: /client/proc/modify_variables(var/atom/O, var/param_var_name = null, var/autodetect_class = 0) -datum/proc/on_varedit(modified_var) //called whenever a var is edited +/datum + var/var_edited = 0 //Warrenty void if seal is broken + +/datum/proc/on_varedit(modified_var) //called whenever a var is edited + var_edited = 1 return /client/proc/debug_variables(datum/D in world) @@ -218,6 +222,8 @@ datum/proc/on_varedit(modified_var) //called whenever a var is edited if(src.holder && src.holder.marked_datum && src.holder.marked_datum == D) body += "
Marked Object" + if(D.var_edited) + body += "
Var Edited" body += "" body += "" @@ -270,6 +276,7 @@ datum/proc/on_varedit(modified_var) //called whenever a var is edited if(ishuman(D)) body += "" body += "" + body += "" body += "" body += "" body += "" @@ -887,6 +894,25 @@ body H.set_species(newtype) H.dna.species.admin_set_species(H,old_species) + else if(href_list["removebodypart"]) + if(!check_rights(R_SPAWN)) + return + + var/mob/living/carbon/human/H = locate(href_list["removebodypart"]) + if(!istype(H)) + usr << "This can only be done to instances of type /mob/living/carbon/human" + return + + var/result = input(usr, "Please choose which body part to remove","Remove Body Part") as null|anything in list("head", "l_arm", "r_arm", "l_leg", "r_leg") + + if(!H) + usr << "Mob doesn't exist anymore" + return + + if(result) + var/obj/item/bodypart/BP = H.get_bodypart(result) + if(BP) + BP.drop_limb() else if(href_list["purrbation"]) if(!check_rights(R_SPAWN)) diff --git a/code/datums/diseases/_MobProcs.dm b/code/datums/diseases/_MobProcs.dm index f5fcf511f2f..001614a66aa 100644 --- a/code/datums/diseases/_MobProcs.dm +++ b/code/datums/diseases/_MobProcs.dm @@ -140,6 +140,6 @@ /mob/living/carbon/human/CanContractDisease(datum/disease/D) - if(dna && VIRUSIMMUNE in dna.species.specflags) + if(dna && (VIRUSIMMUNE in dna.species.specflags)) return 0 return ..() \ No newline at end of file diff --git a/code/datums/diseases/_disease.dm b/code/datums/diseases/_disease.dm index e96b40ca822..87a55138682 100644 --- a/code/datums/diseases/_disease.dm +++ b/code/datums/diseases/_disease.dm @@ -164,7 +164,7 @@ var/list/diseases = subtypesof(/datum/disease) if(ishuman(affected_mob)) var/mob/living/carbon/human/H = affected_mob for(var/obj/item/organ/O in required_organs) - if(!locate(O) in H.organs) + if(!locate(O) in H.bodyparts) if(!locate(O) in H.internal_organs) cure() return diff --git a/code/datums/diseases/advance/symptoms/damage_converter.dm b/code/datums/diseases/advance/symptoms/damage_converter.dm index ce8c644a67f..c6b4f0a87d0 100644 --- a/code/datums/diseases/advance/symptoms/damage_converter.dm +++ b/code/datums/diseases/advance/symptoms/damage_converter.dm @@ -40,12 +40,12 @@ Bonus if(istype(M, /mob/living/carbon/human)) var/mob/living/carbon/human/H = M - var/list/parts = H.get_damaged_organs(1,1) //1,1 because it needs inputs. + var/list/parts = H.get_damaged_bodyparts(1,1) //1,1 because it needs inputs. if(!parts.len) return - for(var/obj/item/organ/limb/L in parts) + for(var/obj/item/bodypart/L in parts) L.heal_damage(get_damage, get_damage, 0) M.adjustToxLoss(get_damage*parts.len) diff --git a/code/datums/diseases/appendicitis.dm b/code/datums/diseases/appendicitis.dm index 499a5aaa924..77ec5a583d4 100644 --- a/code/datums/diseases/appendicitis.dm +++ b/code/datums/diseases/appendicitis.dm @@ -12,7 +12,7 @@ disease_flags = CAN_CARRY|CAN_RESIST spread_flags = NON_CONTAGIOUS visibility_flags = HIDDEN_PANDEMIC - required_organs = list(/obj/item/organ/internal/appendix) + required_organs = list(/obj/item/organ/appendix) /datum/disease/appendicitis/stage_act() ..() @@ -21,7 +21,7 @@ if(prob(5)) affected_mob.emote("cough") if(2) - var/obj/item/organ/internal/appendix/A = affected_mob.getorgan(/obj/item/organ/internal/appendix) + var/obj/item/organ/appendix/A = affected_mob.getorgan(/obj/item/organ/appendix) if(A) A.inflamed = 1 A.update_icon() diff --git a/code/datums/diseases/brainrot.dm b/code/datums/diseases/brainrot.dm index 01464fe65fe..8a0349854cb 100644 --- a/code/datums/diseases/brainrot.dm +++ b/code/datums/diseases/brainrot.dm @@ -9,7 +9,7 @@ viable_mobtypes = list(/mob/living/carbon/human) cure_chance = 15//higher chance to cure, since two reagents are required desc = "This disease destroys the braincells, causing brain fever, brain necrosis and general intoxication." - required_organs = list(/obj/item/organ/limb/head) + required_organs = list(/obj/item/bodypart/head) severity = DANGEROUS /datum/disease/brainrot/stage_act() //Removed toxloss because damaging diseases are pretty horrible. Last round it killed the entire station because the cure didn't work -- Urist -ACTUALLY Removed rather than commented out, I don't see it returning - RR diff --git a/code/datums/diseases/dna_spread.dm b/code/datums/diseases/dna_spread.dm index d627fe8edbe..11a8eebbe5d 100644 --- a/code/datums/diseases/dna_spread.dm +++ b/code/datums/diseases/dna_spread.dm @@ -18,7 +18,7 @@ ..() if(!affected_mob.dna) cure() - if(affected_mob.dna.species.specflags & NOTRANSSTING) //Only species that can be spread by transformation sting can be spread by the retrovirus + if(NOTRANSSTING in affected_mob.dna.species.specflags) //Only species that can be spread by transformation sting can be spread by the retrovirus cure() if(!strain_data["dna"]) diff --git a/code/datums/diseases/tuberculosis.dm b/code/datums/diseases/tuberculosis.dm index 6086d6d0b22..b2d4fb9065b 100644 --- a/code/datums/diseases/tuberculosis.dm +++ b/code/datums/diseases/tuberculosis.dm @@ -8,7 +8,7 @@ viable_mobtypes = list(/mob/living/carbon/human) cure_chance = 5//like hell are you getting out of hell desc = "A rare highly transmittable virulent virus. Few samples exist, rumoured to be carefully grown and cultured by clandestine bio-weapon specialists. Causes fever, blood vomiting, lung damage, weight loss, and fatigue." - required_organs = list(/obj/item/organ/limb/head) + required_organs = list(/obj/item/bodypart/head) severity = DANGEROUS /datum/disease/tuberculosis/stage_act() //it begins diff --git a/code/datums/diseases/wizarditis.dm b/code/datums/diseases/wizarditis.dm index 25c73a7f0ed..bc9d70fc63c 100644 --- a/code/datums/diseases/wizarditis.dm +++ b/code/datums/diseases/wizarditis.dm @@ -11,7 +11,7 @@ permeability_mod = 0.75 desc = "Some speculate, that this virus is the cause of Wizard Federation existance. Subjects affected show the signs of mental retardation, yelling obscure sentences or total gibberish. On late stages subjects sometime express the feelings of inner power, and, cite, 'the ability to control the forces of cosmos themselves!' A gulp of strong, manly spirits usually reverts them to normal, humanlike, condition." severity = HARMFUL - required_organs = list(/obj/item/organ/limb/head) + required_organs = list(/obj/item/bodypart/head) /* BIRUZ BENNAR diff --git a/code/datums/martial.dm b/code/datums/martial.dm index d1b498f5070..46e18dde7d7 100644 --- a/code/datums/martial.dm +++ b/code/datums/martial.dm @@ -41,7 +41,7 @@ add_logs(A, D, "attempted to [atk_verb]") return 0 - var/obj/item/organ/limb/affecting = D.get_organ(ran_zone(A.zone_selected)) + var/obj/item/bodypart/affecting = D.get_bodypart(ran_zone(A.zone_selected)) var/armor_block = D.run_armor_check(affecting, "melee") playsound(D.loc, A.dna.species.attack_sound, 25, 1, -1) @@ -106,7 +106,7 @@ return 0 - var/obj/item/organ/limb/affecting = D.get_organ(ran_zone(A.zone_selected)) + var/obj/item/bodypart/affecting = D.get_bodypart(ran_zone(A.zone_selected)) var/armor_block = D.run_armor_check(affecting, "melee") playsound(D.loc, A.dna.species.attack_sound, 25, 1, -1) @@ -128,64 +128,6 @@ D.forcesay(hit_appends) return 1 -/datum/martial_art/wrestling - name = "Wrestling" - help_verb = /mob/living/carbon/human/proc/wrestling_help - -// combo refence since wrestling uses a different format to sleeping carp and plasma fist. -// Clinch "G" -// Suplex "GD" -// Advanced grab "G" - -/datum/martial_art/wrestling/harm_act(mob/living/carbon/human/A, mob/living/carbon/human/D) - D.grabbedby(A,1) - var/obj/item/weapon/grab/G = A.get_active_hand() - if(G && prob(50)) - G.state = GRAB_AGGRESSIVE - D.visible_message("[A] has [D] in a clinch!", \ - "[A] has [D] in a clinch!") - else - D.visible_message("[A] fails to get [D] in a clinch!", \ - "[A] fails to get [D] in a clinch!") - return 1 - - -/datum/martial_art/wrestling/proc/Suplex(mob/living/carbon/human/A, mob/living/carbon/human/D) - - D.visible_message("[A] suplexes [D]!", \ - "[A] suplexes [D]!") - D.forceMove(A.loc) - var/armor_block = D.run_armor_check(null, "melee") - D.apply_damage(30, BRUTE, null, armor_block) - D.apply_effect(6, WEAKEN, armor_block) - add_logs(A, D, "suplexed") - - A.SpinAnimation(10,1) - - D.SpinAnimation(10,1) - spawn(3) - armor_block = A.run_armor_check(null, "melee") - A.apply_effect(4, WEAKEN, armor_block) - return - -/datum/martial_art/wrestling/disarm_act(mob/living/carbon/human/A, mob/living/carbon/human/D) - if(istype(A.get_inactive_hand(),/obj/item/weapon/grab)) - var/obj/item/weapon/grab/G = A.get_inactive_hand() - if(G.affecting == D) - Suplex(A,D) - return 1 - harm_act(A,D) - return 1 - -/datum/martial_art/wrestling/grab_act(mob/living/carbon/human/A, mob/living/carbon/human/D) - D.grabbedby(A,1) - D.visible_message("[A] holds [D] down!", \ - "[A] holds [D] down!") - var/obj/item/organ/limb/affecting = D.get_organ(ran_zone(A.zone_selected)) - var/armor_block = D.run_armor_check(affecting, "melee") - D.apply_damage(10, STAMINA, affecting, armor_block) - return 1 - /mob/living/carbon/human/proc/wrestling_help() set name = "Recall Teachings" set desc = "Remember how to wrestle." @@ -452,7 +394,6 @@ if(slot == slot_belt) var/mob/living/carbon/human/H = user style.teach(H,1) - user << "You have an urge to flex your muscles and get into a fight. You have the knowledge of a thousand wrestlers before you. You can remember more by using the Recall teaching verb in the wrestling tab." return /obj/item/weapon/storage/belt/champion/wrestling/dropped(mob/user) @@ -461,7 +402,6 @@ var/mob/living/carbon/human/H = user if(H.get_item_by_slot(slot_belt) == src) style.remove(H) - user << "You no longer have an urge to flex your muscles." return /obj/item/weapon/plasma_fist_scroll diff --git a/code/datums/martial/wrestling.dm b/code/datums/martial/wrestling.dm new file mode 100644 index 00000000000..c80217e7754 --- /dev/null +++ b/code/datums/martial/wrestling.dm @@ -0,0 +1,421 @@ +/datum/martial_art/wrestling + name = "Wrestling" + var/datum/action/slam/slam = new/datum/action/slam() + var/datum/action/throw_wrassle/throw_wrassle = new/datum/action/throw_wrassle() + var/datum/action/kick/kick = new/datum/action/kick() + var/datum/action/strike/strike = new/datum/action/strike() + var/datum/action/drop/drop = new/datum/action/drop() + +/datum/martial_art/wrestling/proc/check_streak(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) + switch(streak) + if("drop") + streak = "" + drop(A,D) + return 1 + if("strike") + streak = "" + strike(A,D) + return 1 + if("kick") + streak = "" + kick(A,D) + return 1 + if("throw") + streak = "" + throw_wrassle(A,D) + return 1 + if("slam") + streak = "" + slam(A,D) + return 1 + return 0 + +/datum/action/slam + name = "Slam (Cinch) - Slam a grappled opponent into the floor." + button_icon_state = "wrassle_slam" + +/datum/action/slam/Trigger() + if(owner.incapacitated()) + owner << "You can't WRESTLE while you're OUT FOR THE COUNT." + return + owner.visible_message("[owner] prepares to BODY SLAM!", "Your next attack will be a BODY SLAM.") + var/mob/living/carbon/human/H = owner + H.martial_art.streak = "slam" + +/datum/action/throw_wrassle + name = "Throw (Cinch) - Spin a cinched opponent around and throw them." + button_icon_state = "wrassle_throw" + +/datum/action/throw_wrassle/Trigger() + if(owner.incapacitated()) + owner << "You can't WRESTLE while you're OUT FOR THE COUNT." + return + owner.visible_message("[owner] prepares to THROW!", "Your next attack will be a THROW.") + var/mob/living/carbon/human/H = owner + H.martial_art.streak = "throw" + +/datum/action/kick + name = "Kick - A powerful kick, sends people flying away from you. Also useful for escaping from bad situations." + button_icon_state = "wrassle_kick" + +/datum/action/kick/Trigger() + if(owner.incapacitated()) + owner << "You can't WRESTLE while you're OUT FOR THE COUNT." + return + owner.visible_message("[owner] prepares to KICK!", "Your next attack will be a KICK.") + var/mob/living/carbon/human/H = owner + H.martial_art.streak = "kick" + +/datum/action/strike + name = "Strike - Hit a neaby opponent with a quick attack." + button_icon_state = "wrassle_strike" + +/datum/action/strike/Trigger() + if(owner.incapacitated()) + owner << "You can't WRESTLE while you're OUT FOR THE COUNT." + return + owner.visible_message("[owner] prepares to STRIKE!", "Your next attack will be a STRIKE.") + var/mob/living/carbon/human/H = owner + H.martial_art.streak = "strike" + +/datum/action/drop + name = "Drop - Smash down onto an opponent." + button_icon_state = "wrassle_drop" + +/datum/action/drop/Trigger() + if(owner.incapacitated()) + owner << "You can't WRESTLE while you're OUT FOR THE COUNT." + return + owner.visible_message("[owner] prepares to LEG DROP!", "Your next attack will be a LEG DROP.") + var/mob/living/carbon/human/H = owner + H.martial_art.streak = "drop" + +/datum/martial_art/wrestling/teach(var/mob/living/carbon/human/H,var/make_temporary=0) + ..() + H << "SNAP INTO A THIN TIM!" + H << "Place your cursor over a move at the top of the screen to see what it does." + drop.Grant(H) + kick.Grant(H) + slam.Grant(H) + throw_wrassle.Grant(H) + strike.Grant(H) + +/datum/martial_art/wrestling/remove(var/mob/living/carbon/human/H) + ..() + H << "You no longer feel that the tower of power is too sweet to be sour..." + drop.Remove(H) + kick.Remove(H) + slam.Remove(H) + throw_wrassle.Remove(H) + strike.Remove(H) + +/datum/martial_art/wrestling/harm_act(mob/living/carbon/human/A, mob/living/carbon/human/D) + if(check_streak(A,D)) + return 1 + ..() + +/datum/martial_art/wrestling/proc/throw_wrassle(mob/living/carbon/human/A, mob/living/carbon/human/D) + if(!D) + return + if(!A.pulling || A.pulling != D) + A << "You need to have [D] in a cinch!" + return + D.forceMove(A.loc) + D.dir = get_dir(D, A) + + D.Stun(4) + A.visible_message("[A] starts spinning around with [D]!") + A.emote("scream") + + for (var/i = 0, i < 20, i++) + var/delay = 5 + switch (i) + if (17 to INFINITY) + delay = 0.25 + if (14 to 16) + delay = 0.5 + if (9 to 13) + delay = 1 + if (5 to 8) + delay = 2 + if (0 to 4) + delay = 3 + + if (A && D) + + if (get_dist(A, D) > 1) + A << "[D] is too far away!" + return 0 + + if (!isturf(A.loc) || !isturf(D.loc)) + A << "You can't throw [D] from here!" + return 0 + + A.dir = turn(A.dir, 90) + var/turf/T = get_step(A, A.dir) + var/turf/S = D.loc + if ((S && isturf(S) && S.Exit(D)) && (T && isturf(T) && T.Enter(A))) + D.forceMove(T) + D.dir = get_dir(D, A) + else + return 0 + + sleep(delay) + + if (A && D) + // These are necessary because of the sleep call. + + if (get_dist(A, D) > 1) + A << "[D] is too far away!" + return 0 + + if (!isturf(A.loc) || !isturf(D.loc)) + A << "You can't throw [D] from here!" + return 0 + + D.forceMove(A.loc) // Maybe this will help with the wallthrowing bug. + + A.visible_message("[A] throws [D]!") + playsound(A.loc, "swing_hit", 50, 1) + var/turf/T = get_edge_target_turf(A, A.dir) + if (T && isturf(T)) + if (!D.stat) + D.emote("scream") + D.throw_at(T, 10, 4) + D.Weaken(2) + + return 0 + +/datum/martial_art/wrestling/proc/slam(mob/living/carbon/human/A, mob/living/carbon/human/D) + if(!D) + return + if(!A.pulling || A.pulling != D) + A << "You need to have [D] in a cinch!" + return + D.forceMove(A.loc) + A.dir = get_dir(A, D) + D.dir = get_dir(D, A) + + A.visible_message("[A] lifts [D] up!") + + spawn (0) + if (D) + animate(D, transform = matrix(180, MATRIX_ROTATE), time = 1, loop = 0) + sleep (15) + if (D) + animate(transform = null, time = 1, loop = 0) + + for (var/i = 0, i < 3, i++) + if (A && D) + A.pixel_y += 3 + D.pixel_y += 3 + A.dir = turn(A.dir, 90) + D.dir = turn(D.dir, 90) + + switch (A.dir) + if (NORTH) + D.pixel_x = A.pixel_x + if (SOUTH) + D.pixel_x = A.pixel_x + if (EAST) + D.pixel_x = A.pixel_x - 8 + if (WEST) + D.pixel_x = A.pixel_x + 8 + + if (get_dist(A, D) > 1) + A << "[D] is too far away!" + A.pixel_x = 0 + A.pixel_y = 0 + D.pixel_x = 0 + D.pixel_y = 0 + return 0 + + if (!isturf(A.loc) || !isturf(D.loc)) + A << "You can't slam [D] here!" + A.pixel_x = 0 + A.pixel_y = 0 + D.pixel_x = 0 + D.pixel_y = 0 + return 0 + else + if (A) + A.pixel_x = 0 + A.pixel_y = 0 + if (D) + D.pixel_x = 0 + D.pixel_y = 0 + return 0 + + sleep (1) + + if (A && D) + A.pixel_x = 0 + A.pixel_y = 0 + D.pixel_x = 0 + D.pixel_y = 0 + + if (get_dist(A, D) > 1) + A << "[D] is too far away!" + return 0 + + if (!isturf(A.loc) || !isturf(D.loc)) + A << "You can't slam [D] here!" + return 0 + + D.forceMove(A.loc) + + var/fluff = "body-slam" + switch(pick(2,3)) + if (2) + fluff = "turbo [fluff]" + if (3) + fluff = "atomic [fluff]" + + A.visible_message("[A] [fluff] [D]!") + playsound(A.loc, "swing_hit", 50, 1) + if (!D.stat) + D.emote("scream") + D.weakened += 2 + D.stunned += 2 + + switch(rand(1,3)) + if (2) + D.adjustBruteLoss(rand(20,30)) + if (3) + D.ex_act(3) + else + D.adjustBruteLoss(rand(10,20)) + else + D.ex_act(3) + + else + if (A) + A.pixel_x = 0 + A.pixel_y = 0 + if (D) + D.pixel_x = 0 + D.pixel_y = 0 + + + return 0 + +/datum/martial_art/wrestling/proc/strike(mob/living/carbon/human/A, mob/living/carbon/human/D) + if(!D) + return + var/turf/T = get_turf(A) + if (T && isturf(T) && D && isturf(D.loc)) + for (var/i = 0, i < 4, i++) + A.dir = turn(A.dir, 90) + + A.forceMove(D.loc) + spawn (4) + if (A && (T && isturf(T) && get_dist(A, T) <= 1)) + A.forceMove(T) + + A.visible_message("[A] headbutts [D]!") + D.adjustBruteLoss(rand(10,20)) + playsound(A.loc, "swing_hit", 50, 1) + D.Paralyse(1) + +/datum/martial_art/wrestling/proc/kick(mob/living/carbon/human/A, mob/living/carbon/human/D) + if(!D) + return + A.emote("scream") + A.emote("flip") + A.dir = turn(A.dir, 90) + + A.visible_message("[A] roundhouse-kicks [D]!") + playsound(A.loc, "swing_hit", 50, 1) + D.adjustBruteLoss(rand(10,20)) + + var/turf/T = get_edge_target_turf(A, get_dir(A, get_step_away(D, A))) + if (T && isturf(T)) + D.Weaken(1) + D.throw_at(T, 3, 2) + +/datum/martial_art/wrestling/proc/drop(mob/living/carbon/human/A, mob/living/carbon/human/D) + if(!D) + return + var/obj/surface = null + var/turf/ST = null + var/falling = 0 + + for (var/obj/O in oview(1, A)) + if (O.density == 1) + if (O == A) continue + if (O == D) continue + if (O.opacity) continue + else + surface = O + ST = get_turf(O) + break + + if (surface && (ST && isturf(ST))) + A.forceMove(ST) + A.visible_message("[A] climbs onto [surface]!") + A.pixel_y = 10 + falling = 1 + sleep(10) + + if (A && D) + // These are necessary because of the sleep call. + + if ((falling == 0 && get_dist(A, D) > 1) || (falling == 1 && get_dist(A, D) > 2)) // We climbed onto stuff. + A.pixel_y = 0 + if (falling == 1) + A.visible_message("...and dives head-first into the ground, ouch!") + A.adjustBruteLoss(rand(10,20)) + A.Weaken(3) + A << "[D] is too far away!" + return 0 + + if (!isturf(A.loc) || !isturf(D.loc)) + A.pixel_y = 0 + A << "You can't drop onto [D] from here!" + return 0 + + if(A) + animate(A, transform = matrix(90, MATRIX_ROTATE), time = 1, loop = 0) + sleep(10) + if(A) + animate(A, transform = null, time = 1, loop = 0) + + A.forceMove(D.loc) + + A.visible_message("[A] leg-drops [D]!") + playsound(A.loc, "swing_hit", 50, 1) + A.emote("scream") + + if (falling == 1) + if (prob(33) || D.stat) + D.ex_act(3) + else + D.adjustBruteLoss(rand(20,30)) + else + D.adjustBruteLoss(rand(20,30)) + + D.Weaken(1) + D.Stun(2) + + A.pixel_y = 0 + + else + if (A) + A.pixel_y = 0 + return + +/datum/martial_art/wrestling/disarm_act(mob/living/carbon/human/A, mob/living/carbon/human/D) + if(check_streak(A,D)) + return 1 + ..() + +/datum/martial_art/wrestling/grab_act(mob/living/carbon/human/A, mob/living/carbon/human/D) + if(check_streak(A,D)) + return 1 + if(A.pulling == D) + return 1 + A.start_pulling(D) + D.visible_message("[A] gets [D] in a cinch!", \ + "[A] gets [D] in a cinch!") + D.Stun(rand(3,5)) + return 1 diff --git a/code/datums/mind.dm b/code/datums/mind.dm index 933d8ff2db8..1587bc4b8d2 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -146,11 +146,7 @@ /datum/mind/proc/remove_cultist() if(src in ticker.mode.cult) - ticker.mode.cult -= src - ticker.mode.update_cult_icons_removed(src) - var/datum/game_mode/cult/cult = ticker.mode - if(istype(cult)) - cult.memorize_cult_objectives(src) + ticker.mode.remove_cultist(src, 0, 0) special_role = null remove_objectives() remove_antag_equip() @@ -488,20 +484,20 @@ if(ticker.mode.config_tag == "handofgod") text = uppertext(text) text = "[text]: " - if(src in ticker.mode.red_deity_prophets) - text += "RED PROPHET|red follower|employee|blue follower|blue prophet|red god|blue god" + if (src in ticker.mode.red_deities) + text += "RED GOD|red prophet|red follower|employee|blue god|blue prophet|blue follower" + else if(src in ticker.mode.red_deity_prophets) + text += "red god|RED PROPHET|red follower|employee|blue god|blue prophet|blue follower" else if (src in ticker.mode.red_deity_followers) - text += "red prophet|RED FOLLOWER|employee|blue follower|blue prophet|red god|blue god" - else if (src in ticker.mode.blue_deity_followers) - text += "red prophet|red follower|employee|BLUE FOLLOWER|blue prophet|red god|blue god" - else if (src in ticker.mode.blue_deity_prophets) - text += "red prophet|red follower|employee|blue follower|BLUE PROPHET|red god|blue god" - else if (src in ticker.mode.red_deities) - text += "red prophet|red follower|employee|blue follower|blue prophet|RED GOD|blue god" + text += "red god|red prophet|RED FOLLOWER|employee|blue god|blue prophet|blue follower" else if (src in ticker.mode.blue_deities) - text += "red prophet|red follower|employee|blue follower|blue prophet|red god|BLUE GOD" + text += "red god|red prophet|red follower|employee|BLUE GOD|blue prophet|blue follower" + else if (src in ticker.mode.blue_deity_prophets) + text += "red god|red prophet|red follower|employee|blue god|BLUE PROPHET|blue follower" + else if (src in ticker.mode.blue_deity_followers) + text += "red god|red prophet|red follower|employee|blue god|blue prophet|BLUE FOLLOWER" else - text += "red prophet|red follower|EMPLOYEE|blue follower|blue prophet|red god|blue god" + text += "red god|red prophet|red follower|EMPLOYEE|blue god|blue prophet|blue follower" if(current && current.client && (ROLE_HOG_GOD in current.client.prefs.be_special)) text += "|HOG God Enabled in Prefs" @@ -983,12 +979,11 @@ switch(href_list["cult"]) if("clear") remove_cultist() - current << "You have been brainwashed! You are no longer a cultist!" message_admins("[key_name_admin(usr)] has de-cult'ed [current].") log_admin("[key_name(usr)] has de-cult'ed [current].") if("cultist") if(!(src in ticker.mode.cult)) - ticker.mode.add_cultist(src) + ticker.mode.add_cultist(src, 0) message_admins("[key_name_admin(usr)] has cult'ed [current].") log_admin("[key_name(usr)] has cult'ed [current].") if("tome") diff --git a/code/datums/mutations.dm b/code/datums/mutations.dm index 4a74b38236d..3111a81c8d4 100644 --- a/code/datums/mutations.dm +++ b/code/datums/mutations.dm @@ -19,6 +19,7 @@ var/layer_used = MUTATIONS_LAYER //which mutation layer to use var/list/species_allowed = list() //to restrict mutation to only certain species var/health_req //minimum health required to acquire the mutation + var/limb_req //required limbs to acquire this mutation var/time_coeff = 1 //coefficient for timed mutations /datum/mutation/human/proc/force_give(mob/living/carbon/human/owner) @@ -61,6 +62,8 @@ return 1 if(health_req && owner.health < health_req) return 1 + if(limb_req && !owner.get_bodypart(limb_req)) + return 1 owner.dna.mutations.Add(src) if(text_gain_indication) owner << text_gain_indication @@ -120,24 +123,16 @@ species_allowed = list("human") //no skeleton/lizard hulk health_req = 25 -/datum/mutation/human/hulk/New() - ..() - visual_indicators |= image("icon"='icons/effects/genetics.dmi', "icon_state"="hulk_f_s", "layer"=-MUTATIONS_LAYER) - visual_indicators |= image("icon"='icons/effects/genetics.dmi', "icon_state"="hulk_m_s", "layer"=-MUTATIONS_LAYER) - /datum/mutation/human/hulk/on_acquiring(mob/living/carbon/human/owner) if(..()) return var/status = CANSTUN | CANWEAKEN | CANPARALYSE | CANPUSH owner.status_flags &= ~status + owner.update_body_parts() /datum/mutation/human/hulk/on_attack_hand(mob/living/carbon/human/owner, atom/target) return target.attack_hulk(owner) -/datum/mutation/human/hulk/get_visual_indicator(mob/living/carbon/human/owner) - var/g = (owner.gender == FEMALE) ? 1 : 2 - return visual_indicators[g] - /datum/mutation/human/hulk/on_life(mob/living/carbon/human/owner) if(owner.health < 0) on_losing(owner) @@ -147,6 +142,7 @@ if(..()) return owner.status_flags |= CANSTUN | CANWEAKEN | CANPARALYSE | CANPUSH + owner.update_body_parts() /datum/mutation/human/hulk/say_mod(message) if(message) @@ -160,6 +156,7 @@ get_chance = 20 lowest_value = 256 * 12 text_gain_indication = "You feel smarter!" + limb_req = "head" /datum/mutation/human/telekinesis/New() ..() @@ -613,6 +610,7 @@ dna_block = NON_SCANNABLE text_gain_indication = "You feel pressure building up behind your eyes." layer_used = FRONT_MUTATIONS_LAYER + limb_req = "head" /datum/mutation/human/laser_eyes/New() ..() diff --git a/code/game/asteroid.dm b/code/game/asteroid.dm index 4b1786c596a..37e7a2f52b3 100644 --- a/code/game/asteroid.dm +++ b/code/game/asteroid.dm @@ -65,7 +65,7 @@ var/global/max_secret_rooms = 6 walltypes = list(/turf/closed/wall/r_wall=2,/turf/closed/wall=2,/turf/closed/mineral/random/high_chance=1) floortypes = list(/turf/open/floor/plasteel,/turf/open/floor/engine) treasureitems = list(/mob/living/simple_animal/bot/medbot/mysterious=1, /obj/item/weapon/circular_saw=1, /obj/structure/closet/crate/critter=2, /mob/living/simple_animal/pet/cat/space=1) - fluffitems = list(/obj/effect/decal/cleanable/blood=5,/obj/item/organ/internal/appendix=2,/obj/structure/closet/crate/freezer=2, + fluffitems = list(/obj/effect/decal/cleanable/blood=5,/obj/item/organ/appendix=2,/obj/structure/closet/crate/freezer=2, /obj/structure/table/optable=1,/obj/item/weapon/scalpel=1,/obj/item/weapon/storage/firstaid/regular=3, /obj/item/weapon/tank/internals/anesthetic=1, /obj/item/weapon/surgical_drapes=2, /obj/item/device/mass_spectrometer/adv=1,/obj/item/clothing/glasses/hud/health=1) @@ -76,7 +76,7 @@ var/global/max_secret_rooms = 6 treasureitems = list(/obj/item/device/soulstone/anybody=1, /obj/item/clothing/suit/space/cult=1, /obj/item/weapon/bedsheet/cult=2, /obj/item/clothing/suit/cultrobes=2, /mob/living/simple_animal/hostile/creature=3) fluffitems = list(/obj/effect/gateway=1,/obj/effect/gibspawner=1,/obj/structure/cult/talisman=1,/obj/item/toy/crayon/red=2, - /obj/item/organ/internal/heart=2, /obj/effect/decal/cleanable/blood=4,/obj/structure/table/wood=2,/obj/item/weapon/ectoplasm=3, + /obj/item/organ/heart=2, /obj/effect/decal/cleanable/blood=4,/obj/structure/table/wood=2,/obj/item/weapon/ectoplasm=3, /obj/item/clothing/head/helmet/space/cult=1, /obj/item/clothing/shoes/cult=1) if("wizden") diff --git a/code/game/atoms.dm b/code/game/atoms.dm index e6727a1f781..038b52b7a91 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -402,3 +402,4 @@ var/list/blood_splatter_icons = list() var/datum/reagent/consumable/nutri_check = R if(nutri_check.nutriment_factor >0) M.reagents.remove_reagent(R.id,R.volume) + diff --git a/code/game/data_huds.dm b/code/game/data_huds.dm index 14a79e8a9ae..4185dc51a4b 100644 --- a/code/game/data_huds.dm +++ b/code/game/data_huds.dm @@ -16,7 +16,7 @@ /datum/atom_hud/data /datum/atom_hud/data/human/medical - hud_icons = list(HEALTH_HUD, STATUS_HUD) + hud_icons = list(STATUS_HUD, HEALTH_HUD) /datum/atom_hud/data/human/medical/basic @@ -67,24 +67,49 @@ return 0 //helper for getting the appropriate health status -/proc/RoundHealth(health) - switch(health) +/proc/RoundHealth(mob/living/M) + if(M.stat == DEAD) + return "health-100" //what's our health? it doesn't matter, we're dead + var/resulthealth = (M.health / M.maxHealth) * 100 + switch(resulthealth) if(100 to INFINITY) return "health100" - if(70 to 100) - return "health80" - if(50 to 70) - return "health60" - if(30 to 50) - return "health40" - if(18 to 30) + if(90.625 to 100) + return "health93.75" + if(84.375 to 90.625) + return "health87.5" + if(78.125 to 84.375) + return "health81.25" + if(71.875 to 78.125) + return "health75" + if(65.625 to 71.875) + return "health68.75" + if(59.375 to 65.625) + return "health62.5" + if(53.125 to 59.375) + return "health56.25" + if(46.875 to 53.125) + return "health50" + if(40.625 to 46.875) + return "health43.75" + if(34.375 to 40.625) + return "health37.5" + if(28.125 to 34.375) + return "health31.25" + if(21.875 to 28.125) return "health25" - if(5 to 18) - return "health10" - if(1 to 5) - return "health1" - if(-99 to 0) + if(15.625 to 21.875) + return "health18.75" + if(9.375 to 15.625) + return "health12.5" + if(1 to 9.375) + return "health6.25" + if(-50 to 1) return "health0" + if(-85 to -50) + return "health-50" + if(-99 to -85) + return "health-85" else return "health-100" return "0" @@ -99,20 +124,28 @@ var/turf/T = get_turf(src) if (T) crewmonitor.queueUpdate(T.z) -//called when a carbon changes health -/mob/living/carbon/proc/med_hud_set_health() +//called when a living mob changes health +/mob/living/proc/med_hud_set_health() var/image/holder = hud_list[HEALTH_HUD] - if(stat == DEAD) - holder.icon_state = "hudhealth-100" - else - holder.icon_state = "hud[RoundHealth(health)]" + holder.icon_state = "hud[RoundHealth(src)]" + +//for carbon suit sensors +/mob/living/carbon/med_hud_set_health() + ..() var/turf/T = get_turf(src) - if (T) + if(T) crewmonitor.queueUpdate(T.z) //called when a carbon changes stat, virus or XENO_HOST -/mob/living/carbon/proc/med_hud_set_status() +/mob/living/proc/med_hud_set_status() + var/image/holder = hud_list[STATUS_HUD] + if(stat == DEAD) + holder.icon_state = "huddead" + else + holder.icon_state = "hudhealthy" + +/mob/living/carbon/med_hud_set_status() var/image/holder = hud_list[STATUS_HUD] if(stat == DEAD) holder.icon_state = "huddead" diff --git a/code/game/dna.dm b/code/game/dna.dm index b1e51e9b5e5..5ea7e2f103e 100644 --- a/code/game/dna.dm +++ b/code/game/dna.dm @@ -183,7 +183,7 @@ if(icon_update) update_body() update_hair() - update_mutcolor() + update_body_parts() update_mutations_overlay()// no lizard with human hulk overlay please. @@ -220,7 +220,7 @@ if(mrace || newfeatures || ui) update_body() update_hair() - update_mutcolor() + update_body_parts() update_mutations_overlay() @@ -249,7 +249,7 @@ mob/living/carbon/human/updateappearance(icon_update=1, mutcolor_update=0, mutat update_body() update_hair() if(mutcolor_update) - update_mutcolor() + update_body_parts() if(mutations_overlay_update) update_mutations_overlay() diff --git a/code/game/gamemodes/blob/blobs/blob_mobs.dm b/code/game/gamemodes/blob/blobs/blob_mobs.dm index 7f433d5fc36..037d0d246ea 100644 --- a/code/game/gamemodes/blob/blobs/blob_mobs.dm +++ b/code/game/gamemodes/blob/blobs/blob_mobs.dm @@ -89,6 +89,8 @@ attacktext = "hits" attack_sound = 'sound/weapons/genhit1.ogg' flying = 1 + del_on_death = 1 + deathmessage = "The blob spore explodes into a cloud of gas!" var/death_cloud_size = 1 //size of cloud produced from a dying spore var/list/human_overlays = list() var/is_zombie = 0 @@ -134,7 +136,6 @@ visible_message("The corpse of [H.name] suddenly rises!") /mob/living/simple_animal/hostile/blob/blobspore/death(gibbed) - ..(1) // On death, create a small smoke of harmful gas (s-Acid) var/datum/effect_system/smoke_spread/chem/S = new var/turf/location = get_turf(src) @@ -151,9 +152,10 @@ S.attach(location) S.set_up(reagents, death_cloud_size, location, silent=1) S.start() + if(factory) + factory.spore_delay = world.time + factory.spore_cooldown //put the factory on cooldown - ghostize() - qdel(src) + ..() /mob/living/simple_animal/hostile/blob/blobspore/Destroy() if(factory) diff --git a/code/game/gamemodes/blob/blobs/factory.dm b/code/game/gamemodes/blob/blobs/factory.dm index 8ee6baa2c73..ccaf8e12a1a 100644 --- a/code/game/gamemodes/blob/blobs/factory.dm +++ b/code/game/gamemodes/blob/blobs/factory.dm @@ -11,6 +11,7 @@ var/mob/living/simple_animal/hostile/blob/blobbernaut/naut = null var/max_spores = 3 var/spore_delay = 0 + var/spore_cooldown = 80 //8 seconds between spores and after spore death /obj/effect/blob/factory/scannerreport() @@ -38,7 +39,7 @@ if(spore_delay > world.time) return flick("blob_factory_glow", src) - spore_delay = world.time + 100 // 10 seconds + spore_delay = world.time + spore_cooldown var/mob/living/simple_animal/hostile/blob/blobspore/BS = new/mob/living/simple_animal/hostile/blob/blobspore(src.loc, src) if(overmind) //if we don't have an overmind, we don't need to do anything but make a spore BS.overmind = overmind diff --git a/code/game/gamemodes/blob/theblob.dm b/code/game/gamemodes/blob/theblob.dm index 1ff18339458..72112430613 100644 --- a/code/game/gamemodes/blob/theblob.dm +++ b/code/game/gamemodes/blob/theblob.dm @@ -225,16 +225,24 @@ user.changeNext_move(CLICK_CD_MELEE) user << "The analyzer beeps once, then reports:
" user << 'sound/machines/ping.ogg' - if(overmind) - user << "Material: [overmind.blob_reagent_datum.name]." - user << "Material Effects: [overmind.blob_reagent_datum.analyzerdescdamage]" - user << "Material Properties: [overmind.blob_reagent_datum.analyzerdesceffect]
" - user << "Blob Type: [uppertext(initial(name))]" - user << "Health: [health]/[maxhealth]" - user << "Effects: [scannerreport()]" + chemeffectreport(user) + typereport(user) else return ..() +/obj/effect/blob/proc/chemeffectreport(mob/user) + if(overmind) + user << "Material: [overmind.blob_reagent_datum.name]." + user << "Material Effects: [overmind.blob_reagent_datum.analyzerdescdamage]" + user << "Material Properties: [overmind.blob_reagent_datum.analyzerdesceffect]
" + else + user << "No Material Detected!
" + +/obj/effect/blob/proc/typereport(mob/user) + user << "Blob Type: [uppertext(initial(name))]" + user << "Health: [health]/[maxhealth]" + user << "Effects: [scannerreport()]" + /obj/effect/blob/attacked_by(obj/item/I, mob/living/user) user.changeNext_move(CLICK_CD_MELEE) user.do_attack_animation(src) @@ -294,8 +302,13 @@ /obj/effect/blob/examine(mob/user) ..() - user << "It seems to be made of [get_chem_name()]." - return + var/datum/atom_hud/hud_to_check = huds[DATA_HUD_MEDICAL_ADVANCED] + if(user.research_scanner || (user in hud_to_check.hudusers)) + user << "Your HUD displays an extensive report...
" + chemeffectreport(user) + typereport(user) + else + user << "It seems to be made of [get_chem_name()]." /obj/effect/blob/proc/scannerreport() return "A generic blob. Looks like someone forgot to override this proc, adminhelp this." diff --git a/code/game/gamemodes/changeling/powers/augmented_eyesight.dm b/code/game/gamemodes/changeling/powers/augmented_eyesight.dm index facf2bb191a..e69d48b60ce 100644 --- a/code/game/gamemodes/changeling/powers/augmented_eyesight.dm +++ b/code/game/gamemodes/changeling/powers/augmented_eyesight.dm @@ -12,26 +12,26 @@ /obj/effect/proc_holder/changeling/augmented_eyesight/sting_action(mob/living/carbon/human/user) if(!istype(user)) return - if(user.getorgan(/obj/item/organ/internal/cyberimp/eyes/thermals/ling)) + if(user.getorgan(/obj/item/organ/cyberimp/eyes/thermals/ling)) user << "Our eyes are protected from flashes." - var/obj/item/organ/internal/cyberimp/eyes/O = new /obj/item/organ/internal/cyberimp/eyes/shield/ling() + var/obj/item/organ/cyberimp/eyes/O = new /obj/item/organ/cyberimp/eyes/shield/ling() O.Insert(user) else - var/obj/item/organ/internal/cyberimp/eyes/O = new /obj/item/organ/internal/cyberimp/eyes/thermals/ling() + var/obj/item/organ/cyberimp/eyes/O = new /obj/item/organ/cyberimp/eyes/thermals/ling() O.Insert(user) return 1 /obj/effect/proc_holder/changeling/augmented_eyesight/on_refund(mob/user) - var/obj/item/organ/internal/cyberimp/eyes/O = user.getorganslot("eye_ling") + var/obj/item/organ/cyberimp/eyes/O = user.getorganslot("eye_ling") if(O) O.Remove(user) qdel(O) -/obj/item/organ/internal/cyberimp/eyes/shield/ling +/obj/item/organ/cyberimp/eyes/shield/ling name = "protective membranes" desc = "These variable transparency organic membranes will protect you from welders and flashes and heal your eye damage." icon_state = "ling_eyeshield" @@ -41,18 +41,18 @@ slot = "eye_ling" status = ORGAN_ORGANIC -/obj/item/organ/internal/cyberimp/eyes/shield/ling/on_life() +/obj/item/organ/cyberimp/eyes/shield/ling/on_life() ..() if(owner.eye_blind>1 || (owner.eye_blind && owner.stat !=UNCONSCIOUS) || owner.eye_damage || owner.eye_blurry || (owner.disabilities & NEARSIGHT)) owner.reagents.add_reagent("oculine", 1) -/obj/item/organ/internal/cyberimp/eyes/shield/ling/prepare_eat() +/obj/item/organ/cyberimp/eyes/shield/ling/prepare_eat() var/obj/S = ..() S.reagents.add_reagent("oculine", 15) return S -/obj/item/organ/internal/cyberimp/eyes/thermals/ling +/obj/item/organ/cyberimp/eyes/thermals/ling name = "heat receptors" desc = "These heat receptors dramatically increases eyes light sensing ability." icon_state = "ling_thermal" @@ -63,16 +63,16 @@ status = ORGAN_ORGANIC aug_message = "You feel a minute twitch in our eyes, and darkness creeps away." -/obj/item/organ/internal/cyberimp/eyes/thermals/ling/emp_act(severity) +/obj/item/organ/cyberimp/eyes/thermals/ling/emp_act(severity) return -/obj/item/organ/internal/cyberimp/eyes/thermals/ling/Insert(mob/living/carbon/M, special = 0) +/obj/item/organ/cyberimp/eyes/thermals/ling/Insert(mob/living/carbon/M, special = 0) ..() if(ishuman(owner)) var/mob/living/carbon/human/H = owner H.weakeyes = 1 -/obj/item/organ/internal/cyberimp/eyes/thermals/ling/Remove(mob/living/carbon/M, special = 0) +/obj/item/organ/cyberimp/eyes/thermals/ling/Remove(mob/living/carbon/M, special = 0) if(ishuman(owner)) var/mob/living/carbon/human/H = owner H.weakeyes = 0 diff --git a/code/game/gamemodes/changeling/powers/fleshmend.dm b/code/game/gamemodes/changeling/powers/fleshmend.dm index 2b07ab71265..e4c68a8537c 100644 --- a/code/game/gamemodes/changeling/powers/fleshmend.dm +++ b/code/game/gamemodes/changeling/powers/fleshmend.dm @@ -6,6 +6,9 @@ dna_cost = 2 req_stat = UNCONSCIOUS var/recent_uses = 1 //The factor of which the healing should be divided by + var/healing_ticks = 10 + // The ideal total healing amount, divided by healing_ticks to get heal/tick + var/total_healing = 100 /obj/effect/proc_holder/changeling/fleshmend/New() ..() @@ -17,7 +20,7 @@ /obj/effect/proc_holder/changeling/fleshmend/process() if(recent_uses > 1) - recent_uses-- + recent_uses = max(1, recent_uses - (1 / healing_ticks)) //Starts healing you every second for 10 seconds. Can be used whilst unconscious. /obj/effect/proc_holder/changeling/fleshmend/sting_action(mob/living/user) @@ -30,12 +33,20 @@ var/mob/living/carbon/human/H = user H.restore_blood() H.remove_all_embedded_objects() + if(H.get_missing_limbs()) + playsound(user, 'sound/magic/Demon_consume.ogg', 50, 1) + H.visible_message("[user]'s missing limbs reform, making a loud, grotesque sound!", "Your limbs regrow, making a loud, crunchy sound and giving you great pain!", "You hear organic matter ripping and tearing!") + H.emote("scream") + H.regenerate_limbs(1) - for(var/i = 0, i < 10, i++) //The healing itself - doesn't heal toxin damage (that's anatomic panacea) and effectiveness decreases with each use in a short timespan + // The healing itself - doesn't heal toxin damage (that's anatomic panacea) and + // effectiveness decreases with each use in a short timespan + for(var/i in 1 to healing_ticks) if(user) - user.adjustBruteLoss(-10 / recent_uses, 0) - user.adjustOxyLoss(-10 / recent_uses, 0) - user.adjustFireLoss(-10 / recent_uses, 0) + var/healpertick = -(total_healing / healing_ticks) + user.adjustBruteLoss(healpertick / recent_uses, 0) + user.adjustOxyLoss(healpertick / recent_uses, 0) + user.adjustFireLoss(healpertick / recent_uses, 0) user.updatehealth() sleep(10) diff --git a/code/game/gamemodes/changeling/powers/headcrab.dm b/code/game/gamemodes/changeling/powers/headcrab.dm index c93fcb06c26..78a0e5f9fe3 100644 --- a/code/game/gamemodes/changeling/powers/headcrab.dm +++ b/code/game/gamemodes/changeling/powers/headcrab.dm @@ -10,7 +10,7 @@ var/datum/mind/M = user.mind var/list/organs = user.getorganszone("head", 1) - for(var/obj/item/organ/internal/I in organs) + for(var/obj/item/organ/I in organs) I.Remove(user, 1) explosion(get_turf(user),0,0,2,0,silent=1) @@ -26,7 +26,7 @@ var/turf = get_turf(user) spawn(5) // So it's not killed in explosion var/mob/living/simple_animal/hostile/headcrab/crab = new(turf) - for(var/obj/item/organ/internal/I in organs) + for(var/obj/item/organ/I in organs) I.loc = crab crab.origin = M if(crab.origin) diff --git a/code/game/gamemodes/changeling/powers/mutations.dm b/code/game/gamemodes/changeling/powers/mutations.dm index fddcbfa6d66..1dc79ffc084 100644 --- a/code/game/gamemodes/changeling/powers/mutations.dm +++ b/code/game/gamemodes/changeling/powers/mutations.dm @@ -38,10 +38,18 @@ user.update_inv_l_hand() return 1 -/obj/effect/proc_holder/changeling/weapon/sting_action(mob/user) +/obj/effect/proc_holder/changeling/weapon/sting_action(mob/living/user) if(!user.drop_item()) user << "The [user.get_active_hand()] is stuck to your hand, you cannot grow a [weapon_name_simple] over it!" return + var/limb_regen = 0 + if(user.hand) //we regen the arm before changing it into the weapon + limb_regen = user.regenerate_limb("l_arm", 1) + else + limb_regen = user.regenerate_limb("r_arm", 1) + if(limb_regen) + user.visible_message("[user]'s missing arm reforms, making a loud, grotesque sound!", "Your arm regrows, making a loud, crunchy sound and giving you great pain!", "You hear organic matter ripping and tearing!") + user.emote("scream") var/obj/item/W = new weapon_type(user) user.put_in_hands(W) playsound(user, 'sound/effects/blobattack.ogg', 30, 1) diff --git a/code/game/gamemodes/changeling/powers/panacea.dm b/code/game/gamemodes/changeling/powers/panacea.dm index e72decb7b34..d4c60625f27 100644 --- a/code/game/gamemodes/changeling/powers/panacea.dm +++ b/code/game/gamemodes/changeling/powers/panacea.dm @@ -10,7 +10,7 @@ /obj/effect/proc_holder/changeling/panacea/sting_action(mob/user) user << "We begin cleansing impurities from our form." - var/obj/item/organ/internal/body_egg/egg = user.getorgan(/obj/item/organ/internal/body_egg) + var/obj/item/organ/body_egg/egg = user.getorgan(/obj/item/organ/body_egg) if(egg) egg.Remove(user) if(iscarbon(user)) @@ -19,11 +19,11 @@ egg.loc = get_turf(user) user.reagents.add_reagent("mutadone", 10) - user.reagents.add_reagent("potass_iodide", 10) - user.reagents.add_reagent("charcoal", 20) + user.reagents.add_reagent("pen_acid", 20) user.reagents.add_reagent("antihol", 10) + user.reagents.add_reagent("mannitol", 25) for(var/datum/disease/D in user.viruses) D.cure() feedback_add_details("changeling_powers","AP") - return 1 \ No newline at end of file + return 1 diff --git a/code/game/gamemodes/cult/cult.dm b/code/game/gamemodes/cult/cult.dm index 6b619838ded..dc706d3934f 100644 --- a/code/game/gamemodes/cult/cult.dm +++ b/code/game/gamemodes/cult/cult.dm @@ -15,51 +15,23 @@ return 0 /proc/is_convertable_to_cult(datum/mind/mind) - if(!istype(mind)) return 0 - if(istype(mind.current, /mob/living/carbon/human) && (mind.assigned_role in list("Captain", "Chaplain"))) return 0 + if(!istype(mind)) + return 0 + if(istype(mind.current, /mob/living/carbon/human) && (mind.assigned_role in list("Captain", "Chaplain"))) + return 0 if(isloyal(mind.current)) return 0 if (ticker.mode.name == "cult") //redundant? if(is_sacrifice_target(mind)) return 0 return 1 -/proc/cultist_commune(mob/living/user, clear = 0, say = 0, message) - if(!message) - return - if(say) - user.say("O bidai nabora se[pick("'","`")]sma!") - else - user.whisper("O bidai nabora se[pick("'","`")]sma!") - sleep(10) - if(!user) - return - if(say) - user.say(message) - else - user.whisper(message) - var/my_message = "Error, message null. You should probably report this." - for(var/mob/M in mob_list) - if(iscultist(M) || (M in dead_mob_list)) - if(clear || !ishuman(user)) - my_message = "[(ishuman(user) ? "Acolyte" : "Construct")] [user]: [message]" - else //Emergency comms - my_message = "Acolyte ???: [message]" - if(M in dead_mob_list) - M << "(F) [my_message]" - else - M << my_message - - log_say("[user.real_name]/[user.key] : [message]") - - - /datum/game_mode/cult name = "cult" config_tag = "cult" antag_flag = ROLE_CULTIST restricted_jobs = list("Chaplain","AI", "Cyborg", "Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel") protected_jobs = list() - required_players = 30 + required_players = 24 required_enemies = 4 recommended_enemies = 4 enemy_minimum_age = 14 @@ -71,11 +43,12 @@ var/acolytes_survived = 0 var/datum/mind/sacrifice_target = null//The target to be sacrificed + var/list/cultists_to_cult = list() //the cultists we'll convert /datum/game_mode/cult/announce() world << "The current game mode is - Cult!" - world << "Some crewmembers are attempting to start a cult!
\nCultists - complete your objectives at all costs. Convert crewmembers to your cause by using the convert rune, or sacrifice them and turn them into constructs. Remember - there is no you, there is only the cult.
\nPersonnel - Do not let the cult succeed in its mission. Forced consumption of holy water will convert a cultist back to a Nanotrasen-sanctioned faith.
" + world << "Some crewmembers are attempting to start a cult!
\nCultists - sacrifice your target and summon Nar-Sie at all costs. Convert crewmembers to your cause by using the convert rune, or sacrifice them and turn them into constructs. Remember - there is no you, there is only the cult.
\nPersonnel - Do not let the cult succeed in its mission. Forced consumption of holy water will convert a cultist back to a Nanotrasen-sanctioned faith.
" /datum/game_mode/cult/pre_setup() @@ -97,12 +70,12 @@ break var/datum/mind/cultist = pick(antag_candidates) antag_candidates -= cultist - cult += cultist + cultists_to_cult += cultist cultist.special_role = "Cultist" cultist.restricted_roles = restricted_jobs log_game("[cultist.key] (ckey) has been selected as a cultist") - return (cult.len>=required_enemies) + return (cultists_to_cult.len>=required_enemies) /datum/game_mode/cult/proc/memorize_cult_objectives(datum/mind/cult_mind) @@ -113,21 +86,22 @@ explanation = "Our knowledge must live on. Make sure at least [acolytes_needed] acolytes escape on the shuttle to spread their work on an another station." if("sacrifice") if(sacrifice_target) - explanation = "Sacrifice [sacrifice_target.name], the [sacrifice_target.assigned_role]. You will need the Sacrifice rune and three acolytes to do so." + explanation = "Sacrifice [sacrifice_target.name], the [sacrifice_target.assigned_role] via invoking a Sacrifice rune with them on it and three acolytes around it." else explanation = "Free objective." if("eldergod") - explanation = "Summon Nar-Sie via the rune 'Call Forth The Geometer'. It will only work if nine acolytes stand on and around it." + explanation = "Summon Nar-Sie by invoking the rune 'Summon Nar-Sie' with nine acolytes around and on it. You must do this after sacrificing your target." cult_mind.current << "Objective #[obj_count]: [explanation]" cult_mind.memory += "Objective #[obj_count]: [explanation]
" + /datum/game_mode/cult/post_setup() - modePlayer += cult + modePlayer += cultists_to_cult if("sacrifice" in cult_objectives) var/list/possible_targets = get_unconvertables() if(!possible_targets.len) message_admins("Cult Sacrifice: Could not find unconvertable target, checking for convertable target.") for(var/mob/living/carbon/human/player in player_list) - if(player.mind && !(player.mind in cult)) + if(player.mind && !(player.mind in cultists_to_cult)) possible_targets += player.mind if(possible_targets.len > 0) sacrifice_target = pick(possible_targets) @@ -135,16 +109,16 @@ message_admins("Cult Sacrifice: ERROR - Null target chosen!") else message_admins("Cult Sacrifice: Could not find unconvertable or convertable target. WELP!") - for(var/datum/mind/cult_mind in cult) + for(var/datum/mind/cult_mind in cultists_to_cult) equip_cultist(cult_mind.current) update_cult_icons_added(cult_mind) cult_mind.current << "You are a member of the cult!" - memorize_cult_objectives(cult_mind) + add_cultist(cult_mind, 0) ..() + /datum/game_mode/proc/equip_cultist(mob/living/carbon/human/mob,tome = 0) if(!istype(mob)) return - mob.cult_add_comm() if (mob.mind) if (mob.mind.assigned_role == "Clown") mob << "Your training has allowed you to overcome your clownish nature, allowing you to wield weapons without harming yourself." @@ -180,14 +154,17 @@ B.show_to(mob) return 1 -/datum/game_mode/proc/add_cultist(datum/mind/cult_mind) //BASE +/datum/game_mode/proc/add_cultist(datum/mind/cult_mind, stun) //BASE if (!istype(cult_mind)) return 0 if(!(cult_mind in cult) && is_convertable_to_cult(cult_mind)) - cult_mind.current.Paralyse(5) + if(stun) + cult_mind.current.Paralyse(5) cult += cult_mind cult_mind.current.faction |= "cult" - cult_mind.current.cult_add_comm() + cult_mind.current.verbs += /mob/living/proc/cult_help + var/datum/action/innate/cultcomm/C = new() + C.Grant(cult_mind.current) update_cult_icons_added(cult_mind) cult_mind.current.attack_log += "\[[time_stamp()]\] Has been converted to the cult!" if(jobban_isbanned(cult_mind.current, ROLE_CULTIST)) @@ -195,18 +172,21 @@ return 1 -/datum/game_mode/cult/add_cultist(datum/mind/cult_mind) //INHERIT +/datum/game_mode/cult/add_cultist(datum/mind/cult_mind, stun) //INHERIT if (!..(cult_mind)) return memorize_cult_objectives(cult_mind) -/datum/game_mode/proc/remove_cultist(datum/mind/cult_mind, show_message = 1) +/datum/game_mode/proc/remove_cultist(datum/mind/cult_mind, show_message = 1, stun) if(cult_mind in cult) cult -= cult_mind cult_mind.current.faction -= "cult" - cult_mind.current.verbs -= /mob/living/proc/cult_innate_comm - cult_mind.current.Paralyse(5) + cult_mind.current.verbs -= /mob/living/proc/cult_help + for(var/datum/action/innate/cultcomm/C in cult_mind.current.actions) + qdel(C) + if(stun) + cult_mind.current.Paralyse(5) cult_mind.current << "An unfamiliar white light flashes through your mind, cleansing the taint of the Dark One and all your memories as its servant." cult_mind.memory = "" update_cult_icons_removed(cult_mind) diff --git a/code/game/gamemodes/cult/cult_comms.dm b/code/game/gamemodes/cult/cult_comms.dm new file mode 100644 index 00000000000..0af0525f908 --- /dev/null +++ b/code/game/gamemodes/cult/cult_comms.dm @@ -0,0 +1,75 @@ + +/datum/action/innate/cultcomm + name = "Communion" + button_icon_state = "cult_comms" + background_icon_state = "bg_demon" + check_flags = AB_CHECK_RESTRAINED|AB_CHECK_STUNNED|AB_CHECK_CONSCIOUS + +/datum/action/innate/cultcomm/IsAvailable() + if(!iscultist(owner)) + return 0 + return ..() + +/datum/action/innate/cultcomm/Activate() + var/input = stripped_input(usr, "Please choose a message to tell to the other acolytes.", "Voice of Blood", "") + if(!input || !IsAvailable()) + return + + cultist_commune(usr, input) + return + +/proc/cultist_commune(mob/living/user, message) + if(!message) + return + if(!ishuman(user)) + user.say("O bidai nabora se[pick("'","`")]sma!") + else + user.whisper("O bidai nabora se[pick("'","`")]sma!") + sleep(10) + if(!user) + return + if(!ishuman(user)) + user.say(message) + else + user.whisper(message) + var/my_message = "[(ishuman(user) ? "Acolyte" : "Construct")] [user]: [message]" + for(var/mob/M in mob_list) + if(iscultist(M)) + M << my_message + else if(M in dead_mob_list) + M << "(F) [my_message]" + + log_say("[user.real_name]/[user.key] : [message]") + +/mob/living/proc/cult_help() + set category = "Cultist" + set name = "How to Play Cult" + var/text = "" + text += "
Tenets of the Dark One



" + + text += "I. SECRECY
Your cult is a SECRET organization. Your success DEPENDS on keeping your cult's members and locations SECRET for as long as possible. This means that your tome should be hidden \ + in your bag and never brought out in public. You should never create runes where other crew might find them, and you should avoid using talismans or other cult magic with witnesses around.

" + + text += "II. TOME
You start with a unique talisman in your bag. This supply talisman can be used 3 times, and creates starter equipment for your cult. The most critical of the talisman's functions is \ + the power to create a tome. This tome is your most important item and summoning one (in secret) is your FIRST PRIORITY. It lets you talk to fellow cultists and create runes, which in turn is essential to growing the cult's power.

" + + text += "III. RUNES
Runes are powerful sources of cult magic. Your tome will allow you to draw runes with your blood. Those runes, when hit with an empty hand, will attempt to \ + trigger the rune's magic. Runes are essential for the cult to convert new members, create powerful minions, or call upon incredibly powerful magic. Some runes require more than one cultist to use.

" + + text += "IV. TALISMANS
Talismans are a mobile source of cult magic that are NECESSARY to achieve success as a cult. Your starting talisman can produce certain talismans, but you will need \ + to use the -create talisman- rune (with ordinary paper on top) to get more talismans. Talismans are EXTREMELY powerful, therefore creating more talismans in a HIDDEN location should be one of your TOP PRIORITIES.

" + + text += "V. GROW THE CULT
There are certain basic strategies that all cultists should master. STUN talismans are the foundation of a successful cult. If you intend to convert the stunned person \ + you should use cuffs or a talisman of shackling on them and remove their headset before they recover (it takes about 10 seconds to recover). If you intend to sacrifice the victim, striking them quickly and repeatedly with your tome \ + will knock them out before they can recover. Sacrificed victims will their soul behind in a shard, these shards can be used on construct shells to make powerful servants for the cult. Remember you need TWO cultists standing near a \ + conversion rune to convert someone. Your construct minions cannot trigger most runes, but they will count as cultists in helping you trigger more powerful runes like conversion or blood boil.

" + + text += "VI. VICTORY
You have two ultimate goals as a cultist, sacrifice your target, and summon Nar-Sie. Sacrificing the target involves killing that individual and then placing \ + their corpse on a sacrifice rune and triggering that rune with THREE cultists. Do NOT lose the target's corpse! Only once the target is sacrificed can Nar-Sie be summoned. Summoning Nar-Sie will take nearly one minute \ + just to draw the massive rune needed. Do not create the rune until your cult is ready, the crew will receive the NAME and LOCATION of anyone who attempts to create the Nar-Sie rune. Once the Nar-Sie rune is drawn \ + you must gathered 9 cultists (or constructs) over the rune and then click it to bring the Dark One into this world!

" + + var/datum/browser/popup = new(usr, "mind", "", 800, 600) + popup.set_content(text) + popup.open() + return 1 \ No newline at end of file diff --git a/code/game/gamemodes/cult/cult_items.dm b/code/game/gamemodes/cult/cult_items.dm index 8b8b70de1b9..680317bb768 100644 --- a/code/game/gamemodes/cult/cult_items.dm +++ b/code/game/gamemodes/cult/cult_items.dm @@ -12,7 +12,6 @@ attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "rended") - /obj/item/weapon/melee/cultblade/attack(mob/living/target, mob/living/carbon/human/user) if(!iscultist(user)) user.Weaken(5) @@ -49,6 +48,15 @@ var/mob/living/carbon/human/H = target H.drip(50) + +/obj/item/weapon/restraints/legcuffs/bola/cult + name = "nar'sian bola" + desc = "A strong bola, bound with dark magic. Throw it to trip and slow your victim." + icon_state = "bola_cult" + breakouttime = 45 + weaken = 1 + + /obj/item/clothing/head/culthood name = "ancient cultist hood" icon_state = "culthood" diff --git a/code/game/gamemodes/cult/ritual.dm b/code/game/gamemodes/cult/ritual.dm index 3002178f3f7..ecd8c75aa6e 100644 --- a/code/game/gamemodes/cult/ritual.dm +++ b/code/game/gamemodes/cult/ritual.dm @@ -1,84 +1,9 @@ /* -This file contains the arcane tome files as well as innate cultist emergency communications. +This file contains the arcane tome files. */ -/mob/proc/cult_add_comm() //why the fuck does this have its own proc? not removing it because it might be used somewhere but... - verbs += /mob/living/proc/cult_help - verbs += /mob/living/proc/cult_innate_comm - - -/mob/living/proc/cult_help() - set category = "Cultist" - set name = "How to Play Cult" - var/text = "" - text += "
Tenets of the Dark One



" - - text += "I. SECRECY
Your cult is a SECRET organization. Your success DEPENDS on keeping your cult's members and locations SECRET for as long as possible. This means that your tome should be hidden \ - in your bag and never brought out in public. You should never create runes where other crew might find them, and you should avoid using talismans or other cult magic with witnesses around.

" - - text += "II. TOME
You start with a unique talisman in your bag. This supply talisman can be used 3 times, and creates starter equipment for your cult. The most critical of the talisman's functions is \ - the power to create a tome. This tome is your most important item and summoning one (in secret) is your FIRST PRIORITY. It lets you talk to fellow cultists and create runes, which in turn is essential to growing the cult's power.

" - - text += "III. RUNES
Runes are powerful sources of cult magic. Your tome will allow you to draw runes with your blood. Those runes, when hit with an empty hand, will attempt to \ - trigger the rune's magic. Runes are essential for the cult to convert new members, create powerful minions, or call upon incredibly powerful magic. Some runes require more than one cultist to use.

" - - text += "IV. TALISMANS
Talismans are a mobile source of cult magic that are NECESSARY to achieve success as a cult. Your starting talisman can produce certain talismans, but you will need \ - to use the -create talisman- rune (with ordinary paper on top) to get more talismans. Talismans are EXTREMELY powerful, therefore creating more talismans in a HIDDEN location should be one of your TOP PRIORITIES.

" - - text += "V. GROW THE CULT
There are certain basic strategies that all cultists should master. STUN talismans are the foundation of a successful cult. If you intend to convert the stunned person \ - you should use cuffs or a talisman of shackling on them and remove their headset before they recover (it takes about 10 seconds to recover). If you intend to sacrifice the victim, striking them quickly and repeatedly with your tome \ - will knock them out before they can recover. Sacrificed victims will their soul behind in a shard, these shards can be used on construct shells to make powerful servants for the cult. Remember you need TWO cultists standing near a \ - conversion rune to convert someone. Your construct minions cannot trigger most runes, but they will count as cultists in helping you trigger more powerful runes like conversion or blood boil.

" - - text += "VI. VICTORY
You have two ultimate goals as a cultist, sacrifice your target, and summon Nar-Sie. Sacrificing the target involves killing that individual and then placing \ - their corpse on a sacrifice rune and triggering that rune with THREE cultists. Do NOT lose the target's corpse! Only once the target is sacrificed can Nar-Sie be summoned. Summoning Nar-Sie will take nearly one minute \ - just to draw the massive rune needed. Do not create the rune until your cult is ready, the crew will receive the NAME and LOCATION of anyone who attempts to create the Nar-Sie rune. Once the Nar-Sie rune is drawn \ - you must gathered 9 cultists (or constructs) over the rune and then click it to bring the Dark One into this world!

" - - var/datum/browser/popup = new(usr, "mind", "", 800, 600) - popup.set_content(text) - popup.open() - return 1 - -/mob/living/proc/cult_innate_comm() - set category = "Cultist" - set name = "Imperfect Communion" - - if(!iscultist(usr) || usr.incapacitated()) - return - if(!istype(usr, /mob/living/simple_animal)) - var/confirm_desperation = alert(usr, "This is a LAST RESORT; you should use a tome to communicate if possible. This ritual will inflict serious injury on you!", "Is this what you want?", "Yes", "No") - if(confirm_desperation == "No") - usr << "On second thought, maybe I should summon a tome." - return - var/input = stripped_input(usr, "Please choose a message to tell to the other acolytes.", "Voice of Blood", "") - if(!input) - return - - if(!iscultist(usr) || usr.incapacitated()) - return //we do this again because input() sleeps - - if(ishuman(usr) || ismonkey(usr)) //Damage only applies to humans and monkeys, to allow constructs to communicate - usr.visible_message("[usr] starts clawing at \his arms with \his fingernails!", "You begin slicing open your arms with your fingernails!") - apply_damage(10,BRUTE, "l_arm") - apply_damage(10,BRUTE, "r_arm") - sleep(50) - if(usr.incapacitated()) - return //Hard to drawn intrinsic symbols when you're bleeding out in your cell. - var/turf/location = loc - if(istype(location, /turf)) // tearing your arms apart is going to spill a bit of blood, in fact thats the idea - location.add_blood(usr) // TO-DO change this to a badly drawn rune - apply_damage(10,BRUTE, "l_arm") // does a metric fuck ton of damage because this meant to be an emergency method of communication. - apply_damage(10,BRUTE, "r_arm") - if(usr.incapacitated()) - return - usr.visible_message("[usr] paints strange symbols with their own blood.", "You paint a messy rune with your own blood.") - sleep(20) - - cultist_commune(usr, 0, 1, input) - return /obj/item/weapon/tome name = "arcane tome" @@ -90,16 +15,12 @@ This file contains the arcane tome files as well as innate cultist emergency com /obj/item/weapon/tome/examine(mob/user) ..() - if(iscultist(user)) - user << "The scriptures of the Geometer. Allows the scribing of runes and access to the knowledge archives of the cult of Nar-Sie." + if(iscultist(user) || user.stat == DEAD) + user << "The scriptures of the Geometer. Allows the scribing of runes and access to the knowledge archives of the cult of Nar-Sie." + user << "Striking another cultist with it will purge holy water from them." + user << "Striking a noncultist, however, will sear their flesh." /obj/item/weapon/tome/attack(mob/living/M, mob/living/user) - if(istype(M,/mob/dead/observer)) - M.invisibility = 0 - user.visible_message("[user] strikes the air with [src], and a ghost appears!", \ - "You drag the ghost to your plane of reality!") - add_logs(user, M, "smacked", src) - return if(!istype(M)) return if(!iscultist(user)) @@ -127,104 +48,100 @@ This file contains the arcane tome files as well as innate cultist emergency com open_tome(user) /obj/item/weapon/tome/proc/open_tome(mob/user) - var/choice = alert(user,"You open the tome...",,"Commune","Scribe Rune","More Information") + var/choice = alert(user,"You open the tome...",,"Scribe Rune","More Information","Cancel") switch(choice) if("More Information") read_tome(user) if("Scribe Rune") scribe_rune(user) - if("Commune") - var/input = stripped_input(usr, "Please enter a message to tell to the other acolytes.", "Voice of Blood", "") - if(!input) - return - cultist_commune(user, 1, 0, input) + if("Cancel") + return /obj/item/weapon/tome/proc/read_tome(mob/user) var/text = "" text += "
Archives of the Dark One



" text += "A rune's name and effects can be revealed by examining the rune.<

" - text += "Imbue Talisman
The Rune of Talisman Creation is one of the most important. It is the only way to create new talismans. A blank sheet of paper must be on top of the rune. After \ - invoking it and choosing which talisman you desire, the paper will be converted into a talisman.

" + text += "Create Talisman
This rune is one of the most important runes the cult has, being the only way to create new talismans. A blank sheet of paper must be on top of the rune. After \ + invoking it and choosing which talisman you desire, the paper will be converted, after some delay into a talisman.

" - text += "Teleport
The Rune of Teleportation is a unique rite in that it requires a keyword before the scribing can begin. When invoked, search for other Rites of Translocation. \ + text += "Teleport
This rune is unique in that it requires a keyword before the scribing can begin. When invoked, it will find any other Teleport runes; \ If any are found, the user can choose which rune to send to. Upon activation, the rune teleports everything above it to the selected rune.

" - text += "Convert
The Rune of Conversion is important to the success of the cult. It will allow you to convert normal crew members into cultists. \ - To do this, simply place the crew member upon the rune and invoke it. This rune requires two acolytes to use. If the target to be converted is loyalty-implanted or a certain assignment, they will \ - be unable to be converted. People the Geometer wishes sacrificed will also be ineligible for conversion, and anyone with a shielding presence like the null rod will not be converted.

" + text += "Convert
This rune is critical to the success of the cult. It will allow you to convert normal crew members into cultists. \ + To do this, simply place the crew member upon the rune and invoke it. This rune requires two invokers to use. If the target to be converted is loyalty-implanted or a certain assignment, they will \ + be unable to be converted. People the Geometer wishes sacrificed will also be ineligible for conversion, and anyone with a shielding presence like the null rod will not be converted.
\ + Successful conversions will produce a tome for the new cultist.

" - text += "Sacrifice
The Rune of Sacrifice is necessary to achieve your goals. Simply place any dead creature upon the rune and invoke it (this will not \ - target cultists!). If this creature has a mind, a soul shard will be created and the creature's soul transported to it. This rune is required if the cult's objectives include the sacrifice of a crew \ - member. Sacrificing the dead can be done alone, but sacrificing living crew or your cult's target will require 3 cultists. Soul shards used on construct shells will move that soul into a \ - powerful construct of your choice.

" + text += "Sacrifice
This rune is necessary to achieve your goals. Simply place any dead creature upon the rune and invoke it (this will not \ + target cultists!). If this creature has a mind, a soulstone will be created and the creature's soul transported to it. Sacrificing the dead can be done alone, but sacrificing living crew or your cult's target will require 3 cultists. \ + Soulstones used on construct shells will move that soul into a powerful construct of your choice.

" - text += "Raise Dead
The Rune of Resurrection is a delicate rite that requires two corpses. To perform the ritual, place the corpse you wish to revive onto \ + text += "Raise Dead
This rune requires two corpses. To perform the ritual, place the corpse you wish to revive onto \ the rune and the offering body adjacent to it. When the rune is invoked, the body to be sacrificed will turn to dust, the life force flowing into the revival target. Assuming the target is not moved \ within a few seconds, they will be brought back to life, healed of all ailments.

" - text += "Electromagnetic Disruption
Robotic lifeforms have time and time again been the downfall of fledgling cults. The Rite of Disruption may allow you to gain the upper \ + text += "Electromagnetic Disruption
Robotic lifeforms have time and time again been the downfall of fledgling cults. This rune may allow you to gain the upper \ hand against these pests. By using the rune, a large electromagnetic pulse will be emitted from the rune's location. The size of the EMP will grow significantly for each additional adjacent cultist when the \ rune is activated.

" - text += "Astral Communion
The Rune of Astral Communion is perhaps the most ingenious rune that is usable by a single person. Upon invoking the rune, the \ + text += "Astral Communion
This rune is perhaps the most ingenious rune that is usable by a single person. Upon invoking the rune, the \ user's spirit will be ripped from their body. In this state, the user's physical body will be locked in place to the rune itself - any attempts to move it will result in the rune pulling it back. \ The body will also take constant damage while in this form, and may even die. The user's spirit will contain their consciousness, and will allow them to freely wander the station as a ghost. This may \ also be used to commune with the dead.

" - text += "Form Barrier
While simple, the Barrier Rune serves an important purpose in defense and hindering passage. When invoked, the \ + text += "Form Barrier
While simple, this rune serves an important purpose in defense and hindering passage. When invoked, the \ rune will draw a small amount of life force from the user and make the space above the rune completely dense, rendering it impassable to all but the most complex means. The rune may be invoked again to \ undo this effect and allow passage again.

" - text += "Summon Cultist
The Rune of Summoning requires two acolytes to use. When invoked, it will allow the user to summon a single cultist to the rune from \ - any location. This will deal a moderate amount of damage to all invokers. Absolutely crucial for rescuing your brothers from security.

" + text += "Summon Cultist
This rune allows the cult to free other cultists with ease. When invoked, it will allow the user to summon a single cultist to the rune from \ + any location. It requires two invokers, and will damage each invoker slightly.

" - text += "Blood Boil
The Rune of Boiling Blood may be considered one of the most dangerous rites composed by the cult of Nar-Sie. When invoked, it will do a \ - massive amount of damage to all non-cultist viewers, but it will also emit an explosion upon invocation. It requires three invokers.

" + text += "Blood Boil
When invoked, this rune will do a massive amount of damage to all non-cultist viewers, but it will also emit a small explosion upon invocation. \ + It requires three invokers.

" - text += "Manifest Spirit
If you wish to bring a spirit back from the dead with a wish for vengeance and desire to serve, the Rite of Spectral \ - Manifestation can do just that. When invoked, any spirits above the rune will be brought to life as a human wearing nothing that seeks only to serve you and the Geometer. However, the spirit's link \ - to reality is fragile - you must remain on top of the rune, and you will slowly take damage. Upon stepping off the rune, the spirits will dissipate, dropping their items to the ground. You may manifest \ + text += "Manifest Spirit
This rune allows you to summon spirits as humanoid fighters. When invoked, a spirit above the rune will be brought to life as a human, wearing nothing, that seeks only to serve you and the Geometer. \ + However, the spirit's link to reality is fragile - you must remain on top of the rune, and you will slowly take damage. Upon stepping off the rune, all summoned spirits will dissipate, dropping their items to the ground. You may manifest \ multiple spirits with one rune, but you will rapidly take damage in doing so.

" - text += "Summon Nar-Sie
There is only one way to summon the avatar of Nar-Sie, and that is the Ritual of Dimensional Rending. This ritual, in \ - comparison to other runes, is very large, requiring a 3x3 space of empty tiles to create. To invoke the rune, nine cultists must stand on the rune, so that all of them are within its circle. Then, \ - simply invoke it. A brief tearing will be heard as the barrier between dimensions is torn open, and the avatar will come forth.


" + text += "Summon Nar-Sie
This rune is necessary to achieve your goals. On attempting to scribe it, it will produce shields around you and alert everyone you are attempting to scribe it; it takes a very long time to scribe, \ + and does massive damage to the one attempting to scribe it.
Invoking it requires 9 invokers and the sacrifice of a specific crewmember, and once invoked, will summon the Geometer, Nar-Sie herself. \ + This will complete your objectives.


" - text += "Talisman of Teleportation
The talisman form of the Rite of Translocation will transport the invoker to a randomly chosen rune of the same keyword, then \ - disappear.

" + text += "Talisman of Teleportation
The talisman form of the Teleport rune will transport the invoker to a selected Teleport rune once.

" - text += "Talisman of Construction
The Rune of Fabrication is the main way of creating construct shells. To use it, one must place fifteen sheets of metal on top of the rune \ - and invoke it. The sheets will them be twisted into a construct shell, ready to recieve a soul to occupy it.

" + text += "Talisman of Construction
This talisman is the main way of creating construct shells. To use it, one must strike 30 sheets of metal with the talisman. The sheets will then be twisted into a construct shell, ready to recieve a soul to occupy it.

" - text += "Talisman of Tome Summoning
This talisman functions nearly identically to the rune. The talisman will attempt to place the tome in your hand \ - instead of on the ground, though this is the only advantage it has over the rune. It can be used once, then disappears.

" + text += "Talisman of Tome Summoning
This talisman will produce a single tome at your feet.

" - text += "Talismans of Veiling and Disguising
These talismans will hide, reveal, or disguise (as crayon drawings) all nearby runes.

" + text += "Talisman of Veiling/Revealing
This talisman will hide runes on its first use, and on the second, will reveal runes.

" - text += "Talisman of Electromagnetic Pulse
This talisman will EMP the target and anything else nearby. It disappears after one use.

" + text += "Talisman of Disguising
This talisman will permanently disguise all nearby runes as crayon runes.

" - text += "Talisman of Stunning
Without this talisman, the cult would have no way of easily acquiring targets to convert. Commonly called \"stunpapers\", this \ - talisman functions differently from others. Rather than simply reading the words, the target must be attacked directly with the talisman. The talisman will then knock down the target for a long \ - duration in addition to inhibiting their speech. Robotic lifeforms will suffer the effects of a heavy electromagnetic pulse instead.

" + text += "Talisman of Electromagnetic Pulse
This talisman will EMP anything else nearby. It disappears after one use.

" + + text += "Talisman of Stunning
Attacking a target will knock them down for a long duration in addition to inhibiting their speech. \ + Robotic lifeforms will suffer the effects of a heavy electromagnetic pulse instead.

" text += "Talisman of Armaments
The Talisman of Arming will equip the user with armored robes, a backpack, an eldritch longsword, an empowered bola, and a pair of boots. Any items that cannot \ - be equipped will not be summoned.

" + be equipped will not be summoned. Attacking a fellow cultist with it will instead equip them.

" text += "Talisman of Horrors
The Talisman of Horror must be applied directly to the victim, it will shatter your victim's mind with visions of the endtimes that may incapitate them.

" text += "Talisman of Shackling
The Talisman of Shackling must be applied directly to the victim, it has 4 uses and cuffs victims with magic shackles that disappear when removed.

" - + text += "In addition to these runes, the cult has a small selection of equipment and constructs.

" text += "Equipment:

" - text += "Cult Blade
Cult blades are a sharp weapons that, notably, cannot be used by noncultists. These blades are produced by the Rite and Talisman of Arming.

" + text += "Cult Blade
Cult blades are sharp weapons that, notably, cannot be used by noncultists. These blades are produced by the Talisman of Arming.

" - text += "Cult Robes
Cult robes are heavily armored robes. These robes are produced by the Rite and Talisman of Arming.

" + text += "Cult Bola
Cult bolas are strong bolas, useful for snaring targets. These bolas are produced by the Talisman of Arming.

" + + text += "Cult Robes
Cult robes are heavily armored robes. These robes are produced by the Talisman of Arming.

" text += "Soulstone
A soulstone is a simple piece of magic, produced either via the starter talisman or by sacrificing humans. Using it on an unconscious or dead human, or on a Shade, will trap their soul in the stone, allowing its use in construct shells. \ -
The soul within can also be released as a Shade.

" +
The soul within can also be released as a Shade by using it in-hand.

" text += "Construct Shell
A construct shell is useless on its own, but placing a filled soulstone within it allows you to produce your choice of a Wraith, a Juggernaut, or an Artificer. \
Each construct has uses, detailed below in Constructs. Construct shells can be produced via the starter talisman or the Rite of Fabrication.

" @@ -240,14 +157,14 @@ This file contains the arcane tome files as well as innate cultist emergency com text += "Artificer
The Artificer is a weak and fragile construct, able to heal other constructs, produce more soulstones and construct shells, \ construct fortifying cult walls and flooring, and finally, it can release a few indiscriminate stunning missiles.

" - text += "Harvester
If you see one, know that you have done all you can and your life is void.

" - + text += "Harvester
If you see one, know that you have done all you can and your life is void.

" + var/datum/browser/popup = new(user, "tome", "", 800, 600) popup.set_content(text) popup.open() return 1 -/obj/item/weapon/tome/proc/scribe_rune(mob/user) +/obj/item/weapon/tome/proc/scribe_rune(mob/living/user) var/turf/Turf = get_turf(user) var/chosen_keyword var/obj/effect/rune/rune_to_scribe @@ -278,50 +195,45 @@ This file contains the arcane tome files as well as innate cultist emergency com break if(!rune_to_scribe) return - var/turf/Thenewturfyouwalkedto = get_turf(user) //we may have moved. adjust as needed... - if(locate(/obj/effect/rune) in Thenewturfyouwalkedto) + Turf = get_turf(user) //we may have moved. adjust as needed... + if(locate(/obj/effect/rune) in Turf) user << "There is already a rune here." return if(!Adjacent(user) || !src || qdeleted(src) || user.incapacitated()) return + if(ispath(rune_to_scribe, /obj/effect/rune/narsie)) + var/confirm_final = alert(usr, "This is the FINAL step to summon Nar-Sie, it is a long, painful ritual and the crew will be alerted to your presence", "Are you prepared for the final battle?", "My life for Nar-Sie!", "No") + if(confirm_final == "No") + usr << "On second thought, we should prepare further for the final battle..." + return + var/area/A = get_area(src) + var/locname = initial(A.name) + priority_announce("Figments from an eldritch god are being summoned by [user] into [locname] from an unknown dimension. Disrupt the ritual at all costs!","Central Command Higher Dimensionsal Affairs", 'sound/AI/spanomalies.ogg') + for(var/B in spiral_range_turfs(1, user, 1)) + var/turf/T = B + var/obj/machinery/shield/N = new(T) + N.name = "Rune-Scriber's Shield" + N.desc = "A potent shield summoned by cultists to protect them while they prepare the final ritual" + N.icon_state = "shield-red" + N.health = 60 + shields |= N user.visible_message("[user] cuts open their arm and begins writing in their own blood!", \ "You slice open your arm and begin drawing a sigil of the Geometer.") - if(iscarbon(user)) - var/mob/living/carbon/C = user - C.apply_damage(0.1, BRUTE, pick("l_arm", "r_arm")) - if("Summon Nar-Sie" == entered_rune_name) - var/confirm_final = alert(usr, "This is the FINAL step to summon Nar-Sie, it is a long, painful ritual and the crew will be alerted to your presence", "Are you prepared for the final battle?", "My life for Nar-Sie!", "No") - if(confirm_final == "No") - usr << "On second thought, we should prepare further for the final battle..." - return - C.apply_damage(40, BRUTE, pick("l_arm", "r_arm")) - var/area/A = get_area(src) - var/locname = initial(A.name) - priority_announce("Figments from an eldritch god are being summoned by [user] into [locname] from an unknown dimension. Disrupt the ritual at all costs!","Central Command Higher Dimensionsal Affairs", 'sound/AI/spanomalies.ogg') - for(var/turf/B in orange (1, user)) - var/obj/machinery/shield/N = new(B) - N.name = "Rune-Scriber's Shield" - N.desc = "A potent shield summoned by cultists to protect them while they prepare the final ritual" - N.icon_state = "shield-red" - N.health = 60 - shields |= N - if(!do_after(user, 400, target = get_turf(user))) - for(var/V in shields) - var/obj/machinery/shield/S = V - if(S && !qdeleted(S)) - qdel(S) - return - if(!do_after(user, 50, target = get_turf(user))) + user.apply_damage(initial(rune_to_scribe.scribe_damage), BRUTE, pick("l_arm", "r_arm")) + if(!do_after(user, initial(rune_to_scribe.scribe_delay), target = get_turf(user))) for(var/V in shields) var/obj/machinery/shield/S = V if(S && !qdeleted(S)) qdel(S) return + if(locate(/obj/effect/rune) in Turf) + user << "There is already a rune here." + return user.visible_message("[user] creates a strange circle in their own blood.", \ "You finish drawing the arcane markings of the Geometer.") for(var/V in shields) var/obj/machinery/shield/S = V if(S && !qdeleted(S)) qdel(S) - new rune_to_scribe(Thenewturfyouwalkedto, chosen_keyword) + new rune_to_scribe(Turf, chosen_keyword) user << "The [lowertext(initial(rune_to_scribe.cultist_name))] rune [initial(rune_to_scribe.cultist_desc)]" diff --git a/code/game/gamemodes/cult/runes.dm b/code/game/gamemodes/cult/runes.dm index da4d25943c1..4b75c8ce9d1 100644 --- a/code/game/gamemodes/cult/runes.dm +++ b/code/game/gamemodes/cult/runes.dm @@ -17,7 +17,7 @@ To draw a rune, use an arcane tome. name = "rune" var/cultist_name = "basic rune" desc = "An odd collection of symbols drawn in what seems to be blood." - var/cultist_desc = "A basic rune with no function." //This is shown to cultists who examine the rune in order to determine its true purpose. + var/cultist_desc = "a basic rune with no function." //This is shown to cultists who examine the rune in order to determine its true purpose. anchored = 1 icon = 'icons/obj/rune.dmi' icon_state = "1" @@ -30,14 +30,14 @@ To draw a rune, use an arcane tome. var/req_cultists = 1 //The amount of cultists required around the rune to invoke it. If only 1, any cultist can invoke it. var/rune_in_use = 0 // Used for some runes, this is for when you want a rune to not be usable when in use. - var/req_pylons = 0 - var/req_forges = 0 - var/req_archives = 0 - var/req_altars = 0 + var/scribe_delay = 50 //how long the rune takes to create + var/scribe_damage = 0.1 //how much damage you take doing it + + var/allow_excess_invokers = 0 //if we allow excess invokers when being invoked var/req_keyword = 0 //If the rune requires a keyword - go figure amirite var/keyword //The actual keyword for the rune - + /obj/effect/rune/New(loc, set_keyword) ..() if(set_keyword) @@ -47,14 +47,14 @@ To draw a rune, use an arcane tome. ..() if(iscultist(user) || user.stat == DEAD) //If they're a cultist or a ghost, tell them the effects user << "Name: [cultist_name]" - user << "Effects: [cultist_desc]" + user << "Effects: [capitalize(cultist_desc)]" user << "Required Acolytes: [req_cultists]" if(req_keyword && keyword) user << "Keyword: [keyword]" /obj/effect/rune/attackby(obj/I, mob/user, params) if(istype(I, /obj/item/weapon/tome) && iscultist(user)) - user << "You carefully erase [src]." + user << "You carefully erase the [lowertext(cultist_name)] rune." qdel(src) return else if(istype(I, /obj/item/weapon/nullrod)) @@ -68,14 +68,22 @@ To draw a rune, use an arcane tome. if(!iscultist(user)) user << "You aren't able to understand the words of [src]." return - if(can_invoke(user)) - invoke(user) - var/oldtransform = transform - animate(src, transform = matrix()*2, alpha = 0, time = 5) //fade out - animate(transform = oldtransform, alpha = 255, time = 0) + var/list/invokers = can_invoke(user) + if(invokers.len >= req_cultists) + invoke(invokers) else fail_invoke(user) +/obj/effect/rune/proc/talismanhide() //for talisman of revealing/hiding + visible_message("[src] fades away.") + invisibility = INVISIBILITY_OBSERVER + alpha = 100 //To help ghosts distinguish hidden runes + +/obj/effect/rune/proc/talismanreveal() //for talisman of revealing/hiding + invisibility = 0 + visible_message("[src] suddenly appears!") + alpha = initial(alpha) + /* There are a few different procs each rune runs through when a cultist activates it. @@ -88,64 +96,55 @@ structure_check() searches for nearby cultist structures required for the invoca /obj/effect/rune/proc/can_invoke(var/mob/living/user) //This proc determines if the rune can be invoked at the time. If there are multiple required cultists, it will find all nearby cultists. - if(!structure_check(req_pylons, req_forges, req_archives, req_altars)) - return 0 - if(!keyword && req_keyword) - return 0 - if(req_cultists <= 1) - if(invocation) - user.say(invocation) - return 1 - else - var/cultists_in_range = 0 + var/list/invokers = list() //people eligible to invoke the rune + var/list/chanters = list() //people who will actually chant the rune when passed to invoke() + chanters |= user + invokers |= user + if(req_cultists > 1 || allow_excess_invokers) for(var/mob/living/L in range(1, src)) if(iscultist(L)) - var/mob/living/carbon/human/H = L - if(!istype(H)) - if(istype(L, /mob/living/simple_animal/hostile/construct)) - if(invocation) - L.say(invocation) - cultists_in_range++ + if(L == user) continue - if(L.stat || (H.disabilities & MUTE) || H.silent) + if(ishuman(L)) + var/mob/living/carbon/human/H = L + if((H.disabilities & MUTE) || H.silent) + continue + if(L.stat) continue - if(invocation) - L.say(invocation) - cultists_in_range++ - if(cultists_in_range >= req_cultists) - return 1 - else - return 0 + invokers |= L + if(invokers.len >= req_cultists) + if(allow_excess_invokers) + chanters |= invokers + else + invokers -= user + shuffle(invokers) + for(var/i in 0 to req_cultists) + var/L = pick_n_take(invokers) + chanters |= L + return chanters -/obj/effect/rune/proc/invoke(var/mob/living/user) +/obj/effect/rune/proc/invoke(var/list/invokers) //This proc contains the effects of the rune as well as things that happen afterwards. If you want it to spawn an object and then delete itself, have both here. + if(invocation) + for(var/M in invokers) + var/mob/living/L = M + L.say(invocation) + var/oldtransform = transform + spawn(0) //animate is a delay, we want to avoid being delayed + animate(src, transform = matrix()*2, alpha = 0, time = 5) //fade out + animate(transform = oldtransform, alpha = 255, time = 0) /obj/effect/rune/proc/fail_invoke(var/mob/living/user) //This proc contains the effects of a rune if it is not invoked correctly, through either invalid wording or not enough cultists. By default, it's just a basic fizzle. visible_message("The markings pulse with a small flash of red light, then fall dark.") - -/obj/effect/rune/proc/structure_check(var/rpylons, var/rforges, var/rarchives, var/raltars) - var/pylons = 0 - var/forges = 0 - var/archives = 0 - var/altars = 0 - for(var/obj/structure/cult/pylon in orange(3,src)) - pylons++ - for(var/obj/structure/cult/forge in orange(3,src)) - forges++ - for(var/obj/structure/cult/tome in orange(3,src)) - archives++ - for(var/obj/structure/cult/talisman in orange(3,src)) - altars++ - if(pylons >= rpylons && forges >= rforges && archives >= rarchives && altars >= raltars) - return 1 - return 0 - + spawn(0) //animate is a delay, we want to avoid being delayed + animate(src, color = rgb(255, 0, 0), time = 0) + animate(src, color = initial(color), time = 5) //Malformed Rune: This forms if a rune is not drawn correctly. Invoking it does nothing but hurt the user. /obj/effect/rune/malformed cultist_name = "malformed rune" - cultist_desc = "A senseless rune written in gibberish. No good can come from invoking this." + cultist_desc = "a senseless rune written in gibberish. No good can come from invoking this." invocation = "Ra'sha yoka!" /obj/effect/rune/malformed/New() @@ -153,9 +152,12 @@ structure_check() searches for nearby cultist structures required for the invoca icon_state = "[rand(1,6)]" color = rgb(rand(0,255), rand(0,255), rand(0,255)) -/obj/effect/rune/malformed/invoke(mob/living/user) - user << "You feel your life force draining. The Geometer is displeased." - user.apply_damage(30, BRUTE) +/obj/effect/rune/malformed/invoke(var/list/invokers) + ..() + for(var/M in invokers) + var/mob/living/L = M + L << "You feel your life force draining. The Geometer is displeased." + L.apply_damage(30, BRUTE) qdel(src) /mob/proc/null_rod_check() //The null rod, if equipped, will protect the holder from the effects of most runes @@ -164,15 +166,16 @@ structure_check() searches for nearby cultist structures required for the invoca return N return 0 -//Rite of Binding: Turns a nearby rune and a paper on top of the rune to a talisman, if both are valid. +//Rite of Binding: A paper on top of the rune to a talisman. /obj/effect/rune/imbue cultist_name = "Create Talisman" - cultist_desc = "Transforms paper into powerful magic talismans." - invocation = null //no talisman made, no invocation. + cultist_desc = "transforms paper into powerful magic talismans." + invocation = "H'drak v'loso, mir'kanas verbot!" icon_state = "3" color = rgb(0, 0, 255) -/obj/effect/rune/imbue/invoke(mob/living/user) +/obj/effect/rune/imbue/invoke(var/list/invokers) + var/mob/living/user = invokers[1] //the first invoker is always the user var/turf/T = get_turf(src) var/list/papers_on_rune = list() var/entered_talisman_name @@ -184,12 +187,12 @@ structure_check() searches for nearby cultist structures required for the invoca if(!papers_on_rune.len) user << "There must be a blank paper on top of [src]!" fail_invoke() - log_game("Talisman Imbue rune failed - no blank papers on rune") + log_game("Talisman Creation rune failed - no blank papers on rune") return if(rune_in_use) user << "[src] can only support one ritual at a time!" fail_invoke() - log_game("Talisman Imbue rune failed - more than one user") + log_game("Talisman Creation rune failed - already in use") return var/obj/item/weapon/paper/paper_to_imbue = pick(papers_on_rune) for(var/I in subtypesof(/obj/item/weapon/paper/talisman) - /obj/item/weapon/paper/talisman/malformed - /obj/item/weapon/paper/talisman/supply) @@ -198,10 +201,10 @@ structure_check() searches for nearby cultist structures required for the invoca if(talisman_cult_name) possible_talismans[talisman_cult_name] = J //This is to allow the menu to let cultists select talismans by name entered_talisman_name = input(user, "Choose a talisman to imbue.", "Talisman Choices") as null|anything in possible_talismans - if(!Adjacent(user) || !src || qdeleted(src) || user.incapacitated()) - return talisman_type = possible_talismans[entered_talisman_name] - user.say("H'drak v'loso, mir'kanas verbot!") + if(!Adjacent(user) || !src || qdeleted(src) || user.incapacitated() || rune_in_use || !talisman_type) + return + ..() visible_message("Dark power begins to channel into the paper!.") rune_in_use = 1 if(!do_after(user, 100, target = get_turf(user))) @@ -215,7 +218,7 @@ structure_check() searches for nearby cultist structures required for the invoca var/list/teleport_runes = list() /obj/effect/rune/teleport cultist_name = "Teleport" - cultist_desc = "Warps everything above it to another chosen teleport rune." + cultist_desc = "warps everything above it to another chosen teleport rune." invocation = "Sas'so c'arta forbici!" icon_state = "2" color = "#551A8B" @@ -233,7 +236,8 @@ var/list/teleport_runes = list() teleport_runes -= src return ..() -/obj/effect/rune/teleport/invoke(mob/living/user) +/obj/effect/rune/teleport/invoke(var/list/invokers) + var/mob/living/user = invokers[1] //the first invoker is always the user var/list/potential_runes = list() var/list/teleportnames = list() var/list/duplicaterunecount = list() @@ -268,15 +272,22 @@ var/list/teleport_runes = list() return var/turf/T = get_turf(src) - var/turf/UT = get_turf(user) var/movedsomething = 0 + var/moveuserlater = 0 for(var/atom/movable/A in T) + if(A == user) + moveuserlater = 1 + movedsomething = 1 + continue if(!A.anchored) movedsomething = 1 A.forceMove(get_turf(actual_selected_rune)) if(movedsomething) + ..() visible_message("There is a sharp crack of inrushing air, and everything above the rune disappears!") - user << "You[user.loc == UT ? " send everything above the rune away":"r vision blurs, and you suddenly appear somewhere else"]." + user << "You[moveuserlater ? "r vision blurs, and you suddenly appear somewhere else":" send everything above the rune away"]." + if(moveuserlater) + user.forceMove(get_turf(actual_selected_rune)) else fail_invoke() @@ -284,13 +295,13 @@ var/list/teleport_runes = list() //Rite of Enlightenment: Converts a normal crewmember to the cult. Faster for every cultist nearby. /obj/effect/rune/convert cultist_name = "Convert" - cultist_desc = "Converts a normal crewmember on top of it to the cult. Does not work on loyalty-implanted crew." + cultist_desc = "converts a normal crewmember on top of it to the cult. Does not work on loyalty-implanted crew." invocation = "Mah'weyh pleggh at e'ntrath!" icon_state = "3" - color = rgb(255, 0, 0) + color = rgb(200, 0, 0) req_cultists = 2 -/obj/effect/rune/convert/invoke(mob/living/user) +/obj/effect/rune/convert/invoke(var/list/invokers) var/list/convertees = list() var/turf/T = get_turf(src) for(var/mob/living/M in T.contents) @@ -302,17 +313,17 @@ var/list/teleport_runes = list() return var/mob/living/new_cultist = pick(convertees) if(!is_convertable_to_cult(new_cultist.mind) || new_cultist.null_rod_check()) - user << "Something is shielding [new_cultist]'s mind!" + for(var/M in invokers) + M << "Something is shielding [new_cultist]'s mind!" + if(is_sacrifice_target(new_cultist.mind)) + M << "\"I desire this one for myself. SACRIFICE THEM!\"" fail_invoke() log_game("Convert rune failed - convertee could not be converted") - if(is_sacrifice_target(new_cultist.mind)) - for(var/mob/living/M in orange(1,src)) - if(iscultist(M)) - M << "\"I desire this one for myself. SACRIFICE THEM!\"" return + ..() new_cultist.visible_message("[new_cultist] writhes in pain as the markings below them glow a bloody red!", \ "AAAAAAAAAAAAAA-") - ticker.mode.add_cultist(new_cultist.mind) + ticker.mode.add_cultist(new_cultist.mind, 1) new /obj/item/weapon/tome(get_turf(src)) new_cultist.mind.special_role = "Cultist" new_cultist << "Your blood pulses. Your head throbs. The world goes red. All at once you are aware of a horrible, horrible, truth. The veil of reality has been ripped away \ @@ -323,8 +334,9 @@ var/list/teleport_runes = list() //Rite of Tribute: Sacrifices a crew member to Nar-Sie. Places them into a soul shard if they're in their body. /obj/effect/rune/sacrifice cultist_name = "Sacrifice" - cultist_desc = "Sacrifices a crew member to the Geometer. May place them into a soul shard if their spirit remains in their body." + cultist_desc = "sacrifices a crew member to the Geometer. May place them into a soul shard if their spirit remains in their body." icon_state = "3" + allow_excess_invokers = 1 invocation = "Barhah hra zar'garis!" color = rgb(255, 255, 255) rune_in_use = 0 @@ -333,13 +345,17 @@ var/list/teleport_runes = list() ..() icon_state = "[rand(1,6)]" -/obj/effect/rune/sacrifice/invoke(mob/living/user) +/obj/effect/rune/sacrifice/invoke(var/list/invokers) if(rune_in_use) return rune_in_use = 1 + var/mob/living/user = invokers[1] //the first invoker is always the user var/turf/T = get_turf(src) var/list/possible_targets = list() for(var/mob/living/M in T.contents) + if(M.mind) + if(M.mind in sacrificed) + continue if(!iscultist(M)) possible_targets.Add(M) var/mob/offering @@ -360,46 +376,41 @@ var/list/teleport_runes = list() rune_in_use = 0 return*/ if(((ishuman(offering) || isrobot(offering)) && offering.stat != DEAD) || is_sacrifice_target(offering.mind)) //Requires three people to sacrifice living targets - var/cultists_nearby = 1 - for(var/mob/living/M in range(1,src)) - if(iscultist(M) && M != user) - cultists_nearby++ - M.say(invocation) - if(cultists_nearby < 3) - user << "[offering] is too greatly linked to the world! You need three acolytes!" + if(invokers.len < 3) + for(var/M in invokers) + M << "[offering] is too greatly linked to the world! You need three acolytes!" fail_invoke() log_game("Sacrifice rune failed - not enough acolytes and target is living") rune_in_use = 0 return visible_message("[src] pulses blood red!") color = rgb(126, 23, 23) - spawn(5) - color = initial(color) - sac(offering) + ..() + sac(invokers, offering) + color = initial(color) -/obj/effect/rune/sacrifice/proc/sac(mob/living/T) +/obj/effect/rune/sacrifice/proc/sac(var/list/invokers, mob/living/T) var/sacrifice_fulfilled if(T) if(istype(T, /mob/living/simple_animal/pet/dog)) - for(var/mob/living/carbon/C in range(3,src)) - if(iscultist(C)) - C << "\"Even I have standards, such as they are!\"" - if(C.reagents) - C.reagents.add_reagent("hell_water", 2) + for(var/M in invokers) + var/mob/living/L = M + L << "\"Even I have standards, such as they are!\"" + if(L.reagents) + L.reagents.add_reagent("hell_water", 2) if(T.mind) sacrificed.Add(T.mind) if(is_sacrifice_target(T.mind)) sacrifice_fulfilled = 1 PoolOrNew(/obj/effect/overlay/temp/cult/sac, src.loc) - for(var/mob/living/M in range(3,src)) - if(iscultist(M)) - if(sacrifice_fulfilled) - M << "\"Yes! This is the one I desire! You have done well.\"" + for(var/M in invokers) + if(sacrifice_fulfilled) + M << "\"Yes! This is the one I desire! You have done well.\"" + else + if(ishuman(T) || isrobot(T)) + M << "\"I accept this sacrifice.\"" else - if(ishuman(T) || isrobot(T)) - M << "\"I accept this sacrifice.\"" - else - M << "\"I accept this meager sacrifice.\"" + M << "\"I accept this meager sacrifice.\"" if(T.mind) var/obj/item/device/soulstone/stone = new /obj/item/device/soulstone(get_turf(src)) stone.invisibility = INVISIBILITY_MAXIMUM //so it's not picked up during transfer_soul() @@ -421,60 +432,67 @@ var/list/teleport_runes = list() //Ritual of Dimensional Rending: Calls forth the avatar of Nar-Sie upon the station. /obj/effect/rune/narsie cultist_name = "Summon Nar-Sie" - cultist_desc = "Tears apart dimensional barriers, calling forth the avatar of the Geometer." - invocation = null + cultist_desc = "tears apart dimensional barriers, calling forth the Geometer. Requires 9 invokers." + invocation = "TOK-LYR RQA-NAP G'OLT-ULOFT!!" req_cultists = 9 icon = 'icons/effects/96x96.dmi' + color = rgb(125,23,23) icon_state = "rune_large" pixel_x = -32 //So the big ol' 96x96 sprite shows up right pixel_y = -32 + mouse_opacity = 1 //we're huge and easy to click + scribe_delay = 450 //how long the rune takes to create + scribe_damage = 40.1 //how much damage you take doing it var/used -/obj/effect/rune/narsie/invoke(mob/living/user) +/obj/effect/rune/narsie/talismanhide() //can't hide this, and you wouldn't want to + return + +/obj/effect/rune/narsie/invoke(var/list/invokers) if(used) return + var/mob/living/user = invokers[1] if(ticker.mode.name == "cult") var/datum/game_mode/cult/cult_mode = ticker.mode if(!("eldergod" in cult_mode.cult_objectives)) - message_admins("[usr.real_name]([user.ckey]) tried to summon Nar-Sie when the objective was wrong") - for(var/mob/living/M in range(1,src)) - if(iscultist(M)) - M << "\"YOUR SOUL BURNS WITH YOUR ARROGANCE!!!\"" - if(M.reagents) - M.reagents.add_reagent("hell_water", 10) - M.Weaken(7) - M.Stun(7) + message_admins("[user.real_name]([user.ckey]) tried to summon Nar-Sie when the objective was wrong") + for(var/M in invokers) + var/mob/living/L = M + L << "\"YOUR SOUL BURNS WITH YOUR ARROGANCE!!!\"" + if(L.reagents) + L.reagents.add_reagent("hell_water", 10) + L.Weaken(7) + L.Stun(7) fail_invoke() log_game("Summon Nar-Sie rune failed - improper objective") return else if(cult_mode.sacrifice_target && !(cult_mode.sacrifice_target in sacrificed)) - for(var/mob/living/M in orange(1,src)) - if(iscultist(M)) - M << "The sacrifice is not complete. The portal lacks the power to open!" + for(var/M in invokers) + M << "The sacrifice is not complete. The portal lacks the power to open!" fail_invoke() log_game("Summon Nar-Sie rune failed - sacrifice not complete") return if(!cult_mode.eldergod) - for(var/mob/living/M in orange(1,src)) - if(iscultist(M)) - M << "The avatar of Nar-Sie is already on this plane!" - log_game("Summon Nar-Sie rune failed - already summoned") - return + for(var/M in invokers) + M << "Nar-Sie is already on this plane!" + log_game("Summon Nar-Sie rune failed - already summoned") + return //BEGIN THE SUMMONING used = 1 - for(var/mob/living/M in range(1,src)) - if(iscultist(M)) - M.say("TOK-LYR RQA-NAP G'OLT-ULOFT!!") + color = rgb(255, 0, 0) + ..() world << 'sound/effects/dimensional_rend.ogg' world << "The veil... is... TORN!!!--" + var/turf/T = get_turf(src) sleep(40) - new /obj/singularity/narsie/large(get_turf(user)) //Causes Nar-Sie to spawn even if the rune has been removed + new /obj/singularity/narsie/large(T) //Causes Nar-Sie to spawn even if the rune has been removed cult_mode.eldergod = 0 else + for(var/M in invokers) + M << "Nar-Sie does not respond!" fail_invoke() log_game("Summon Nar-Sie rune failed - gametype is not cult") - return /obj/effect/rune/narsie/attackby(obj/I, mob/user, params) //Since the narsie rune takes a long time to make, add logging to removal. if((istype(I, /obj/item/weapon/tome) && iscultist(user))) @@ -494,46 +512,39 @@ var/list/teleport_runes = list() //Rite of Resurrection: Requires two corpses. Revives one and gibs the other. /obj/effect/rune/raise_dead cultist_name = "Raise Dead" - cultist_desc = "Requires two corpses. One on the rune and one adjacent to the rune. The one placed upon the rune is brought to life, the other is turned to ash." + cultist_desc = "requires two corpses, one on the rune and one adjacent to the rune. The one on the rune is brought to life, the other is turned to ash." invocation = null //Depends on the name of the user - see below icon_state = "1" - color = rgb(255, 0, 0) + color = rgb(200, 0, 0) -/obj/effect/rune/raise_dead/invoke(mob/living/user) +/obj/effect/rune/raise_dead/invoke(var/list/invokers) var/turf/T = get_turf(src) var/mob/living/mob_to_sacrifice var/mob/living/mob_to_revive var/list/potential_sacrifice_mobs = list() var/list/potential_revive_mobs = list() + var/mob/living/user = invokers[1] if(rune_in_use) return for(var/mob/living/M in orange(1,src)) - if(!(M in T.contents) && M.stat == DEAD) + if(M.stat == DEAD) potential_sacrifice_mobs.Add(M) if(!potential_sacrifice_mobs.len) user << "There are no eligible sacrifices nearby!" log_game("Raise Dead rune failed - no catalyst corpse") return mob_to_sacrifice = input(user, "Choose a corpse to sacrifice.", "Corpse to Sacrifice") as null|anything in potential_sacrifice_mobs - if(!Adjacent(user) || !src || qdeleted(src) || user.incapacitated() || !mob_to_revive || !mob_to_sacrifice) + if(!Adjacent(user) || !src || qdeleted(src) || user.incapacitated() || !mob_to_revive || !mob_to_sacrifice || rune_in_use) return for(var/mob/living/M in T.contents) if(M.stat == DEAD) potential_revive_mobs.Add(M) - if(rune_in_use) - return if(!potential_revive_mobs.len) user << "There is no eligible revival target on the rune!" log_game("Raise Dead rune failed - no corpse to revived") return mob_to_revive = input(user, "Choose a corpse to revive.", "Corpse to Revive") as null|anything in potential_revive_mobs - if(!Adjacent(user) || !src || qdeleted(src) || user.incapacitated()) - return - revive(mob_to_revive, mob_to_sacrifice, user, T) - - //Begin revival -/obj/effect/rune/raise_dead/proc/revive(mob/living/mob_to_revive, mob/living/mob_to_sacrifice, mob/living/user, turf/T) - if(rune_in_use) + if(!Adjacent(user) || !src || qdeleted(src) || user.incapacitated() || rune_in_use) return if(!in_range(mob_to_sacrifice,src)) user << "The sacrificial target has been moved!" @@ -555,6 +566,7 @@ var/list/teleport_runes = list() user.say("To life, to life, I bring them!") else user.say("Pasnar val'keriam usinar. Savrae ines amutan. Yam'toth remium il'tarat!") + ..() mob_to_sacrifice.visible_message("[mob_to_sacrifice]'s body rises into the air, connected to [mob_to_revive] by a glowing tendril!") mob_to_revive.Beam(mob_to_sacrifice,icon_state="sendbeam",icon='icons/effects/effects.dmi',time=20) sleep(20) @@ -574,7 +586,8 @@ var/list/teleport_runes = list() /obj/effect/rune/raise_dead/fail_invoke() - for(var/mob/living/M in orange(1,src)) + ..() + for(var/mob/living/M in range(1,src)) if(M.stat == DEAD) M.visible_message("[M] twitches.") @@ -582,46 +595,38 @@ var/list/teleport_runes = list() //Rite of Disruption: Emits an EMP blast. /obj/effect/rune/emp cultist_name = "Electromagnetic Disruption" - cultist_desc = "Emits a large electromagnetic pulse, hindering electronics and disabling silicons." + cultist_desc = "emits a large electromagnetic pulse, increasing in size for each cultist invoking it, hindering electronics and disabling silicons." invocation = "Ta'gh fara'qha fel d'amar det!" icon_state = "5" + allow_excess_invokers = 1 color = rgb(77, 148, 255) -/obj/effect/rune/emp/invoke(mob/living/user) +/obj/effect/rune/emp/invoke(var/list/invokers) var/turf/E = get_turf(src) - var/emp_strength = 0 - for(var/mob/living/L in range(1, src)) - if(iscultist(L)) - var/mob/living/carbon/human/H = L - if(!istype(H)) - if(istype(L, /mob/living/simple_animal/hostile/construct)) - if(invocation) - L.say(invocation) - emp_strength++ - continue - if(L.stat || (H.disabilities & MUTE) || H.silent) - continue - emp_strength++ + ..() visible_message("[src] glows blue for a moment before vanishing.") - for(var/mob/living/carbon/C in range(1,src)) - switch(emp_strength) - if(1 to 2) - C << "You feel a minute vibration pass through you..." - playsound(E, 'sound/items/Welder2.ogg', 25, 1) - if(3 to 6) - C << "Your hair stands on end as a shockwave eminates from the rune!" - playsound(E, 'sound/magic/Disable_Tech.ogg', 50, 1) - if(7 to INFINITY) - C << "You chant in unison and a colossal burst of energy knocks you backward!" - playsound(E, 'sound/magic/Disable_Tech.ogg', 100, 1) - C.Weaken(2) + switch(invokers.len) + if(1 to 2) + playsound(E, 'sound/items/Welder2.ogg', 25, 1) + for(var/M in invokers) + M << "You feel a minute vibration pass through you..." + if(3 to 6) + playsound(E, 'sound/magic/Disable_Tech.ogg', 50, 1) + for(var/M in invokers) + M << "Your hair stands on end as a shockwave eminates from the rune!" + if(7 to INFINITY) + playsound(E, 'sound/magic/Disable_Tech.ogg', 100, 1) + for(var/M in invokers) + var/mob/living/L = M + L << "You chant in unison and a colossal burst of energy knocks you backward!" + L.Weaken(2) qdel(src) //delete before pulsing because it's a delay reee - empulse(E, 9*emp_strength, 12*emp_strength) // Scales now, from a single room to most of the station depending on # of chanters + empulse(E, 9*invokers.len, 12*invokers.len) // Scales now, from a single room to most of the station depending on # of chanters //Rite of Astral Communion: Separates one's spirit from their body. They will take damage while it is active. /obj/effect/rune/astral cultist_name = "Astral Communion" - cultist_desc = "Severs the link between one's spirit and body. This effect is taxing and one's physical body will take damage while this is active." + cultist_desc = "severs the link between one's spirit and body. This effect is taxing and one's physical body will take damage while this is active." invocation = "Fwe'sh mah erl nyag r'ya!" icon_state = "6" color = rgb(126, 23, 23) @@ -633,18 +638,22 @@ var/list/teleport_runes = list() if(affecting) user << "A translucent field encases [user] above the rune!" -/obj/effect/rune/astral/invoke(mob/living/user) +/obj/effect/rune/astral/can_invoke(mob/living/user) if(rune_in_use) user << "[src] cannot support more than one body!" - fail_invoke() log_game("Astral Communion rune failed - more than one user") - return + return list() var/turf/T = get_turf(src) if(!user in T.contents) user << "You must be standing on top of [src]!" - fail_invoke() log_game("Astral Communion rune failed - user not standing on rune") - return + return list() + return ..() + +/obj/effect/rune/astral/invoke(var/list/invokers) + var/mob/living/user = invokers[1] + ..() + var/turf/T = get_turf(src) rune_in_use = 1 affecting = user user.color = "#7e1717" @@ -690,7 +699,7 @@ var/list/teleport_runes = list() //Rite of the Corporeal Shield: When invoked, becomes solid and cannot be passed. Invoke again to undo. /obj/effect/rune/wall cultist_name = "Form Barrier" - cultist_desc = "When invoked, makes an invisible wall to block passage. Can be invoked again to reverse this." + cultist_desc = "when invoked, makes an invisible wall to block passage. Can be invoked again to reverse this." invocation = "Khari'd! Eske'te tannin!" icon_state = "1" color = rgb(255, 0, 0) @@ -700,7 +709,9 @@ var/list/teleport_runes = list() if(density) user << "There is a barely perceptible shimmering of the air above [src]." -/obj/effect/rune/wall/invoke(mob/living/user) +/obj/effect/rune/wall/invoke(var/list/invokers) + var/mob/living/user = invokers[1] + ..() density = !density user.visible_message("[user] places their hands on [src], and [density ? "the air above it begins to shimmer" : "the shimmer above it fades"].", \ "You channel your life energy into [src], [density ? "preventing" : "allowing"] passage above it.") @@ -712,17 +723,20 @@ var/list/teleport_runes = list() //Rite of Joined Souls: Summons a single cultist. /obj/effect/rune/summon cultist_name = "Summon Cultist" - cultist_desc = "Summons a single cultist to the rune." + cultist_desc = "summons a single cultist to the rune. Requires 2 invokers." invocation = "N'ath reth sh'yro eth d'rekkathnor!" req_cultists = 2 + allow_excess_invokers = 1 icon_state = "5" color = rgb(0, 255, 0) -/obj/effect/rune/summon/invoke(mob/living/user) +/obj/effect/rune/summon/invoke(var/list/invokers) + var/mob/living/user = invokers[1] var/list/cultists = list() for(var/datum/mind/M in ticker.mode.cult) - cultists.Add(M.current) - var/mob/living/cultist_to_summon = input("Who do you wish to call to [src]?", "Followers of the Geometer") as null|anything in (cultists - user) + if(!(M.current in invokers)) + cultists |= M.current + var/mob/living/cultist_to_summon = input(user, "Who do you wish to call to [src]?", "Followers of the Geometer") as null|anything in cultists if(!Adjacent(user) || !src || qdeleted(src) || user.incapacitated()) return if(!cultist_to_summon) @@ -740,10 +754,9 @@ var/list/teleport_runes = list() fail_invoke() log_game("Summon Cultist rune failed - target in away mission") return - if(cultist_to_summon.buckled) - cultist_to_summon.buckled.unbuckle_mob(cultist_to_summon,force=1) cultist_to_summon.visible_message("[cultist_to_summon] suddenly disappears in a flash of red light!", \ "Overwhelming vertigo consumes you as you are hurled through the air!") + ..() visible_message("A foggy shape materializes atop [src] and solidifes into [cultist_to_summon]!") user.apply_damage(10, BRUTE, "head") cultist_to_summon.forceMove(get_turf(src)) @@ -752,13 +765,14 @@ var/list/teleport_runes = list() //Rite of Boiling Blood: Deals extremely high amounts of damage to non-cultists nearby /obj/effect/rune/blood_boil cultist_name = "Boil Blood" - cultist_desc = "Boils the blood of non-believers who can see the rune, dealing extreme amounts of damage. Requires 3 chanters." + cultist_desc = "boils the blood of non-believers who can see the rune, dealing extreme amounts of damage. Requires 3 invokers." invocation = "Dedo ol'btoh!" icon_state = "4" - color = rgb(255, 0, 0) + color = rgb(200, 0, 0) req_cultists = 3 -/obj/effect/rune/blood_boil/invoke(mob/living/user) +/obj/effect/rune/blood_boil/invoke(var/list/invokers) + ..() visible_message("[src] briefly bubbles before exploding!") for(var/mob/living/carbon/C in viewers(src)) if(!iscultist(C)) @@ -769,10 +783,10 @@ var/list/teleport_runes = list() C << "Your blood boils in your veins!" C.take_overall_damage(45,45) C.Stun(7) - for(var/mob/living/carbon/M in range(1,src)) - if(iscultist(M)) - M.apply_damage(15, BRUTE, pick("l_arm", "r_arm")) - M << "[src] saps your strength!" + for(var/M in invokers) + var/mob/living/L = M + L.apply_damage(15, BRUTE, pick("l_arm", "r_arm")) + L << "[src] saps your strength!" explosion(get_turf(src), -1, 0, 1, 5) qdel(src) @@ -780,10 +794,10 @@ var/list/teleport_runes = list() //Rite of Spectral Manifestation: Summons a ghost on top of the rune as a cultist human with no items. User must stand on the rune at all times, and takes damage for each summoned ghost. /obj/effect/rune/manifest cultist_name = "Manifest Spirit" - cultist_desc = "Manifests a spirit as a servant of the Geometer. The invoker must not move from atop the rune, and will take damage for each summoned spirit." + cultist_desc = "manifests a spirit as a servant of the Geometer. The invoker must not move from atop the rune, and will take damage for each summoned spirit." invocation = "Gal'h'rfikk harfrandid mud'gib!" //how the fuck do you pronounce this icon_state = "6" - color = rgb(255, 0, 0) + color = rgb(200, 0, 0) /obj/effect/rune/manifest/New(loc) ..() @@ -794,7 +808,7 @@ var/list/teleport_runes = list() user << "You must be standing on [src]!" fail_invoke() log_game("Manifest rune failed - user not standing on rune") - return 0 + return list() var/list/ghosts_on_rune = list() for(var/mob/dead/observer/O in get_turf(src)) if(O.client && !jobban_isbanned(O, ROLE_CULTIST)) @@ -803,10 +817,11 @@ var/list/teleport_runes = list() user << "There are no spirits near [src]!" fail_invoke() log_game("Manifest rune failed - no nearby ghosts") - return 0 + return list() return ..() -/obj/effect/rune/manifest/invoke(mob/living/user) +/obj/effect/rune/manifest/invoke(var/list/invokers) + var/mob/living/user = invokers[1] var/list/ghosts_on_rune = list() for(var/mob/dead/observer/O in get_turf(src)) if(O.client && !jobban_isbanned(O, ROLE_CULTIST)) @@ -815,6 +830,7 @@ var/list/teleport_runes = list() var/mob/living/carbon/human/new_human = new(get_turf(src)) new_human.real_name = ghost_to_spawn.real_name new_human.alpha = 150 //Makes them translucent + ..() visible_message("A cloud of red mist forms above [src], and from within steps... a man.") user << "Your blood begins flowing into [src]. You must remain in place and conscious to maintain the forms of those summoned. This will hurt you slowly but surely..." var/obj/machinery/shield/N = new(get_turf(src)) @@ -824,14 +840,14 @@ var/list/teleport_runes = list() N.health = 20 N.mouse_opacity = 0 new_human.key = ghost_to_spawn.key - ticker.mode.add_cultist(new_human.mind) + ticker.mode.add_cultist(new_human.mind, 0) new_human << "You are a servant of the Geometer. You have been made semi-corporeal by the cult of Nar-Sie, and you are to serve them at all costs." while(user in get_turf(src)) if(user.stat) break - user.apply_damage(1, BRUTE) - sleep(30) + user.apply_damage(0.1, BRUTE) + sleep(3) qdel(N) if(new_human) @@ -840,41 +856,3 @@ var/list/teleport_runes = list() for(var/obj/I in new_human) new_human.unEquip(I) new_human.dust() -/* -//Rite of Dimensional Corruption: Stops time around the rune for all non-cultists. -/obj/effect/rune/timestop - cultist_name = "Time Stop" - cultist_desc = "Stops time around the rune for all non-cultists. Requires 3 chanters." - invocation = "T'ak ot'marzah oahr'du!" - icon_state = "2" - color = rgb(0, 0, 255) - req_cultists = 3 - -/obj/effect/rune/timestop/invoke(mob/living/user) - visible_message("[src] flares up for a moment, and then disappears into itself!") - new /obj/effect/timestop/cult(get_turf(src)) - for(var/mob/living/carbon/M in range(1,src)) - if(iscultist(M)) - M.apply_damage(20, BRUTE, "chest") - M << "[src] temporarily stops your heart from beating!" - qdel(src) - -/obj/effect/timestop/cult - name = "Dimensional Corruption" - desc = "Something not from this world has corrupted the spacetime continuum in this exact spot." - icon = 'icons/effects/96x96.dmi' - icon_state = "rune_large" - pixel_x = -32 - pixel_y = -32 - duration = 50 - alpha = 0 - color = rgb(255, 0, 0) - -/obj/effect/timestop/cult/timestop() - animate(src, alpha = 255, time = 5, loop = -1) - SpinAnimation(speed = 5) - for(var/mob/living/M in player_list) - if(iscultist(M) || M.null_rod_check()) - immune |= M - ..() -*/ diff --git a/code/game/gamemodes/cult/talisman.dm b/code/game/gamemodes/cult/talisman.dm index d2a3d80b61b..0125bec86da 100644 --- a/code/game/gamemodes/cult/talisman.dm +++ b/code/game/gamemodes/cult/talisman.dm @@ -55,13 +55,13 @@ var/dat = "There are [uses] bloody runes on the parchment.
" dat += "Please choose the chant to be imbued into the fabric of reality.
" dat += "
" - dat += "N'ath reth sh'yro eth d'raggathnor! - Allows you to summon an arcane tome.
" + dat += "N'ath reth sh'yro eth d'raggathnor! - Summons an arcane tome, used to scribe runes and communicate with other cultists.
" dat += "Sas'so c'arta forbici! - Allows you to move to a selected teleportation rune.
" dat += "Ta'gh fara'qha fel d'amar det! - Allows you to destroy technology in a short range.
" dat += "Fuu ma'jin! - Allows you to stun a person by attacking them with the talisman.
" - dat += "Kal'om neth! - Summons a soul stone, used to capure the spirits of dead or dying humans.
" - dat += "Daa'ig osk! - Summons a construct shell for use with captured souls. It is too large to carry on your person.
" dat += "Kla'atu barada nikt'o! - Two use talisman, first use makes all nearby runes invisible, second use reveals nearby hidden runes.
" + dat += "Kal'om neth! - Summons a soul stone, used to capure the spirits of dead or dying humans.
" + dat += "Daa'ig osk! - Summons a construct shell for use with soulstone-captured souls. It is too large to carry on your person.
" var/datum/browser/popup = new(user, "talisman", "", 400, 400) popup.set_content(dat) popup.open() @@ -176,16 +176,12 @@ invocation = "Nikt'o barada kla'atu!" revealing = TRUE for(var/obj/effect/rune/R in range(3,user)) - R.visible_message("[R] fades away.") - R.invisibility = INVISIBILITY_OBSERVER - R.alpha = 100 //To help ghosts distinguish hidden runes + R.talismanhide() else user.visible_message("A flash of light shines from [user]'s hand!", \ "You speak the words of the talisman, revealing nearby runes.") for(var/obj/effect/rune/R in range(3,user)) - R.invisibility = 0 - R.visible_message("[R] suddenly appears!") - R.alpha = initial(R.alpha) + R.talismanreveal() //Rite of False Truths: Same as rune /obj/item/weapon/paper/talisman/make_runes_fake @@ -201,6 +197,7 @@ for(var/obj/effect/rune/R in orange(6,user)) R.desc = "A rune drawn in crayon." + //Rite of Disruption: Weaker than rune /obj/item/weapon/paper/talisman/emp cultist_name = "Talisman of Electromagnetic Pulse" @@ -215,6 +212,7 @@ "You speak the words of the talisman, emitting an EMP blast.") empulse(src, 4, 8) + //Rite of Disorientation: Stuns and inhibit speech on a single target for quite some time /obj/item/weapon/paper/talisman/stun cultist_name = "Talisman of Stunning" @@ -259,6 +257,7 @@ return ..() + //Rite of Arming: Equips cultist armor on the user, where available /obj/item/weapon/paper/talisman/armor cultist_name = "Talisman of Arming" @@ -286,6 +285,7 @@ return ..() + //Talisman of Horrors: Breaks the mind of the victim with nightmarish hallucinations /obj/item/weapon/paper/talisman/horror cultist_name = "Talisman of Horrors" @@ -295,12 +295,13 @@ /obj/item/weapon/paper/talisman/horror/attack(mob/living/target, mob/living/user) if(iscultist(user)) - user.visible_message("You disturb [target] with visons of the end!") + user << "You disturb [target] with visons of the end!" if(iscarbon(target)) var/mob/living/carbon/H = target H.reagents.add_reagent("mindbreaker", 25) qdel(src) + //Talisman of Fabrication: Creates a construct shell out of 25 metal sheets. /obj/item/weapon/paper/talisman/construction cultist_name = "Talisman of Construction" @@ -319,7 +320,7 @@ if(iscultist(user)) user << "This talisman will only work on a stack of metal sheets!" log_game("Construct talisman failed - not a valid target") - + /obj/item/weapon/paper/talisman/construction/afterattack(obj/item/stack/sheet/metal/target, mob/user, proximity_flag, click_parameters) ..() if(proximity_flag && istype(target) && iscultist(user)) @@ -330,23 +331,7 @@ qdel(src) else user << "The talisman requires at least 25 sheets of metal!" - -/obj/item/weapon/restraints/handcuffs/energy/cult //For the talisman of shackling - name = "cult shackles" - desc = "shackles that bind the wrists with sinister magic." - trashtype = /obj/item/weapon/restraints/handcuffs/energy/used - origin_tech = "materials=2;magnets=5" -/obj/item/weapon/restraints/handcuffs/energy/cult/used - desc = "magical remnants" - -/obj/item/weapon/restraints/handcuffs/energy/cult/used/dropped(mob/user) - user.visible_message("Your [src] shatter in a discharge of dark magic!", \ - "[user]'s [src] shatters in a discharge of dark magic!") - var/datum/effect_system/spark_spread/S = new - S.set_up(4,0,user.loc) - S.start() - qdel(src) //Talisman of Shackling: Applies special cuffs directly from the talisman /obj/item/weapon/paper/talisman/shackle @@ -365,26 +350,21 @@ user << "There are indecipherable images scrawled on the paper in what looks to be... blood?" return 0 -/obj/item/weapon/paper/talisman/shackle/attack(mob/living/target, mob/living/user) - if(iscultist(user)) - if(isrobot(target)) - ..() - return - if(!isliving(target)) +/obj/item/weapon/paper/talisman/shackle/attack(mob/living/carbon/target, mob/living/user) + if(iscultist(user) && istype(target)) + if(target.stat == DEAD) user.visible_message("This talisman's magic does not affect the dead!") return - var/mob/living/L = target - if(ishuman(L)) - CuffAttack(L,user) - -/obj/item/weapon/paper/talisman/shackle/proc/CuffAttack(mob/living/L,mob/living/user) - if(!iscarbon(L)) + CuffAttack(target, user) return - var/mob/living/carbon/C = L + ..() + +/obj/item/weapon/paper/talisman/shackle/proc/CuffAttack(mob/living/carbon/C, mob/living/user) if(!C.handcuffed) + invoke(user, 1) playsound(loc, 'sound/weapons/cablecuff.ogg', 30, 1, -2) C.visible_message("[user] begins restraining [C] with dark magic!", \ - "[user] begins shaping an dark magic around your wrists!") + "[user] begins shaping a dark magic around your wrists!") if(do_mob(user, C, 30)) if(!C.handcuffed) C.handcuffed = new /obj/item/weapon/restraints/handcuffs/energy/cult/used(C) @@ -392,9 +372,24 @@ user << "You shackle [C]." add_logs(user, C, "handcuffed") uses-- + else + user << "[C] is already bound." else user << "You fail to shackle [C]." + else + user << "[C] is already bound." if(uses <= 0) user.drop_item() qdel(src) return + +/obj/item/weapon/restraints/handcuffs/energy/cult //For the talisman of shackling + name = "cult shackles" + desc = "Shackles that bind the wrists with sinister magic." + trashtype = /obj/item/weapon/restraints/handcuffs/energy/used + origin_tech = "materials=2;magnets=5" + +/obj/item/weapon/restraints/handcuffs/energy/cult/used/dropped(mob/user) + user.visible_message("[user]'s [src] shatter in a discharge of dark magic!", \ + "Your [src] shatters in a discharge of dark magic!") + qdel(src) diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm index d7c63098f28..b4cd86efb66 100644 --- a/code/game/gamemodes/game_mode.dm +++ b/code/game/gamemodes/game_mode.dm @@ -530,7 +530,7 @@ M.key = theghost.key /datum/game_mode/proc/remove_antag_for_borging(datum/mind/newborgie) - ticker.mode.remove_cultist(newborgie, 0) + ticker.mode.remove_cultist(newborgie, 0, 0) ticker.mode.remove_revolutionary(newborgie, 0) ticker.mode.remove_gangster(newborgie, 0, remove_bosses=1) ticker.mode.remove_hog_follower(newborgie, 0) diff --git a/code/game/gamemodes/gang/dominator.dm b/code/game/gamemodes/gang/dominator.dm index e2c6276dbb6..bc1236d7d0e 100644 --- a/code/game/gamemodes/gang/dominator.dm +++ b/code/game/gamemodes/gang/dominator.dm @@ -101,7 +101,7 @@ SSshuttle.emergency.timer = world.time priority_announce("Hostile enviroment resolved. You have 3 minutes to board the Emergency Shuttle.", null, 'sound/AI/shuttledock.ogg', "Priority") else - priority_announce("All hostile activity within station systems have ceased.","Network Alert") + priority_announce("All hostile activity within station systems has ceased.","Network Alert") if(get_security_level() == "delta") set_security_level("red") @@ -119,6 +119,7 @@ if(!(stat & BROKEN)) set_broken() poi_list.Remove(src) + gang = null qdel(spark_system) return ..() diff --git a/code/game/gamemodes/gang/gang.dm b/code/game/gamemodes/gang/gang.dm index 31c3205f476..b43ee71186c 100644 --- a/code/game/gamemodes/gang/gang.dm +++ b/code/game/gamemodes/gang/gang.dm @@ -183,6 +183,7 @@ var/list/gang_colors_pool = list("red","orange","yellow","green","blue","purple" gangster_mind.current << "You can identify your bosses by their red \[G\] icon." gangster_mind.current.attack_log += "\[[time_stamp()]\] Has been converted to the [G.name] Gang!" gangster_mind.special_role = "[G.name] Gangster" + gangster_mind.store_memory("You are a member of the [G.name] Gang!") G.add_gang_hud(gangster_mind) if(jobban_isbanned(gangster_mind.current, ROLE_GANG)) replace_jobbaned_player(gangster_mind.current, ROLE_GANG, ROLE_GANG) @@ -224,6 +225,7 @@ var/list/gang_colors_pool = list("red","orange","yellow","green","blue","purple" gangster_mind.current.Paralyse(5) gangster_mind.current.visible_message("[gangster_mind.current] looks like they've given up the life of crime!") gangster_mind.current << "You have been reformed! You are no longer a gangster!
You try as hard as you can, but you can't seem to recall any of the identities of your former gangsters...
" + gangster_mind.memory = "" gang.remove_gang_hud(gangster_mind) return 1 diff --git a/code/game/gamemodes/gang/gang_datum.dm b/code/game/gamemodes/gang/gang_datum.dm index d5d431073b9..df8d646f440 100644 --- a/code/game/gamemodes/gang/gang_datum.dm +++ b/code/game/gamemodes/gang/gang_datum.dm @@ -117,8 +117,7 @@ if(mob && mob.mind && mob.stat == CONSCIOUS) if(mob.mind.gang_datum == src) mob << "\icon[tool] [message]" - if(beep) - playsound(mob.loc, 'sound/machines/twobeep.ogg', 50, 1) + return //////////////////////////////////////////// INCOME diff --git a/code/game/gamemodes/gang/recaller.dm b/code/game/gamemodes/gang/recaller.dm index eec67985c08..de6176c3c7c 100644 --- a/code/game/gamemodes/gang/recaller.dm +++ b/code/game/gamemodes/gang/recaller.dm @@ -228,7 +228,7 @@ pointcost = 10 if("C4") if(gang.points >= 10) - item_type = /obj/item/weapon/c4 + item_type = /obj/item/weapon/grenade/plastic/c4 pointcost = 10 if("pen") if((gang.points >= 50) || free_pen) diff --git a/code/game/gamemodes/handofgod/_handofgod.dm b/code/game/gamemodes/handofgod/_handofgod.dm index d5375834943..afba1ce73cf 100644 --- a/code/game/gamemodes/handofgod/_handofgod.dm +++ b/code/game/gamemodes/handofgod/_handofgod.dm @@ -358,7 +358,7 @@ var/global/list/global_handofgod_structuretypes = list() text += "
Red follower count: [red_deity_followers.len]" text += "
Red followers: " for(var/datum/mind/player in red_deity_followers) - text += "[player.name] ([player.key])" + text += "[player.name] ([player.key]), " var/objectives = "" if(red_god.objectives.len) diff --git a/code/game/gamemodes/handofgod/actions.dm b/code/game/gamemodes/handofgod/actions.dm index 762a8b4d683..9f6b01f8dff 100644 --- a/code/game/gamemodes/handofgod/actions.dm +++ b/code/game/gamemodes/handofgod/actions.dm @@ -1,6 +1,4 @@ - - - +/* Prophet's innate godspeak */ /datum/action/innate/godspeak name = "Godspeak" button_icon_state = "godspeak" @@ -17,8 +15,12 @@ var/msg = input(owner,"Speak to your god","Godspeak","") as null|text if(!msg) return - god << "[owner]: [msg]" - owner << "You say: [msg]" + var/rendered = "Prophet [owner]: [msg]" + god << rendered + owner << rendered + for(var/mob/M in mob_list) + if(isobserver(M)) + M << "(F) [rendered]" /datum/action/innate/godspeak/Destroy() god = null diff --git a/code/game/gamemodes/handofgod/god.dm b/code/game/gamemodes/handofgod/god.dm index 7dcd5b5f933..39deb470840 100644 --- a/code/game/gamemodes/handofgod/god.dm +++ b/code/game/gamemodes/handofgod/god.dm @@ -31,9 +31,9 @@ update_icons() build_hog_construction_lists() - //Force nexuses after 2 minutes in hand of god mode + //Force nexuses after 15 minutes in hand of god mode if(ticker && ticker.mode && ticker.mode.name == "hand of god") - addtimer(src, "forceplacenexus", 1200, FALSE) + addtimer(src, "forceplacenexus", 9000, FALSE) //Rebuilds the list based on the gamemode's lists @@ -197,12 +197,13 @@ return msg = say_quote(msg, get_spans()) - var/rendered = "Divine Telepathy, [name] [msg]" + var/rendered = "Divine Telepathy, [name] [msg]
" for(var/mob/M in mob_list) - if(is_handofgod_myfollowers(M) || isobserver(M)) - M.show_message(rendered, 2) - src << rendered + if(is_handofgod_god(M) || is_handofgod_myfollowers(M)) + M << rendered + if(isobserver(M)) + M << "(F) [rendered]" /mob/camera/god/emote(act,m_type = 1 ,msg = null) diff --git a/code/game/gamemodes/handofgod/items.dm b/code/game/gamemodes/handofgod/items.dm index 9d63f86c773..f512c5c11cb 100644 --- a/code/game/gamemodes/handofgod/items.dm +++ b/code/game/gamemodes/handofgod/items.dm @@ -1,5 +1,3 @@ - - /obj/item/weapon/banner name = "banner" icon = 'icons/obj/items.dmi' diff --git a/code/game/gamemodes/handofgod/powers.dm b/code/game/gamemodes/handofgod/powers.dm index a783595352d..30b3365cfcd 100644 --- a/code/game/gamemodes/handofgod/powers.dm +++ b/code/game/gamemodes/handofgod/powers.dm @@ -1,4 +1,3 @@ - /mob/camera/god/proc/ability_cost(cost = 0,structures = 0, requires_conduit = 0, can_place_near_enemy_nexus = 0) if(faith < cost) src << "You lack the faith!" @@ -127,7 +126,7 @@ var/mob/living/carbon/human/H = choice.current var/popehat = null var/popestick = null - + var/success = "" switch(side) if("red") popehat = /obj/item/clothing/head/helmet/plate/crusader/prophet/red @@ -139,22 +138,28 @@ if(popehat) var/obj/item/clothing/head/helmet/plate/crusader/prophet/P = new popehat() - H.unEquip(H.head) - H << "A powerful hat has been bestowed upon your head, you will need to wear this to utilize your staff fully.." - H.equip_to_slot_or_del(P,slot_head) + if(H.equip_to_slot_if_possible(P,slot_in_backpack,0,1,1)) + success = "It is in your backpack." + else + H.unEquip(H.head) + H.equip_to_slot_or_del(P,slot_head) + success = "It is on your head." + + if(success) + H << "A powerful hat has been bestowed upon you, you will need to wear it to utilize your staff fully." + H << "[success]" if(popestick) var/obj/item/weapon/godstaff/G = new popestick() G.god = src - var/success = "" - if(!H.put_in_hands(G)) - if(!H.equip_to_slot_if_possible(G,slot_in_backpack,0,1,1)) + if(!H.equip_to_slot_if_possible(G,slot_in_backpack,0,1,1)) + if(!H.put_in_hands(G)) G.loc = get_turf(H) success = "It is on the floor..." else - success = "It is in your backpack..." + success = "It is in your hands..." else - success = "It is in your hands..." + success = "It is in your backpack..." if(success) H << "A powerful staff has been bestowed upon you, you can use this to convert the false god's structures!" diff --git a/code/game/gamemodes/miniantags/abduction/abduction_gear.dm b/code/game/gamemodes/miniantags/abduction/abduction_gear.dm index 6b9c1366ddf..914dfa1c9d0 100644 --- a/code/game/gamemodes/miniantags/abduction/abduction_gear.dm +++ b/code/game/gamemodes/miniantags/abduction/abduction_gear.dm @@ -482,18 +482,20 @@ Congratulations! You are now trained for xenobiology research!"} return var/mob/living/carbon/C = L if(!C.handcuffed) - playsound(loc, 'sound/weapons/cablecuff.ogg', 30, 1, -2) - C.visible_message("[user] begins restraining [C] with [src]!", \ - "[user] begins shaping an energy field around your hands!") - if(do_mob(user, C, 30)) - if(!C.handcuffed) - C.handcuffed = new /obj/item/weapon/restraints/handcuffs/energy/used(C) - C.update_handcuffed() - user << "You handcuff [C]." - add_logs(user, C, "handcuffed") + if(C.get_num_arms() >= 2) + playsound(loc, 'sound/weapons/cablecuff.ogg', 30, 1, -2) + C.visible_message("[user] begins restraining [C] with [src]!", \ + "[user] begins shaping an energy field around your hands!") + if(do_mob(user, C, 30) && C.get_num_arms() >= 2) + if(!C.handcuffed) + C.handcuffed = new /obj/item/weapon/restraints/handcuffs/energy/used(C) + C.update_handcuffed() + user << "You handcuff [C]." + add_logs(user, C, "handcuffed") + else + user << "You fail to handcuff [C]." else - user << "You fail to handcuff [C]." - return + user << "[C] doesn't have two hands..." /obj/item/weapon/abductor_baton/proc/ProbeAttack(mob/living/L,mob/living/user) L.visible_message("[user] probes [L] with [src]!", \ @@ -507,7 +509,7 @@ Congratulations! You are now trained for xenobiology research!"} species = "[H.dna.species.name]" if(L.mind && L.mind.changeling) species = "Changeling lifeform" - var/obj/item/organ/internal/gland/temp = locate() in H.internal_organs + var/obj/item/organ/gland/temp = locate() in H.internal_organs if(temp) helptext = "Experimental gland detected!" else diff --git a/code/game/gamemodes/miniantags/abduction/abduction_surgery.dm b/code/game/gamemodes/miniantags/abduction/abduction_surgery.dm index a97011d53db..30f7d7c10e7 100644 --- a/code/game/gamemodes/miniantags/abduction/abduction_surgery.dm +++ b/code/game/gamemodes/miniantags/abduction/abduction_surgery.dm @@ -19,8 +19,8 @@ name = "remove heart" accept_hand = 1 time = 32 - var/obj/item/organ/internal/IC = null - var/list/organ_types = list(/obj/item/organ/internal/heart) + var/obj/item/organ/IC = null + var/list/organ_types = list(/obj/item/organ/heart) /datum/surgery_step/extract_organ/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) for(var/obj/item/I in target.internal_organs) @@ -41,7 +41,7 @@ /datum/surgery_step/gland_insert name = "insert gland" - implements = list(/obj/item/organ/internal/gland = 100) + implements = list(/obj/item/organ/gland = 100) time = 32 /datum/surgery_step/gland_insert/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) @@ -50,6 +50,6 @@ /datum/surgery_step/gland_insert/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) user.visible_message("[user] inserts [tool] into [target].", "You insert [tool] into [target].") user.drop_item() - var/obj/item/organ/internal/gland/gland = tool + var/obj/item/organ/gland/gland = tool gland.Insert(target, 2) return 1 \ No newline at end of file diff --git a/code/game/gamemodes/miniantags/abduction/gland.dm b/code/game/gamemodes/miniantags/abduction/gland.dm index eab9171f6b7..537f29f3551 100644 --- a/code/game/gamemodes/miniantags/abduction/gland.dm +++ b/code/game/gamemodes/miniantags/abduction/gland.dm @@ -1,4 +1,4 @@ -/obj/item/organ/internal/gland +/obj/item/organ/gland name = "fleshy mass" desc = "A nausea-inducing hunk of twisting flesh and metal." icon = 'icons/obj/abductor.dmi' @@ -14,30 +14,30 @@ var/human_only = 0 var/active = 0 -/obj/item/organ/internal/gland/proc/ownerCheck() +/obj/item/organ/gland/proc/ownerCheck() if(ishuman(owner)) return 1 if(!human_only && iscarbon(owner)) return 1 return 0 -/obj/item/organ/internal/gland/proc/Start() +/obj/item/organ/gland/proc/Start() active = 1 next_activation = world.time + rand(cooldown_low,cooldown_high) -/obj/item/organ/internal/gland/Remove(var/mob/living/carbon/M, special = 0) +/obj/item/organ/gland/Remove(var/mob/living/carbon/M, special = 0) active = 0 if(initial(uses) == 1) uses = initial(uses) ..() -/obj/item/organ/internal/gland/Insert(var/mob/living/carbon/M, special = 0) +/obj/item/organ/gland/Insert(var/mob/living/carbon/M, special = 0) ..() if(special != 2 && uses) // Special 2 means abductor surgery Start() -/obj/item/organ/internal/gland/on_life() +/obj/item/organ/gland/on_life() if(!active) return if(!ownerCheck()) @@ -50,30 +50,30 @@ if(!uses) active = 0 -/obj/item/organ/internal/gland/proc/activate() +/obj/item/organ/gland/proc/activate() return -/obj/item/organ/internal/gland/heals +/obj/item/organ/gland/heals origin_tech = "materials=4;biotech=6;abductor=3" cooldown_low = 200 cooldown_high = 400 uses = -1 icon_state = "health" -/obj/item/organ/internal/gland/heals/activate() +/obj/item/organ/gland/heals/activate() owner << "You feel curiously revitalized." owner.adjustBruteLoss(-20) owner.adjustOxyLoss(-20) owner.adjustFireLoss(-20) -/obj/item/organ/internal/gland/slime +/obj/item/organ/gland/slime origin_tech = "materials=4;biotech=6;abductor=3" cooldown_low = 600 cooldown_high = 1200 uses = -1 icon_state = "slime" -/obj/item/organ/internal/gland/slime/activate() +/obj/item/organ/gland/slime/activate() owner << "You feel nauseous!" owner.vomit(20) @@ -81,14 +81,14 @@ Slime.Friends = list(owner) Slime.Leader = owner -/obj/item/organ/internal/gland/mindshock +/obj/item/organ/gland/mindshock origin_tech = "materials=4;biotech=5;magnets=3;abductor=3" cooldown_low = 300 cooldown_high = 300 uses = -1 icon_state = "mindshock" -/obj/item/organ/internal/gland/mindshock/activate() +/obj/item/organ/gland/mindshock/activate() owner << "You get a headache." var/turf/T = get_turf(owner) @@ -98,7 +98,7 @@ H << "You hear a buzz in your head." H.confused += 20 -/obj/item/organ/internal/gland/pop +/obj/item/organ/gland/pop origin_tech = "materials=4;biotech=6;abductor=3" cooldown_low = 900 cooldown_high = 1800 @@ -106,32 +106,32 @@ human_only = 1 icon_state = "species" -/obj/item/organ/internal/gland/pop/activate() +/obj/item/organ/gland/pop/activate() owner << "You feel unlike yourself." var/species = pick(list(/datum/species/lizard,/datum/species/jelly/slime,/datum/species/pod,/datum/species/fly)) owner.set_species(species) -/obj/item/organ/internal/gland/ventcrawling +/obj/item/organ/gland/ventcrawling origin_tech = "materials=4;biotech=5;bluespace=3;abductor=3" cooldown_low = 1800 cooldown_high = 2400 uses = 1 icon_state = "vent" -/obj/item/organ/internal/gland/ventcrawling/activate() +/obj/item/organ/gland/ventcrawling/activate() owner << "You feel very stretchy." owner.ventcrawler = 2 return -/obj/item/organ/internal/gland/viral +/obj/item/organ/gland/viral origin_tech = "materials=4;biotech=6;abductor=3" cooldown_low = 1800 cooldown_high = 2400 uses = 1 icon_state = "viral" -/obj/item/organ/internal/gland/viral/activate() +/obj/item/organ/gland/viral/activate() owner << "You feel sick." var/virus_type = pick(/datum/disease/beesease, /datum/disease/brainrot, /datum/disease/magnitis) var/datum/disease/D = new virus_type() @@ -142,49 +142,49 @@ owner.med_hud_set_status() -/obj/item/organ/internal/gland/emp //TODO : Replace with something more interesting +/obj/item/organ/gland/emp //TODO : Replace with something more interesting origin_tech = "materials=4;biotech=5;magnets=3;abductor=3" cooldown_low = 900 cooldown_high = 1600 uses = 10 icon_state = "emp" -/obj/item/organ/internal/gland/emp/activate() +/obj/item/organ/gland/emp/activate() owner << "You feel a spike of pain in your head." empulse(get_turf(owner), 2, 5, 1) -/obj/item/organ/internal/gland/spiderman +/obj/item/organ/gland/spiderman origin_tech = "materials=4;biotech=6;abductor=3" cooldown_low = 450 cooldown_high = 900 uses = 10 icon_state = "spider" -/obj/item/organ/internal/gland/spiderman/activate() +/obj/item/organ/gland/spiderman/activate() owner << "You feel something crawling in your skin." owner.faction |= "spiders" new /obj/effect/spider/spiderling(owner.loc) -/obj/item/organ/internal/gland/egg +/obj/item/organ/gland/egg origin_tech = "materials=4;biotech=6;abductor=3" cooldown_low = 300 cooldown_high = 400 uses = -1 icon_state = "egg" -/obj/item/organ/internal/gland/egg/activate() +/obj/item/organ/gland/egg/activate() owner << "You lay an egg!" var/obj/item/weapon/reagent_containers/food/snacks/egg/egg = new(owner.loc) egg.reagents.add_reagent("sacid",20) egg.desc += " It smells bad." -/obj/item/organ/internal/gland/bloody +/obj/item/organ/gland/bloody origin_tech = "materials=4;biotech=6;abductor=3" cooldown_low = 200 cooldown_high = 400 uses = -1 -/obj/item/organ/internal/gland/bloody/activate() +/obj/item/organ/gland/bloody/activate() owner.adjustBruteLoss(15) owner.visible_message("[owner]'s skin erupts with blood!",\ @@ -200,14 +200,14 @@ H.w_uniform.add_blood(owner) H.update_inv_w_uniform(0) -/obj/item/organ/internal/gland/bodysnatch +/obj/item/organ/gland/bodysnatch origin_tech = "materials=4;biotech=7;abductor=3" cooldown_low = 600 cooldown_high = 600 human_only = 1 uses = 1 -/obj/item/organ/internal/gland/bodysnatch/activate() +/obj/item/organ/gland/bodysnatch/activate() owner << "You feel something moving around inside you..." //spawn cocoon with clone greytide snpc inside if(ishuman(owner)) @@ -252,13 +252,13 @@ M.loc = src.loc qdel(src) -/obj/item/organ/internal/gland/plasma +/obj/item/organ/gland/plasma cooldown_low = 2400 cooldown_high = 3000 origin_tech = "materials=4;biotech=5;plasmatech=3;abductor=3" uses = 1 -/obj/item/organ/internal/gland/plasma/activate() +/obj/item/organ/gland/plasma/activate() owner << "You feel bloated." sleep(150) if(!owner) return diff --git a/code/game/gamemodes/miniantags/abduction/machinery/dispenser.dm b/code/game/gamemodes/miniantags/abduction/machinery/dispenser.dm index 5a8eb481921..dc1a5ec85f7 100644 --- a/code/game/gamemodes/miniantags/abduction/machinery/dispenser.dm +++ b/code/game/gamemodes/miniantags/abduction/machinery/dispenser.dm @@ -14,7 +14,7 @@ return rgb(rand(0,255),rand(0,255),rand(0,255)) /obj/machinery/abductor/gland_dispenser/New() - gland_types = subtypesof(/obj/item/organ/internal/gland) + gland_types = subtypesof(/obj/item/organ/gland) gland_types = shuffle(gland_types) gland_colors = new/list(gland_types.len) amounts = new/list(gland_types.len) @@ -59,7 +59,7 @@ return /obj/machinery/abductor/gland_dispenser/attackby(obj/item/weapon/W, mob/user, params) - if(istype(W, /obj/item/organ/internal/gland)) + if(istype(W, /obj/item/organ/gland)) if(!user.drop_item()) return W.loc = src diff --git a/code/game/gamemodes/miniantags/abduction/machinery/experiment.dm b/code/game/gamemodes/miniantags/abduction/machinery/experiment.dm index d1909eed3c0..19fbe24f92d 100644 --- a/code/game/gamemodes/miniantags/abduction/machinery/experiment.dm +++ b/code/game/gamemodes/miniantags/abduction/machinery/experiment.dm @@ -137,7 +137,7 @@ if(H.stat == DEAD) say("Specimen deceased - please provide fresh sample.") return "Specimen deceased." - var/obj/item/organ/internal/gland/GlandTest = locate() in H.internal_organs + var/obj/item/organ/gland/GlandTest = locate() in H.internal_organs if(!GlandTest) say("Experimental dissection not detected!") return "No glands detected!" @@ -166,7 +166,7 @@ obj_count++ ticker.mode.update_abductor_icons_added(H.mind) - for(var/obj/item/organ/internal/gland/G in H.internal_organs) + for(var/obj/item/organ/gland/G in H.internal_organs) G.Start() point_reward++ if(point_reward > 0) diff --git a/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm b/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm index 4a47acdeaa3..03d896d0e1d 100644 --- a/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm +++ b/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm @@ -52,6 +52,7 @@ melee_damage_upper = 15 melee_damage_type = STAMINA damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 0, CLONE = 0, STAMINA = 0, OXY = 0) + hud_possible = list(ANTAG_HUD, DIAG_STAT_HUD, DIAG_HUD) languages = SWARMER environment_smash = 0 attacktext = "shocks" @@ -84,6 +85,17 @@ /mob/living/simple_animal/hostile/swarmer/New() ..() verbs -= /mob/living/verb/pulled + var/datum/atom_hud/data/diagnostic/diag_hud = huds[DATA_HUD_DIAGNOSTIC] + diag_hud.add_to_hud(src) + + +/mob/living/simple_animal/hostile/swarmer/med_hud_set_health() + var/image/holder = hud_list[DIAG_HUD] + holder.icon_state = "huddiag[RoundDiagBar(health/maxHealth)]" + +/mob/living/simple_animal/hostile/swarmer/med_hud_set_status() + var/image/holder = hud_list[DIAG_STAT_HUD] + holder.icon_state = "hudstat" /mob/living/simple_animal/hostile/swarmer/Stat() ..() diff --git a/code/game/gamemodes/miniantags/monkey/monkey.dm b/code/game/gamemodes/miniantags/monkey/monkey.dm index 12f24f40b6e..717bf0a8346 100644 --- a/code/game/gamemodes/miniantags/monkey/monkey.dm +++ b/code/game/gamemodes/miniantags/monkey/monkey.dm @@ -15,7 +15,7 @@ var/carriers_to_make = 1 var/list/carriers = list() - var/monkeys_to_win = 0 + var/monkeys_to_win = 1 var/escaped_monkeys = 0 var/players_per_carrier = 30 diff --git a/code/game/gamemodes/miniantags/revenant/revenant.dm b/code/game/gamemodes/miniantags/revenant/revenant.dm index 6d9e107a652..5725354a7ea 100644 --- a/code/game/gamemodes/miniantags/revenant/revenant.dm +++ b/code/game/gamemodes/miniantags/revenant/revenant.dm @@ -41,7 +41,7 @@ anchored = 1 mob_size = MOB_SIZE_TINY pass_flags = PASSTABLE | PASSGRILLE | PASSMOB - speed = 0 + speed = 1 unique_name = 1 var/essence = 75 //The resource, and health, of revenants. @@ -268,9 +268,13 @@ if(!src) return var/turf/T = get_turf(src) - if(istype(T, /turf/closed/wall)) + if(istype(T, /turf/closed)) src << "You cannot use abilities from inside of a wall." return 0 + for(var/obj/O in T) + if(O.density && !O.CanPass(src, T, 5)) + src << "You cannot use abilities inside of a dense object." + return 0 if(src.inhibited) src << "Your powers have been suppressed by nulling energy!" return 0 diff --git a/code/game/gamemodes/miniantags/revenant/revenant_abilities.dm b/code/game/gamemodes/miniantags/revenant/revenant_abilities.dm index b311c1e7669..d03f94b1164 100644 --- a/code/game/gamemodes/miniantags/revenant/revenant_abilities.dm +++ b/code/game/gamemodes/miniantags/revenant/revenant_abilities.dm @@ -118,6 +118,16 @@ log_say("RevenantTransmit: [key_name(user)]->[key_name(M)] : [msg]") user << "You transmit to [M]: [msg]" M << "An alien voice resonates from all around... [msg]" + for(var/ded in dead_mob_list) + if(!isobserver(ded)) + continue + ded << "(F) \ + [user] \ + Revenant Transmit --> \ + (F) \ + [M] \ + [msg]" + /obj/effect/proc_holder/spell/aoe_turf/revenant @@ -214,7 +224,7 @@ if(M == user) continue L.Beam(M,icon_state="purple_lightning",icon='icons/effects/effects.dmi',time=5) - M.electrocute_act(shock_damage, "[L.name]", safety=1) + M.electrocute_act(shock_damage, L, safety=1) var/datum/effect_system/spark_spread/z = new /datum/effect_system/spark_spread z.set_up(4, 0, M) z.start() diff --git a/code/game/gamemodes/miniantags/revenant/revenant_blight.dm b/code/game/gamemodes/miniantags/revenant/revenant_blight.dm index 11ca11e7d3b..75efe72c4d9 100644 --- a/code/game/gamemodes/miniantags/revenant/revenant_blight.dm +++ b/code/game/gamemodes/miniantags/revenant/revenant_blight.dm @@ -25,7 +25,7 @@ ..() /datum/disease/revblight/stage_act() - if(!finalstage && affected_mob.lying && prob(stage*2)) + if(!finalstage && affected_mob.lying && prob(stage*5)) cure() return if(!finalstage && prob(stage*3)) diff --git a/code/game/gamemodes/miniantags/revenant/revenant_spawn_event.dm b/code/game/gamemodes/miniantags/revenant/revenant_spawn_event.dm index 287dff359e1..ebd2f67eafd 100644 --- a/code/game/gamemodes/miniantags/revenant/revenant_spawn_event.dm +++ b/code/game/gamemodes/miniantags/revenant/revenant_spawn_event.dm @@ -1,11 +1,11 @@ -#define REVENANT_SPAWN_THRESHOLD 10 +#define REVENANT_SPAWN_THRESHOLD 20 /datum/round_event_control/revenant name = "Spawn Revenant" typepath = /datum/round_event/revenant weight = 7 max_occurrences = 1 - earliest_start = 6000 //Meant to mix things up early-game. + earliest_start = 12000 //Meant to mix things up early-game. min_players = 5 diff --git a/code/game/gamemodes/miniantags/slaughter/slaughter.dm b/code/game/gamemodes/miniantags/slaughter/slaughter.dm index 8ed824052bd..88c386b94a6 100644 --- a/code/game/gamemodes/miniantags/slaughter/slaughter.dm +++ b/code/game/gamemodes/miniantags/slaughter/slaughter.dm @@ -41,7 +41,7 @@ loot = list(/obj/effect/decal/cleanable/blood, \ /obj/effect/decal/cleanable/blood/innards, \ - /obj/item/organ/internal/heart/demon) + /obj/item/organ/heart/demon) del_on_death = 1 deathmessage = "The generic slaughter demon screams in anger because this is the default death message!" @@ -73,17 +73,17 @@ //The loot from killing a slaughter demon - can be consumed to allow the user to blood crawl -/obj/item/organ/internal/heart/demon +/obj/item/organ/heart/demon name = "demon heart" desc = "Still it beats furiously, emanating an aura of utter hate." icon = 'icons/obj/surgery.dmi' icon_state = "demon_heart" origin_tech = "combat=5;biotech=8" -/obj/item/organ/internal/heart/demon/update_icon() +/obj/item/organ/heart/demon/update_icon() return //always beating visually -/obj/item/organ/internal/heart/demon/attack(mob/M, mob/living/carbon/user, obj/target) +/obj/item/organ/heart/demon/attack(mob/M, mob/living/carbon/user, obj/target) if(M != user) return ..() user.visible_message("[user] raises [src] to their mouth and tears into it with their teeth!", \ @@ -99,17 +99,17 @@ user.drop_item() src.Insert(user) //Consuming the heart literally replaces your heart with a demon heart. H A R D C O R E -/obj/item/organ/internal/heart/demon/Insert(mob/living/carbon/M, special = 0) +/obj/item/organ/heart/demon/Insert(mob/living/carbon/M, special = 0) ..() if(M.mind) M.mind.AddSpell(new /obj/effect/proc_holder/spell/bloodcrawl(null)) -/obj/item/organ/internal/heart/demon/Remove(mob/living/carbon/M, special = 0) +/obj/item/organ/heart/demon/Remove(mob/living/carbon/M, special = 0) ..() if(M.mind) M.mind.RemoveSpell(/obj/effect/proc_holder/spell/bloodcrawl) -/obj/item/organ/internal/heart/demon/Stop() +/obj/item/organ/heart/demon/Stop() return 0 // Always beating. /mob/living/simple_animal/slaughter/laughter diff --git a/code/game/gamemodes/nuclear/nuclear.dm b/code/game/gamemodes/nuclear/nuclear.dm index ee02361d451..fbd6fe472a8 100644 --- a/code/game/gamemodes/nuclear/nuclear.dm +++ b/code/game/gamemodes/nuclear/nuclear.dm @@ -303,7 +303,7 @@ l_pocket = /obj/item/weapon/pinpointer/nukeop id = /obj/item/weapon/card/id/syndicate belt = /obj/item/weapon/gun/projectile/automatic/pistol - backpack_contents = list(/obj/item/weapon/storage/box/engineer=1) + backpack_contents = list(/obj/item/weapon/storage/box/syndie=1) var/tc = 25 @@ -338,7 +338,7 @@ r_pocket = /obj/item/weapon/tank/internals/emergency_oxygen/engi belt = /obj/item/weapon/storage/belt/military r_hand = /obj/item/weapon/gun/projectile/automatic/shotgun/bulldog - backpack_contents = list(/obj/item/weapon/storage/box/engineer=1,\ + backpack_contents = list(/obj/item/weapon/storage/box/syndie=1,\ /obj/item/weapon/tank/jetpack/oxygen/harness=1,\ /obj/item/weapon/gun/projectile/automatic/pistol=1) diff --git a/code/game/gamemodes/shadowling/shadowling.dm b/code/game/gamemodes/shadowling/shadowling.dm index 64bd43c8bea..9ea427013e0 100644 --- a/code/game/gamemodes/shadowling/shadowling.dm +++ b/code/game/gamemodes/shadowling/shadowling.dm @@ -257,6 +257,7 @@ Made by Xhuis specflags = list(NOBREATH,NOBLOOD,RADIMMUNE,NOGUNS) //Can't use guns due to muzzle flash burnmod = 1.5 //1.5x burn damage, 2x is excessive heatmod = 1.5 + has_dismemberment = 0 /datum/species/shadow/ling/spec_life(mob/living/carbon/human/H) if(!H.weakeyes) H.weakeyes = 1 //Makes them more vulnerable to flashes and flashbangs diff --git a/code/game/gamemodes/wizard/artefact.dm b/code/game/gamemodes/wizard/artefact.dm index 986f9357519..a8248121b9b 100644 --- a/code/game/gamemodes/wizard/artefact.dm +++ b/code/game/gamemodes/wizard/artefact.dm @@ -298,7 +298,7 @@ var/global/list/multiverse = list() M.set_species(pick(all_species), icon_update=0) M.update_body() M.update_hair() - M.update_mutcolor() + M.update_body_parts() M.dna.update_dna_identity() equip_copy(M) @@ -355,21 +355,9 @@ var/global/list/multiverse = list() M.equip_to_slot_or_del(new /obj/item/clothing/head/wizard/red(M), slot_head) M.equip_to_slot_or_del(sword, slot_r_hand) if("cyborg") - var/obj/item/organ/limb/chest/C = locate(/obj/item/organ/limb/chest) in M.organs - qdel(C) - M.organs += new /obj/item/organ/limb/robot/chest - var/obj/item/organ/limb/r_arm/R = locate(/obj/item/organ/limb/r_arm) in M.organs - qdel(R) - M.organs += new /obj/item/organ/limb/robot/r_arm - var/obj/item/organ/limb/l_arm/L = locate(/obj/item/organ/limb/l_arm) in M.organs - qdel(L) - M.organs += new /obj/item/organ/limb/robot/l_arm - var/obj/item/organ/limb/l_leg/LL = locate(/obj/item/organ/limb/l_leg) in M.organs - qdel(LL) - M.organs += new /obj/item/organ/limb/robot/l_leg - var/obj/item/organ/limb/r_leg/RL = locate(/obj/item/organ/limb/r_leg) in M.organs - qdel(RL) - M.organs += new /obj/item/organ/limb/robot/r_leg + for(var/X in M.bodyparts) + var/obj/item/bodypart/affecting = X + affecting.change_bodypart_status(ORGAN_ROBOTIC) M.equip_to_slot_or_del(new /obj/item/clothing/glasses/thermal/eyepatch(M), slot_glasses) M.equip_to_slot_or_del(sword, slot_r_hand) @@ -473,7 +461,7 @@ var/global/list/multiverse = list() return M.update_icons() - M.update_augments() + M.update_body_parts() var/obj/item/weapon/card/id/W = new /obj/item/weapon/card/id W.icon_state = "centcom" @@ -602,7 +590,7 @@ var/global/list/multiverse = list() //Provides a decent heal, need to pump every 6 seconds -/obj/item/organ/internal/heart/cursed/wizard +/obj/item/organ/heart/cursed/wizard pump_delay = 60 heal_brute = 25 heal_burn = 25 diff --git a/code/game/gamemodes/wizard/soulstone.dm b/code/game/gamemodes/wizard/soulstone.dm index 72b678155e3..92c19d7600b 100644 --- a/code/game/gamemodes/wizard/soulstone.dm +++ b/code/game/gamemodes/wizard/soulstone.dm @@ -7,7 +7,6 @@ w_class = 1 slot_flags = SLOT_BELT origin_tech = "bluespace=4;materials=4" - var/imprinted = "empty" var/usability = 0 /obj/item/device/soulstone/anybody @@ -19,6 +18,12 @@ user << "An overwhelming feeling of dread comes over you as you pick up the soulstone. It would be wise to be rid of this quickly." user.Dizzy(120) +/obj/item/device/soulstone/examine(mob/user) + ..() + if(usability || iscultist(user) || iswizard(user) || user.stat == DEAD) + user << "A soulstone, used to capture souls, either from unconscious or sleeping humans or from freed shades." + user << "The captured soul can be placed into a construct shell to produce a construct, or released from the stone as a shade." + //////////////////////////////Capturing//////////////////////////////////////////////////////// /obj/item/device/soulstone/attack(mob/living/carbon/human/M, mob/user) @@ -28,10 +33,8 @@ return if(!istype(M, /mob/living/carbon/human))//If target is not a human. return ..() - if(istype(M, /mob/living/carbon/human/dummy)) - return ..() if(iscultist(M)) - user << "You shouldn't do that." + user << "\"Come now, do not capture your fellow's soul.\"" return add_logs(user, M, "captured [M.name]'s soul", src) @@ -41,53 +44,23 @@ ///////////////////Options for using captured souls/////////////////////////////////////// /obj/item/device/soulstone/attack_self(mob/user) - if (!in_range(src, user)) + if(!in_range(src, user)) return if(!iscultist(user) && !iswizard(user) && !usability) user.Paralyse(5) user << "Your body is wracked with debilitating pain!" return - user.set_machine(src) - var/dat = "Soul Stone
" for(var/mob/living/simple_animal/shade/A in src) - dat += "Captured Soul: [A.name]
" - dat += {"Summon Shade"} - dat += "
" - dat += {"Close"} - user << browse(dat, "window=aicard") - onclose(user, "aicard") - return - - -/obj/item/device/soulstone/Topic(href, href_list) - var/mob/U = usr - if (!in_range(src, U)||U.machine!=src) - U << browse(null, "window=aicard") - U.unset_machine() - return - - add_fingerprint(U) - U.set_machine(src) - - switch(href_list["choice"])//Now we switch based on choice. - if ("Close") - U << browse(null, "window=aicard") - U.unset_machine() - return - - if ("Summon") - for(var/mob/living/simple_animal/shade/A in src) - A.status_flags &= ~GODMODE - A.canmove = 1 - A.loc = U.loc - A.cancel_camera() - src.icon_state = "soulstone" - if(iswizard(U) || usability) - A << "You have been released from your prison, but you are still bound to [U.real_name]'s will. Help them succeed in their goals at all costs." - else if(iscultist(U)) - A << "You have been released from your prison, but you are still bound to the cult's will. Help them succeed in their goals at all costs." - - attack_self(U) + A.status_flags &= ~GODMODE + A.canmove = 1 + A.forceMove(get_turf(user)) + A.cancel_camera() + icon_state = "soulstone" + name = initial(name) + if(iswizard(user) || usability) + A << "You have been released from your prison, but you are still bound to [user.real_name]'s will. Help them succeed in their goals at all costs." + else if(iscultist(user)) + A << "You have been released from your prison, but you are still bound to the cult's will. Help them succeed in their goals at all costs." ///////////////////////////Transferring to constructs///////////////////////////////////////////////////// /obj/structure/constructshell @@ -96,6 +69,15 @@ icon_state = "construct" desc = "A wicked machine used by those skilled in magical arts. It is inactive." +/obj/structure/constructshell/examine(mob/user) + ..() + if(iscultist(user) || iswizard(user) || user.stat == DEAD) + user << "A construct shell, used to house bound souls from a soulstone." + user << "Placing a soulstone with a soul into this shell allows you to produce your choice of the following:" + user << "An Artificer, which can produce more shells and soulstones, as well as fortifications." + user << "A Wraith, which does high damage and can jaunt through walls, though it is quite fragile." + user << "A Juggernaut, which is very hard to kill and can produce temporary walls, but is slow." + /obj/structure/constructshell/attackby(obj/item/O, mob/user, params) if(istype(O, /obj/item/device/soulstone)) var/obj/item/device/soulstone/SS = O @@ -121,56 +103,50 @@ if(T.client != null) for(var/obj/item/W in T) T.unEquip(W) - init_shade(src, T, user) + init_shade(T, user) return 1 else user << "Capture failed!: The soul has already fled its mortal frame. You attempt to bring it back..." - return getCultGhost(src,T,user) + return getCultGhost(T,user) if("VICTIM") var/mob/living/carbon/human/T = target if(ticker.mode.name == "cult" && T.mind == ticker.mode:sacrifice_target) if(iscultist(user)) - user << "The Geometer of blood wants this mortal sacrificed with the rune." + user << "\"This soul is mine. SACRIFICE THEM!\"" else - user << "The soul stone doesn't work for no apparent reason." + user << "The soulstone doesn't work for no apparent reason." return 0 - if(imprinted != "empty") - user << "Capture failed!: The soul stone has already been imprinted with [imprinted]'s mind!" + if(contents.len) + user << "Capture failed!: The soulstone is full! Free an existing soul to make room." else - if (T.stat == 0) - user << "Capture failed!: Kill or maim the victim first!" - else + if(T.stat != CONSCIOUS) if(T.client == null) user << "Capture failed!: The soul has already fled its mortal frame. You attempt to bring it back..." - getCultGhost(src,T,user) + getCultGhost(T,user) else - if(contents.len) - user << "Capture failed!: The soul stone is full! Use or free an existing soul to make room." - else - for(var/obj/item/W in T) - T.unEquip(W) - init_shade(src, T, user, vic = 1) - qdel(T) + for(var/obj/item/W in T) + T.unEquip(W) + init_shade(T, user, vic = 1) + qdel(T) + else + user << "Capture failed!: Kill or maim the victim first!" + if("SHADE") var/mob/living/simple_animal/shade/T = target - if (T.stat == DEAD) - user << "Capture failed!: The shade has already been banished!" + if(contents.len) + user << "Capture failed!: The soulstone is full! Free an existing soul to make room." else - if(contents.len) - user << "Capture failed!: The soul stone is full! Use or free an existing soul to make room." - else - if(T.name != imprinted) - user << "Capture failed!: The soul stone has already been imprinted with [imprinted]'s mind!" - else - T.loc = src //put shade in stone - T.status_flags |= GODMODE - T.canmove = 0 - T.health = T.maxHealth - icon_state = "soulstone2" - T << "Your soul has been recaptured by the soul stone, its arcane energies are reknitting your ethereal form" - if(user != T) - user << "Capture successful!: [T.real_name]'s has been recaptured and stored within the soul stone." + T.loc = src //put shade in stone + T.status_flags |= GODMODE + T.canmove = 0 + T.health = T.maxHealth + icon_state = "soulstone2" + name = "soulstone: Shade of [T.real_name]" + T << "Your soul has been captured by the soulstone. Its arcane energies are reknitting your ethereal form." + if(user != T) + user << "Capture successful!: [T.real_name]'s soul has been captured and stored within the soulstone." + if("CONSTRUCT") var/obj/structure/constructshell/T = target var/mob/living/simple_animal/shade/A = locate() in src @@ -193,6 +169,7 @@ makeNewConstruct(/mob/living/simple_animal/hostile/construct/builder/noncult, A, user, 0, T.loc) qdel(T) + user.drop_item() qdel(src) else user << "Creation failed!: The soul stone is empty! Go kill someone!" @@ -203,22 +180,22 @@ var/mob/living/simple_animal/hostile/construct/newstruct = new ctype((loc_override) ? (loc_override) : (get_turf(target))) newstruct.faction |= "\ref[stoner]" newstruct.key = target.key - if(stoner && iscultist(stoner) || cultoverride) - if(ticker.mode.name == "cult") - ticker.mode:add_cultist(newstruct.mind) - else - ticker.mode.cult+=newstruct.mind - ticker.mode.update_cult_icons_added(newstruct.mind) + if(newstruct.mind) + if(stoner && iscultist(stoner) || cultoverride) + if(ticker.mode.name == "cult") + ticker.mode:add_cultist(newstruct.mind, 0) + else + ticker.mode.cult += newstruct.mind + ticker.mode.update_cult_icons_added(newstruct.mind) newstruct << newstruct.playstyle_string - if(stoner && iswizard(stoner)) - newstruct << "You are still bound to serve your creator, follow their orders and help them complete their goals at all costs." - else if(stoner && iscultist(stoner)) - newstruct << "You are still bound to serve the cult, follow their orders and help them complete their goals at all costs." - else newstruct << "You are still bound to serve your creator, follow their orders and help them complete their goals at all costs." + if(iscultist(stoner)) + newstruct << "You are still bound to serve the cult and [stoner], follow their orders and help them complete their goals at all costs." + else + newstruct << "You are still bound to serve your creator, [stoner], follow their orders and help them complete their goals at all costs." newstruct.cancel_camera() -/obj/item/device/soulstone/proc/init_shade(obj/item/device/soulstone/C, mob/living/carbon/human/T, mob/U, vic = 0) +/obj/item/device/soulstone/proc/init_shade(mob/living/carbon/human/T, mob/U, vic = 0) new /obj/effect/decal/remains/human(T.loc) //Spawns a skeleton T.invisibility = INVISIBILITY_ABSTRACT var/atom/movable/overlay/animation = new /atom/movable/overlay( T.loc ) @@ -227,8 +204,7 @@ animation.master = T flick("dust-h", animation) qdel(animation) - var/mob/living/simple_animal/shade/S = new /mob/living/simple_animal/shade( T.loc ) - S.loc = C //put shade in stone + var/mob/living/simple_animal/shade/S = new /mob/living/simple_animal/shade(src) S.status_flags |= GODMODE //So they won't die inside the stone somehow S.canmove = 0//Can't move out of the soul stone S.name = "Shade of [T.real_name]" @@ -237,21 +213,19 @@ if(U) S.faction |= "\ref[U]" //Add the master as a faction, allowing inter-mob cooperation if(U && iscultist(U)) - ticker.mode.add_cultist(S.mind,2) + ticker.mode.add_cultist(S.mind, 0) S.cancel_camera() - C.icon_state = "soulstone2" - C.name = "Soul Stone: [S.real_name]" + name = "soulstone: Shade of [T.real_name]" + icon_state = "soulstone2" if(U && (iswizard(U) || usability)) S << "Your soul has been captured! You are now bound to [U.real_name]'s will. Help them succeed in their goals at all costs." else if(U && iscultist(U)) S << "Your soul has been captured! You are now bound to the cult's will. Help them succeed in their goals at all costs." - C.imprinted = "[S.name]" if(vic && U) U << "Capture successful!: [T.real_name]'s soul has been ripped from their body and stored within the soul stone." - U << "The soulstone has been imprinted with [S.real_name]'s mind, it will no longer react to other souls." -/obj/item/device/soulstone/proc/getCultGhost(obj/item/device/soulstone/C, mob/living/carbon/human/T, mob/U) +/obj/item/device/soulstone/proc/getCultGhost(mob/living/carbon/human/T, mob/U) var/mob/dead/observer/chosen_ghost for(var/mob/dead/observer/ghost in player_list) //We put them back in their body @@ -266,13 +240,13 @@ if(!T) return 0 if(!chosen_ghost) - U << "The ghost has fled beyond your grasp." + U << "There were no spirits willing to become a shade." return 0 - if(C.contents.len) //If they used the soulstone on someone else in the meantime + if(contents.len) //If they used the soulstone on someone else in the meantime return 0 T.ckey = chosen_ghost.ckey for(var/obj/item/W in T) T.unEquip(W) - init_shade(C, T, U) + init_shade(T, U) qdel(T) return 1 diff --git a/code/game/gamemodes/wizard/spellbook.dm b/code/game/gamemodes/wizard/spellbook.dm index d685bd0ea9b..360311ad9c1 100644 --- a/code/game/gamemodes/wizard/spellbook.dm +++ b/code/game/gamemodes/wizard/spellbook.dm @@ -371,7 +371,7 @@ /datum/spellbook_entry/item/cursed_heart name = "Cursed Heart" desc = "A heart that has been revived by dark magicks, the user must concentrate to ensure the heart beats, but every beat heals them. It must beat every 6 seconds." - item_path = /obj/item/organ/internal/heart/cursed/wizard + item_path = /obj/item/organ/heart/cursed/wizard log_name = "CH" cost = 1 category = "Defensive" diff --git a/code/game/machinery/cloning.dm b/code/game/machinery/cloning.dm index 3efd30fa8b8..604fb26bed0 100644 --- a/code/game/machinery/cloning.dm +++ b/code/game/machinery/cloning.dm @@ -82,7 +82,7 @@ if ((M.stat != 2) || (!M.client)) continue //They need a brain! - if (ishuman(M) && !M.getorgan(/obj/item/organ/internal/brain)) + if (ishuman(M) && !M.getorgan(/obj/item/organ/brain)) continue if (M.ckey == find_key) diff --git a/code/game/machinery/computer/cloning.dm b/code/game/machinery/computer/cloning.dm index 7bd87b7a574..fc252a50ab4 100644 --- a/code/game/machinery/computer/cloning.dm +++ b/code/game/machinery/computer/cloning.dm @@ -353,7 +353,7 @@ if (!istype(subject)) scantemp = "Unable to locate valid genetic data." return - if (!subject.getorgan(/obj/item/organ/internal/brain)) + if (!subject.getorgan(/obj/item/organ/brain)) scantemp = "No signs of intelligence detected." return if (subject.suiciding == 1) diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index 66c2510e0ae..83700f7dd21 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -566,10 +566,10 @@ var/list/airlock_overlays = list() if(!istype(H.head, /obj/item/clothing/head/helmet)) H.visible_message("[user] headbutts the airlock.", \ "You headbutt the airlock!") - var/obj/item/organ/limb/affecting = H.get_organ("head") + var/obj/item/bodypart/affecting = H.get_bodypart("head") H.Stun(5) H.Weaken(5) - if(affecting.take_damage(10, 0)) + if(affecting && affecting.take_damage(10, 0)) H.update_damage_overlays(0) else visible_message("[user] headbutts the airlock. Good thing they're wearing a helmet.") diff --git a/code/game/mecha/equipment/mecha_equipment.dm b/code/game/mecha/equipment/mecha_equipment.dm index 7971b6966ea..d2ff930d4eb 100644 --- a/code/game/mecha/equipment/mecha_equipment.dm +++ b/code/game/mecha/equipment/mecha_equipment.dm @@ -13,8 +13,8 @@ var/energy_drain = 0 var/obj/mecha/chassis = null var/range = MELEE //bitflags - reliability = 1000 var/salvageable = 1 + var/selectable = 1 // Set to 0 for passive equipment such as mining scanner or armor plates /obj/item/mecha_parts/mecha_equipment/proc/update_chassis_page() if(chassis) @@ -50,7 +50,15 @@ /obj/item/mecha_parts/mecha_equipment/proc/get_equip_info() if(!chassis) return - return "* [chassis.selected==src?"":""][src.name][chassis.selected==src?"":""]" + var/txt = "* " + if(chassis.selected == src) + txt += "[src.name]" + else if(selectable) + txt += "[src.name]" + else + txt += "[src.name]" + + return txt /obj/item/mecha_parts/mecha_equipment/proc/is_ranged()//add a distance restricted equipment. Why not? return range&RANGED @@ -102,7 +110,7 @@ chassis = M src.loc = M M.log_message("[src] initialized.") - if(!M.selected) + if(!M.selected && selectable) M.selected = src src.update_chassis_page() return diff --git a/code/game/mecha/equipment/tools/mining_tools.dm b/code/game/mecha/equipment/tools/mining_tools.dm index 9231a0654b6..a43d273ac65 100644 --- a/code/game/mecha/equipment/tools/mining_tools.dm +++ b/code/game/mecha/equipment/tools/mining_tools.dm @@ -83,7 +83,7 @@ add_logs(user, target, "attacked", "[name]", "(INTENT: [uppertext(user.a_intent)]) (DAMTYPE: [uppertext(damtype)])") if(ishuman(target)) var/mob/living/carbon/human/H = target - var/obj/item/organ/limb/affecting = H.get_organ("chest") + var/obj/item/bodypart/affecting = H.get_bodypart("chest") affecting.take_damage(drill_damage) H.update_damage_overlays(0) else if(target.stat == DEAD && target.butcher_results) @@ -112,7 +112,7 @@ desc = "Equipment for engineering and combat exosuits. It will automatically check surrounding rock for useful minerals." icon_state = "mecha_analyzer" origin_tech = "materials=3;engineering=2" - equip_cooldown = 30 + selectable = 0 var/scanning = 0 /obj/item/mecha_parts/mecha_equipment/mining_scanner/New() diff --git a/code/game/mecha/equipment/tools/other_tools.dm b/code/game/mecha/equipment/tools/other_tools.dm index cc40a6629a0..ead3ad8781d 100644 --- a/code/game/mecha/equipment/tools/other_tools.dm +++ b/code/game/mecha/equipment/tools/other_tools.dm @@ -152,10 +152,7 @@ range = 0 var/deflect_coeff = 1.15 var/damage_coeff = 0.8 - -/obj/item/mecha_parts/mecha_equipment/anticcw_armor_booster/get_equip_info() - if(!chassis) return - return "* [src.name]" + selectable = 0 /obj/item/mecha_parts/mecha_equipment/anticcw_armor_booster/proc/attack_react(mob/user as mob) if(action_checks(user)) @@ -174,10 +171,7 @@ range = 0 var/deflect_coeff = 1.15 var/damage_coeff = 0.8 - -/obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster/get_equip_info() - if(!chassis) return - return "* [src.name]" + selectable = 0 /obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster/proc/projectile_react() if(action_checks(src)) @@ -198,6 +192,7 @@ var/health_boost = 1 var/icon/droid_overlay var/list/repairable_damage = list(MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH) + selectable = 0 /obj/item/mecha_parts/mecha_equipment/repair_droid/Destroy() SSobj.processing.Remove(src) @@ -217,7 +212,7 @@ /obj/item/mecha_parts/mecha_equipment/repair_droid/get_equip_info() if(!chassis) return - return "* [src.name] - [equip_ready?"A":"Dea"]ctivate" + return "*  [src.name] - [equip_ready?"A":"Dea"]ctivate" /obj/item/mecha_parts/mecha_equipment/repair_droid/Topic(href, href_list) @@ -281,6 +276,7 @@ range = 0 var/coeff = 100 var/list/use_channels = list(EQUIP,ENVIRON,LIGHT) + selectable = 0 /obj/item/mecha_parts/mecha_equipment/tesla_energy_relay/Destroy() SSobj.processing.Remove(src) @@ -323,7 +319,7 @@ /obj/item/mecha_parts/mecha_equipment/tesla_energy_relay/get_equip_info() if(!chassis) return - return "* [src.name] - [equip_ready?"A":"Dea"]ctivate" + return "*  [src.name] - [equip_ready?"A":"Dea"]ctivate" /obj/item/mecha_parts/mecha_equipment/tesla_energy_relay/process() @@ -488,7 +484,6 @@ fuel_per_cycle_active = 30 power_per_cycle = 50 var/rad_per_cycle = 0.3 - reliability = 1000 /obj/item/mecha_parts/mecha_equipment/generator/nuclear/generator_init() fuel = new /obj/item/stack/sheet/mineral/uranium(src) diff --git a/code/game/mecha/equipment/weapons/weapons.dm b/code/game/mecha/equipment/weapons/weapons.dm index c793887e424..b3c67c72ce4 100644 --- a/code/game/mecha/equipment/weapons/weapons.dm +++ b/code/game/mecha/equipment/weapons/weapons.dm @@ -205,7 +205,7 @@ return 1 /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/get_equip_info() - return "[..()]\[[src.projectiles]\][(src.projectiles < initial(src.projectiles))?" - Rearm":null]" + return "[..()] \[[src.projectiles]\][(src.projectiles < initial(src.projectiles))?" - Rearm":null]" /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/rearm() diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm index 97df7baeb51..6c62de01260 100644 --- a/code/game/mecha/mecha.dm +++ b/code/game/mecha/mecha.dm @@ -109,10 +109,12 @@ var/phase_state = "" //icon_state when phasing var/strafe = FALSE //If we are strafing - var/static/list/armour_facings = list("[NORTH]" = list("[SOUTH]" = FRONT_ARMOUR, "[EAST]" = SIDE_ARMOUR, "[WEST]" = SIDE_ARMOUR, "[NORTH]" = BACK_ARMOUR), -"[EAST]" = list("[SOUTH]" = SIDE_ARMOUR, "[WEST]" = FRONT_ARMOUR, "[EAST]" = BACK_ARMOUR, "[NORTH]" = SIDE_ARMOUR), -"[SOUTH]" = list("[NORTH]" = FRONT_ARMOUR, "[WEST]" = SIDE_ARMOUR, "[EAST]" = SIDE_ARMOUR, "[SOUTH]" = BACK_ARMOUR ), -"[WEST]" = list("[NORTH]" = SIDE_ARMOUR, "[EAST]" = FRONT_ARMOUR, "[SOUTH]" = SIDE_ARMOUR, "[WEST]" = BACK_ARMOUR) ) + var/static/list/armour_facings = list( + "[NORTH]" = list("[SOUTH]" = FRONT_ARMOUR, "[EAST]" = SIDE_ARMOUR, "[WEST]" = SIDE_ARMOUR, "[NORTH]" = BACK_ARMOUR, "[SOUTHEAST]" = SIDE_ARMOUR, "[NORTHEAST]" = SIDE_ARMOUR, "[SOUTHWEST]" = SIDE_ARMOUR, "[NORTHWEST]" = SIDE_ARMOUR), + "[EAST]" = list("[SOUTH]" = SIDE_ARMOUR, "[WEST]" = FRONT_ARMOUR, "[EAST]" = BACK_ARMOUR, "[NORTH]" = SIDE_ARMOUR, "[SOUTHEAST]" = SIDE_ARMOUR, "[NORTHEAST]" = SIDE_ARMOUR, "[SOUTHWEST]" = SIDE_ARMOUR, "[NORTHWEST]" = SIDE_ARMOUR), + "[SOUTH]" = list("[NORTH]" = FRONT_ARMOUR, "[WEST]" = SIDE_ARMOUR, "[EAST]" = SIDE_ARMOUR, "[SOUTH]" = BACK_ARMOUR, "[SOUTHEAST]" = SIDE_ARMOUR, "[NORTHEAST]" = SIDE_ARMOUR, "[SOUTHWEST]" = SIDE_ARMOUR, "[NORTHWEST]" = SIDE_ARMOUR ), + "[WEST]" = list("[NORTH]" = SIDE_ARMOUR, "[EAST]" = FRONT_ARMOUR, "[SOUTH]" = SIDE_ARMOUR, "[WEST]" = BACK_ARMOUR, "[SOUTHEAST]" = SIDE_ARMOUR, "[NORTHEAST]" = SIDE_ARMOUR, "[SOUTHWEST]" = SIDE_ARMOUR, "[NORTHWEST]" = SIDE_ARMOUR) + ) var/occupant_sight_flags = 0 //sight flags to give to the occupant (e.g. mech mining scanner gives meson-like vision) @@ -553,9 +555,8 @@ if(yes) if(..()) //mech was thrown return - if(bumpsmash) - var/mecha = src - obstacle.mech_melee_attack(mecha) + if(bumpsmash && occupant) //Need a pilot to push the PUNCH button. + obstacle.mech_melee_attack(src) if(!obstacle || (obstacle && !obstacle.density)) step(src,dir) if(istype(obstacle, /obj)) @@ -1017,280 +1018,4 @@ var/year_integer = text2num(year) // = 2013??? /obj/mecha/update_remote_sight(mob/living/user) if(occupant_sight_flags) if(user == occupant) - user.sight |= occupant_sight_flags - -//////////////////////////////////////// Action Buttons /////////////////////////////////////////////// - -/obj/mecha/proc/GrantActions(mob/living/user, human_occupant = 0) - if(human_occupant) - eject_action.Grant(user, src) - internals_action.Grant(user, src) - cycle_action.Grant(user, src) - lights_action.Grant(user, src) - stats_action.Grant(user, src) - strafing_action.Grant(user, src) - - -/obj/mecha/proc/RemoveActions(mob/living/user, human_occupant = 0) - if(human_occupant) - eject_action.Remove(user) - internals_action.Remove(user) - cycle_action.Remove(user) - lights_action.Remove(user) - stats_action.Remove(user) - strafing_action.Remove(user) - - -/datum/action/innate/mecha - check_flags = AB_CHECK_RESTRAINED | AB_CHECK_STUNNED | AB_CHECK_CONSCIOUS - var/obj/mecha/chassis - -/datum/action/innate/mecha/Grant(mob/living/L, obj/mecha/M) - chassis = M - ..() - -/datum/action/innate/mecha/Destroy() - chassis = null - return ..() - -/datum/action/innate/mecha/mech_eject - name = "Eject From Mech" - button_icon_state = "mech_eject" - -/datum/action/innate/mecha/mech_eject/Activate() - if(!owner || !iscarbon(owner)) - return - if(!chassis || chassis.occupant != owner) - return - chassis.go_out() - - -/datum/action/innate/mecha/mech_toggle_internals - name = "Toggle Internal Airtank Usage" - button_icon_state = "mech_internals_off" - -/datum/action/innate/mecha/mech_toggle_internals/Activate() - if(!owner || !chassis || chassis.occupant != owner) - return - chassis.use_internal_tank = !chassis.use_internal_tank - button_icon_state = "mech_internals_[chassis.use_internal_tank ? "on" : "off"]" - chassis.occupant_message("Now taking air from [chassis.use_internal_tank?"internal airtank":"environment"].") - chassis.log_message("Now taking air from [chassis.use_internal_tank?"internal airtank":"environment"].") - UpdateButtonIcon() - -/datum/action/innate/mecha/mech_cycle_equip - name = "Cycle Equipment" - button_icon_state = "mech_cycle_equip_off" - -/datum/action/innate/mecha/mech_cycle_equip/Activate() - if(!owner || !chassis || chassis.occupant != owner) - return - if(chassis.equipment.len == 0) - chassis.occupant_message("No equipment available.") - return - if(!chassis.selected) - chassis.selected = chassis.equipment[1] - chassis.occupant_message("You select [chassis.selected]") - send_byjax(chassis.occupant,"exosuit.browser","eq_list",chassis.get_equipment_list()) - button_icon_state = "mech_cycle_equip_on" - UpdateButtonIcon() - return - var/number = 0 - for(var/A in chassis.equipment) - number++ - if(A == chassis.selected) - if(chassis.equipment.len == number) - chassis.selected = null - chassis.occupant_message("You switch to no equipment") - button_icon_state = "mech_cycle_equip_off" - else - chassis.selected = chassis.equipment[number+1] - chassis.occupant_message("You switch to [chassis.selected]") - button_icon_state = "mech_cycle_equip_on" - send_byjax(chassis.occupant,"exosuit.browser","eq_list",chassis.get_equipment_list()) - UpdateButtonIcon() - return - - -/datum/action/innate/mecha/mech_toggle_lights - name = "Toggle Lights" - button_icon_state = "mech_lights_off" - -/datum/action/innate/mecha/mech_toggle_lights/Activate() - if(!owner || !chassis || chassis.occupant != owner) - return - chassis.lights = !chassis.lights - if(chassis.lights) - chassis.AddLuminosity(chassis.lights_power) - button_icon_state = "mech_lights_on" - else - chassis.AddLuminosity(-chassis.lights_power) - button_icon_state = "mech_lights_off" - chassis.occupant_message("Toggled lights [chassis.lights?"on":"off"].") - chassis.log_message("Toggled lights [chassis.lights?"on":"off"].") - UpdateButtonIcon() - -/datum/action/innate/mecha/mech_view_stats - name = "View Stats" - button_icon_state = "mech_view_stats" - -/datum/action/innate/mecha/mech_view_stats/Activate() - if(!owner || !chassis || chassis.occupant != owner) - return - chassis.occupant << browse(chassis.get_stats_html(), "window=exosuit") - - -/datum/action/innate/mecha/strafe - name = "Toggle Strafing" - button_icon_state = "strafe" - -/datum/action/innate/mecha/strafe/Activate() - if(!owner || !chassis || chassis.occupant != owner) - return - - chassis.toggle_strafe() - -/obj/mecha/AltClick(mob/living/user) - if(user == occupant) - toggle_strafe() - -/obj/mecha/proc/toggle_strafe() - strafe = !strafe - - occupant_message("Toggled strafing mode [strafe?"on":"off"].") - log_message("Toggled strafing mode [strafe?"on":"off"].") - strafing_action.UpdateButtonIcon() - -//////////////////////////////////////// Specific Ability Actions /////////////////////////////////////////////// -//Need to be granted by the mech type, Not default abilities. - -/datum/action/innate/mecha/mech_toggle_thrusters - name = "Toggle Thrusters" - button_icon_state = "mech_thrusters_off" - -/datum/action/innate/mecha/mech_toggle_thrusters/Activate() - if(!owner || !chassis || chassis.occupant != owner) - return - if(chassis.get_charge() > 0) - chassis.thrusters_active = !chassis.thrusters_active - button_icon_state = "mech_thrusters_[chassis.thrusters_active ? "on" : "off"]" - chassis.log_message("Toggled thrusters.") - chassis.occupant_message("Thrusters [chassis.thrusters_active ?"en":"dis"]abled.") - - -/datum/action/innate/mecha/mech_defence_mode - name = "Toggle Defence Mode" - button_icon_state = "mech_defense_mode_off" - -/datum/action/innate/mecha/mech_defence_mode/Activate(forced_state = null) - if(!owner || !chassis || chassis.occupant != owner) - return - if(!isnull(forced_state)) - chassis.defence_mode = forced_state - else - chassis.defence_mode = !chassis.defence_mode - button_icon_state = "mech_defense_mode_[chassis.defence_mode ? "on" : "off"]" - if(chassis.defence_mode) - chassis.deflect_chance = chassis.defence_mode_deflect_chance - chassis.occupant_message("You enable [chassis] defence mode.") - else - chassis.deflect_chance = initial(chassis.deflect_chance) - chassis.occupant_message("You disable [chassis] defence mode.") - chassis.log_message("Toggled defence mode.") - UpdateButtonIcon() - -/datum/action/innate/mecha/mech_overload_mode - name = "Toggle leg actuators overload" - button_icon_state = "mech_overload_off" - -/datum/action/innate/mecha/mech_overload_mode/Activate(forced_state = null) - if(!owner || !chassis || chassis.occupant != owner) - return - if(!isnull(forced_state)) - chassis.leg_overload_mode = forced_state - else - chassis.leg_overload_mode = !chassis.leg_overload_mode - button_icon_state = "mech_overload_[chassis.leg_overload_mode ? "on" : "off"]" - chassis.log_message("Toggled leg actuators overload.") - if(chassis.leg_overload_mode) - chassis.leg_overload_mode = 1 - chassis.bumpsmash = 1 - chassis.step_in = min(1, round(chassis.step_in/2)) - chassis.step_energy_drain = chassis.step_energy_drain*chassis.leg_overload_coeff - chassis.occupant_message("You enable leg actuators overload.") - else - chassis.leg_overload_mode = 0 - chassis.bumpsmash = 0 - chassis.step_in = initial(chassis.step_in) - chassis.step_energy_drain = initial(chassis.step_energy_drain) - chassis.occupant_message("You disable leg actuators overload.") - UpdateButtonIcon() - -/datum/action/innate/mecha/mech_smoke - name = "Smoke" - button_icon_state = "mech_smoke" - -/datum/action/innate/mecha/mech_smoke/Activate() - if(!owner || !chassis || chassis.occupant != owner) - return - if(chassis.smoke_ready && chassis.smoke>0) - chassis.smoke_system.start() - chassis.smoke-- - chassis.smoke_ready = 0 - spawn(chassis.smoke_cooldown) - chassis.smoke_ready = 1 - - -/datum/action/innate/mecha/mech_zoom - name = "Zoom" - button_icon_state = "mech_zoom_off" - -/datum/action/innate/mecha/mech_zoom/Activate() - if(!owner || !chassis || chassis.occupant != owner) - return - if(owner.client) - chassis.zoom_mode = !chassis.zoom_mode - button_icon_state = "mech_zoom_[chassis.zoom_mode ? "on" : "off"]" - chassis.log_message("Toggled zoom mode.") - chassis.occupant_message("Zoom mode [chassis.zoom_mode?"en":"dis"]abled.") - if(chassis.zoom_mode) - owner.client.view = 12 - owner << sound('sound/mecha/imag_enh.ogg',volume=50) - else - owner.client.view = world.view//world.view - default mob view size - UpdateButtonIcon() - -/datum/action/innate/mecha/mech_switch_damtype - name = "Reconfigure arm microtool arrays" - button_icon_state = "mech_damtype_brute" - -/datum/action/innate/mecha/mech_switch_damtype/Activate() - if(!owner || !chassis || chassis.occupant != owner) - return - var/new_damtype - switch(chassis.damtype) - if("tox") - new_damtype = "brute" - chassis.occupant_message("Your exosuit's hands form into fists.") - if("brute") - new_damtype = "fire" - chassis.occupant_message("A torch tip extends from your exosuit's hand, glowing red.") - if("fire") - new_damtype = "tox" - chassis.occupant_message("A bone-chillingly thick plasteel needle protracts from the exosuit's palm.") - chassis.damtype = new_damtype. - button_icon_state = "mech_damtype_[new_damtype]" - playsound(src, 'sound/mecha/mechmove01.ogg', 50, 1) - UpdateButtonIcon() - -/datum/action/innate/mecha/mech_toggle_phasing - name = "Toggle Phasing" - button_icon_state = "mech_phasing_off" - -/datum/action/innate/mecha/mech_toggle_phasing/Activate() - if(!owner || !chassis || chassis.occupant != owner) - return - chassis.phasing = !chassis.phasing - button_icon_state = "mech_phasing_[chassis.phasing ? "on" : "off"]" - chassis.occupant_message("En":"#f00\">Dis"]abled phasing.") - UpdateButtonIcon() + user.sight |= occupant_sight_flags \ No newline at end of file diff --git a/code/game/mecha/mecha_actions.dm b/code/game/mecha/mecha_actions.dm new file mode 100644 index 00000000000..869801152e4 --- /dev/null +++ b/code/game/mecha/mecha_actions.dm @@ -0,0 +1,281 @@ +//////////////////////////////////////// Action Buttons /////////////////////////////////////////////// + +/obj/mecha/proc/GrantActions(mob/living/user, human_occupant = 0) + if(human_occupant) + eject_action.Grant(user, src) + internals_action.Grant(user, src) + cycle_action.Grant(user, src) + lights_action.Grant(user, src) + stats_action.Grant(user, src) + strafing_action.Grant(user, src) + + +/obj/mecha/proc/RemoveActions(mob/living/user, human_occupant = 0) + if(human_occupant) + eject_action.Remove(user) + internals_action.Remove(user) + cycle_action.Remove(user) + lights_action.Remove(user) + stats_action.Remove(user) + strafing_action.Remove(user) + + +/datum/action/innate/mecha + check_flags = AB_CHECK_RESTRAINED | AB_CHECK_STUNNED | AB_CHECK_CONSCIOUS + var/obj/mecha/chassis + +/datum/action/innate/mecha/Grant(mob/living/L, obj/mecha/M) + chassis = M + ..() + +/datum/action/innate/mecha/Destroy() + chassis = null + return ..() + +/datum/action/innate/mecha/mech_eject + name = "Eject From Mech" + button_icon_state = "mech_eject" + +/datum/action/innate/mecha/mech_eject/Activate() + if(!owner || !iscarbon(owner)) + return + if(!chassis || chassis.occupant != owner) + return + chassis.go_out() + + +/datum/action/innate/mecha/mech_toggle_internals + name = "Toggle Internal Airtank Usage" + button_icon_state = "mech_internals_off" + +/datum/action/innate/mecha/mech_toggle_internals/Activate() + if(!owner || !chassis || chassis.occupant != owner) + return + chassis.use_internal_tank = !chassis.use_internal_tank + button_icon_state = "mech_internals_[chassis.use_internal_tank ? "on" : "off"]" + chassis.occupant_message("Now taking air from [chassis.use_internal_tank?"internal airtank":"environment"].") + chassis.log_message("Now taking air from [chassis.use_internal_tank?"internal airtank":"environment"].") + UpdateButtonIcon() + +/datum/action/innate/mecha/mech_cycle_equip + name = "Cycle Equipment" + button_icon_state = "mech_cycle_equip_off" + +/datum/action/innate/mecha/mech_cycle_equip/Activate() + if(!owner || !chassis || chassis.occupant != owner) + return + + var/list/available_equipment = list() + for(var/obj/item/mecha_parts/mecha_equipment/M in chassis.equipment) + if(M.selectable) + available_equipment += M + + if(available_equipment.len == 0) + chassis.occupant_message("No equipment available.") + return + if(!chassis.selected) + chassis.selected = available_equipment[1] + chassis.occupant_message("You select [chassis.selected]") + send_byjax(chassis.occupant,"exosuit.browser","eq_list",chassis.get_equipment_list()) + button_icon_state = "mech_cycle_equip_on" + UpdateButtonIcon() + return + var/number = 0 + for(var/A in available_equipment) + number++ + if(A == chassis.selected) + if(available_equipment.len == number) + chassis.selected = null + chassis.occupant_message("You switch to no equipment") + button_icon_state = "mech_cycle_equip_off" + else + chassis.selected = available_equipment[number+1] + chassis.occupant_message("You switch to [chassis.selected]") + button_icon_state = "mech_cycle_equip_on" + send_byjax(chassis.occupant,"exosuit.browser","eq_list",chassis.get_equipment_list()) + UpdateButtonIcon() + return + + +/datum/action/innate/mecha/mech_toggle_lights + name = "Toggle Lights" + button_icon_state = "mech_lights_off" + +/datum/action/innate/mecha/mech_toggle_lights/Activate() + if(!owner || !chassis || chassis.occupant != owner) + return + chassis.lights = !chassis.lights + if(chassis.lights) + chassis.AddLuminosity(chassis.lights_power) + button_icon_state = "mech_lights_on" + else + chassis.AddLuminosity(-chassis.lights_power) + button_icon_state = "mech_lights_off" + chassis.occupant_message("Toggled lights [chassis.lights?"on":"off"].") + chassis.log_message("Toggled lights [chassis.lights?"on":"off"].") + UpdateButtonIcon() + +/datum/action/innate/mecha/mech_view_stats + name = "View Stats" + button_icon_state = "mech_view_stats" + +/datum/action/innate/mecha/mech_view_stats/Activate() + if(!owner || !chassis || chassis.occupant != owner) + return + chassis.occupant << browse(chassis.get_stats_html(), "window=exosuit") + + +/datum/action/innate/mecha/strafe + name = "Toggle Strafing" + button_icon_state = "strafe" + +/datum/action/innate/mecha/strafe/Activate() + if(!owner || !chassis || chassis.occupant != owner) + return + + chassis.toggle_strafe() + +/obj/mecha/AltClick(mob/living/user) + if(user == occupant) + toggle_strafe() + +/obj/mecha/proc/toggle_strafe() + strafe = !strafe + + occupant_message("Toggled strafing mode [strafe?"on":"off"].") + log_message("Toggled strafing mode [strafe?"on":"off"].") + strafing_action.UpdateButtonIcon() + +//////////////////////////////////////// Specific Ability Actions /////////////////////////////////////////////// +//Need to be granted by the mech type, Not default abilities. + +/datum/action/innate/mecha/mech_toggle_thrusters + name = "Toggle Thrusters" + button_icon_state = "mech_thrusters_off" + +/datum/action/innate/mecha/mech_toggle_thrusters/Activate() + if(!owner || !chassis || chassis.occupant != owner) + return + if(chassis.get_charge() > 0) + chassis.thrusters_active = !chassis.thrusters_active + button_icon_state = "mech_thrusters_[chassis.thrusters_active ? "on" : "off"]" + chassis.log_message("Toggled thrusters.") + chassis.occupant_message("Thrusters [chassis.thrusters_active ?"en":"dis"]abled.") + + +/datum/action/innate/mecha/mech_defence_mode + name = "Toggle Defence Mode" + button_icon_state = "mech_defense_mode_off" + +/datum/action/innate/mecha/mech_defence_mode/Activate(forced_state = null) + if(!owner || !chassis || chassis.occupant != owner) + return + if(!isnull(forced_state)) + chassis.defence_mode = forced_state + else + chassis.defence_mode = !chassis.defence_mode + button_icon_state = "mech_defense_mode_[chassis.defence_mode ? "on" : "off"]" + if(chassis.defence_mode) + chassis.deflect_chance = chassis.defence_mode_deflect_chance + chassis.occupant_message("You enable [chassis] defence mode.") + else + chassis.deflect_chance = initial(chassis.deflect_chance) + chassis.occupant_message("You disable [chassis] defence mode.") + chassis.log_message("Toggled defence mode.") + UpdateButtonIcon() + +/datum/action/innate/mecha/mech_overload_mode + name = "Toggle leg actuators overload" + button_icon_state = "mech_overload_off" + +/datum/action/innate/mecha/mech_overload_mode/Activate(forced_state = null) + if(!owner || !chassis || chassis.occupant != owner) + return + if(!isnull(forced_state)) + chassis.leg_overload_mode = forced_state + else + chassis.leg_overload_mode = !chassis.leg_overload_mode + button_icon_state = "mech_overload_[chassis.leg_overload_mode ? "on" : "off"]" + chassis.log_message("Toggled leg actuators overload.") + if(chassis.leg_overload_mode) + chassis.leg_overload_mode = 1 + chassis.bumpsmash = 1 + chassis.step_in = min(1, round(chassis.step_in/2)) + chassis.step_energy_drain = chassis.step_energy_drain*chassis.leg_overload_coeff + chassis.occupant_message("You enable leg actuators overload.") + else + chassis.leg_overload_mode = 0 + chassis.bumpsmash = 0 + chassis.step_in = initial(chassis.step_in) + chassis.step_energy_drain = initial(chassis.step_energy_drain) + chassis.occupant_message("You disable leg actuators overload.") + UpdateButtonIcon() + +/datum/action/innate/mecha/mech_smoke + name = "Smoke" + button_icon_state = "mech_smoke" + +/datum/action/innate/mecha/mech_smoke/Activate() + if(!owner || !chassis || chassis.occupant != owner) + return + if(chassis.smoke_ready && chassis.smoke>0) + chassis.smoke_system.start() + chassis.smoke-- + chassis.smoke_ready = 0 + spawn(chassis.smoke_cooldown) + chassis.smoke_ready = 1 + + +/datum/action/innate/mecha/mech_zoom + name = "Zoom" + button_icon_state = "mech_zoom_off" + +/datum/action/innate/mecha/mech_zoom/Activate() + if(!owner || !chassis || chassis.occupant != owner) + return + if(owner.client) + chassis.zoom_mode = !chassis.zoom_mode + button_icon_state = "mech_zoom_[chassis.zoom_mode ? "on" : "off"]" + chassis.log_message("Toggled zoom mode.") + chassis.occupant_message("Zoom mode [chassis.zoom_mode?"en":"dis"]abled.") + if(chassis.zoom_mode) + owner.client.view = 12 + owner << sound('sound/mecha/imag_enh.ogg',volume=50) + else + owner.client.view = world.view//world.view - default mob view size + UpdateButtonIcon() + +/datum/action/innate/mecha/mech_switch_damtype + name = "Reconfigure arm microtool arrays" + button_icon_state = "mech_damtype_brute" + +/datum/action/innate/mecha/mech_switch_damtype/Activate() + if(!owner || !chassis || chassis.occupant != owner) + return + var/new_damtype + switch(chassis.damtype) + if("tox") + new_damtype = "brute" + chassis.occupant_message("Your exosuit's hands form into fists.") + if("brute") + new_damtype = "fire" + chassis.occupant_message("A torch tip extends from your exosuit's hand, glowing red.") + if("fire") + new_damtype = "tox" + chassis.occupant_message("A bone-chillingly thick plasteel needle protracts from the exosuit's palm.") + chassis.damtype = new_damtype. + button_icon_state = "mech_damtype_[new_damtype]" + playsound(src, 'sound/mecha/mechmove01.ogg', 50, 1) + UpdateButtonIcon() + +/datum/action/innate/mecha/mech_toggle_phasing + name = "Toggle Phasing" + button_icon_state = "mech_phasing_off" + +/datum/action/innate/mecha/mech_toggle_phasing/Activate() + if(!owner || !chassis || chassis.occupant != owner) + return + chassis.phasing = !chassis.phasing + button_icon_state = "mech_phasing_[chassis.phasing ? "on" : "off"]" + chassis.occupant_message("En":"#f00\">Dis"]abled phasing.") + UpdateButtonIcon() diff --git a/code/game/mecha/mecha_defense.dm b/code/game/mecha/mecha_defense.dm index 6c6ecde299b..4cef3720702 100644 --- a/code/game/mecha/mecha_defense.dm +++ b/code/game/mecha/mecha_defense.dm @@ -1,7 +1,7 @@ /obj/mecha/proc/get_armour_facing(srcdir,adir) var/facing_hit = armour_facings["[srcdir]"]["[adir]"] var/damage_modifier = facing_modifiers[facing_hit] - return damage_modifier + return damage_modifier || 1 //always return non-0 /obj/mecha/proc/take_damage(amount, type="brute", adir = 0, booster_deflection_modifier = 1, booster_damage_modifier = 1) var/facing_modifier = 1 diff --git a/code/game/mecha/mecha_topic.dm b/code/game/mecha/mecha_topic.dm index a04693ce20f..8084c64a43d 100644 --- a/code/game/mecha/mecha_topic.dm +++ b/code/game/mecha/mecha_topic.dm @@ -52,12 +52,12 @@ /obj/mecha/proc/report_internal_damage() . = "" var/list/dam_reports = list( - "[MECHA_INT_FIRE]" = "INTERNAL FIRE", - "[MECHA_INT_TEMP_CONTROL]" = "LIFE SUPPORT SYSTEM MALFUNCTION", - "[MECHA_INT_TANK_BREACH]" = "GAS TANK BREACH", - "[MECHA_INT_CONTROL_LOST]" = "COORDINATION SYSTEM CALIBRATION FAILURE - Recalibrate", - "[MECHA_INT_SHORT_CIRCUIT]" = "SHORT CIRCUIT" - ) + "[MECHA_INT_FIRE]" = "INTERNAL FIRE", + "[MECHA_INT_TEMP_CONTROL]" = "LIFE SUPPORT SYSTEM MALFUNCTION", + "[MECHA_INT_TANK_BREACH]" = "GAS TANK BREACH", + "[MECHA_INT_CONTROL_LOST]" = "COORDINATION SYSTEM CALIBRATION FAILURE - Recalibrate", + "[MECHA_INT_SHORT_CIRCUIT]" = "SHORT CIRCUIT" + ) for(var/tflag in dam_reports) var/intdamflag = text2num(tflag) if(internal_damage & intdamflag) @@ -176,7 +176,8 @@ var/a_name = get_access_desc(a) if(!a_name) continue //there's some strange access without a name . += "[a_name] - Add
" - . += "
Finish (Warning! The ID upload panel will be locked. It can be unlocked only through Exosuit Interface.)" + . += "
Finish " + . += "(Warning! The ID upload panel will be locked. It can be unlocked only through Exosuit Interface.)" . += "" user << browse(., "window=exosuit_add_access") onclose(user, "exosuit_add_access") @@ -262,7 +263,7 @@ if(href_list["select_equip"]) var/obj/item/mecha_parts/mecha_equipment/equip = filter.getObj("select_equip") - if(equip) + if(equip && equip.selectable) src.selected = equip src.occupant_message("You switch to [equip]") src.visible_message("[src] raises [equip]") diff --git a/code/game/objects/effects/decals/misc.dm b/code/game/objects/effects/decals/misc.dm index 0a627518e15..99f894aa392 100644 --- a/code/game/objects/effects/decals/misc.dm +++ b/code/game/objects/effects/decals/misc.dm @@ -5,8 +5,11 @@ layer = 16 duration = 25 -/obj/effect/overlay/temp/point/New(loc, set_invis = 0) +/obj/effect/overlay/temp/point/New(atom/target, set_invis = 0) ..() + loc = get_turf(target) + pixel_x = target.pixel_x + pixel_y = target.pixel_y invisibility = set_invis // Used for spray that you spray at walls, tables, hydrovats etc diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index bd0425a9239..1c66b00f13e 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -247,8 +247,8 @@ var/global/image/fire_overlay = image("icon" = 'icons/effects/fire.dmi', "icon_s user << "You put out the fire on [src]." else user << "You burn your hand on [src]!" - var/obj/item/organ/limb/affecting = H.get_organ("[user.hand ? "l" : "r" ]_arm") - if(affecting.take_damage( 0, 5 )) // 5 burn damage + var/obj/item/bodypart/affecting = H.get_bodypart("[user.hand ? "l" : "r" ]_arm") + if(affecting && affecting.take_damage( 0, 5 )) // 5 burn damage H.update_damage_overlays(0) H.updatehealth() return @@ -427,7 +427,10 @@ obj/item/proc/item_action_slot_check(slot, mob/user) /obj/item/proc/eyestab(mob/living/carbon/M, mob/living/carbon/user) var/is_human_victim = 0 + var/obj/item/bodypart/affecting = M.get_bodypart("head") if(ishuman(M)) + if(!affecting) //no head! + return is_human_victim = 1 var/mob/living/carbon/human/H = M if((H.head && H.head.flags_cover & HEADCOVERSEYES) || \ @@ -467,7 +470,6 @@ obj/item/proc/item_action_slot_check(slot, mob/user) ) if(is_human_victim) var/mob/living/carbon/human/U = M - var/obj/item/organ/limb/affecting = U.get_organ("head") if(affecting.take_damage(7)) U.update_damage_overlays(0) @@ -572,3 +574,6 @@ obj/item/proc/item_action_slot_check(slot, mob/user) /obj/item/proc/is_sharp() return sharpness + +/obj/item/proc/can_dismember() + return sharpness && w_class >= 3 \ No newline at end of file diff --git a/code/game/objects/items/blueprints.dm b/code/game/objects/items/blueprints.dm index efb3b8c1635..56e99c069fd 100644 --- a/code/game/objects/items/blueprints.dm +++ b/code/game/objects/items/blueprints.dm @@ -337,3 +337,14 @@ found += U found |= F return found + + + +//Blueprint Subtypes + +/obj/item/areaeditor/blueprints/cyborg + name = "station schematics" + desc = "A digital copy of the station blueprints stored in your memory." + icon = 'icons/obj/items.dmi' + icon_state = "blueprints" + fluffnotice = "Intellectual Property of Nanotrasen. For use in engineering cyborgs only. Wipe from memory upon departure from the station." \ No newline at end of file diff --git a/code/game/objects/items/body_egg.dm b/code/game/objects/items/body_egg.dm index 1e84a7556d8..fb786dcf52a 100644 --- a/code/game/objects/items/body_egg.dm +++ b/code/game/objects/items/body_egg.dm @@ -1,4 +1,4 @@ -/obj/item/organ/internal/body_egg +/obj/item/organ/body_egg name = "body egg" desc = "All slimy and yuck." icon_state = "innards" @@ -6,16 +6,16 @@ zone = "chest" slot = "parasite_egg" -/obj/item/organ/internal/body_egg/on_find(mob/living/finder) +/obj/item/organ/body_egg/on_find(mob/living/finder) ..() finder << "You found an unknown alien organism in [owner]'s [zone]!" -/obj/item/organ/internal/body_egg/New(loc) +/obj/item/organ/body_egg/New(loc) if(iscarbon(loc)) src.Insert(loc) return ..() -/obj/item/organ/internal/body_egg/Insert(var/mob/living/carbon/M, special = 0) +/obj/item/organ/body_egg/Insert(var/mob/living/carbon/M, special = 0) ..() owner.status_flags |= XENO_HOST SSobj.processing |= src @@ -23,7 +23,7 @@ spawn(0) AddInfectionImages(owner) -/obj/item/organ/internal/body_egg/Remove(var/mob/living/carbon/M, special = 0) +/obj/item/organ/body_egg/Remove(var/mob/living/carbon/M, special = 0) SSobj.processing.Remove(src) if(owner) owner.status_flags &= ~(XENO_HOST) @@ -32,7 +32,7 @@ RemoveInfectionImages(owner) ..() -/obj/item/organ/internal/body_egg/process() +/obj/item/organ/body_egg/process() if(!owner) return if(!(src in owner.internal_organs)) @@ -40,15 +40,15 @@ return egg_process() -/obj/item/organ/internal/body_egg/proc/egg_process() +/obj/item/organ/body_egg/proc/egg_process() return -/obj/item/organ/internal/body_egg/proc/RefreshInfectionImage() +/obj/item/organ/body_egg/proc/RefreshInfectionImage() RemoveInfectionImages() AddInfectionImages() -/obj/item/organ/internal/body_egg/proc/AddInfectionImages() +/obj/item/organ/body_egg/proc/AddInfectionImages() return -/obj/item/organ/internal/body_egg/proc/RemoveInfectionImages() +/obj/item/organ/body_egg/proc/RemoveInfectionImages() return \ No newline at end of file diff --git a/code/game/objects/items/crayons.dm b/code/game/objects/items/crayons.dm index 1e22c43a028..c101d2fbb61 100644 --- a/code/game/objects/items/crayons.dm +++ b/code/game/objects/items/crayons.dm @@ -195,15 +195,22 @@ if(C.client) C.blur_eyes(3) C.blind_eyes(1) - if(C.check_eye_prot() <= 0) // no eye protection? ARGH IT BURNS. - C.confused = max(C.confused, 3) - C.Weaken(3) + if(C.check_eye_prot() <= 0) // no eye protection? ARGH IT BURNS. + C.confused = max(C.confused, 3) + C.Weaken(3) if(ishuman(C)) var/mob/living/carbon/human/H = C H.lip_style = "spray_face" H.lip_color = paint_color H.update_body() + // Caution, spray cans contain inflammable substances + if(C.reagents) + C.reagents.add_reagent("welding_fuel", 5) + C.reagents.add_reagent("ethanol", 5) + C.reagents.reaction(C, VAPOR, 10) + uses = max(0,uses-10) + if(istype(target, /obj/structure/window)) if(uses) target.color = paint_color @@ -232,4 +239,27 @@ ..() if(G) paint_color = G.color_hex - update_icon() \ No newline at end of file + update_icon() + +/obj/item/toy/crayon/spraycan/borg + desc = "A metallic container containing shiny paint." + // Use depletion of uses to determine what the energy cost is + uses = 100 + +/obj/item/toy/crayon/spraycan/borg/afterattack(atom/target,mob/user,proximity) + ..() + if(!isrobot(user)) + return FALSE + var/mob/living/silicon/robot/borgy = user + + var/starting_uses = initial(uses) + var/diff = starting_uses - uses + if(diff) + uses = starting_uses + // 25 is our cost per unit of paint, making it cost 25 energy per + // normal tag, 50 per window, and 250 per attack + var/cost = diff * 25 + // Cyborgs shouldn't be able to use modules without a cell. But if they do + // it's free. + if(borgy.cell) + borgy.cell.use(cost) diff --git a/code/game/objects/items/dehy_carp.dm b/code/game/objects/items/dehy_carp.dm index 0b20a76264e..48cf67cc93b 100644 --- a/code/game/objects/items/dehy_carp.dm +++ b/code/game/objects/items/dehy_carp.dm @@ -7,6 +7,7 @@ /obj/item/toy/carpplushie/dehy_carp var/mob/owner = null //Carp doesn't attack owner, set when using in hand var/owned = 0 //Boolean, no owner to begin with + var/mobtype = /mob/living/simple_animal/hostile/carp //So admins can change what mob spawns via var fuckery //Attack self /obj/item/toy/carpplushie/dehy_carp/attack_self(mob/user) @@ -36,16 +37,16 @@ //Wait for animation to end sleep(6) //Make space carp - var/mob/living/simple_animal/hostile/carp/C = new /mob/living/simple_animal/hostile/carp(get_turf(src)) + var/mob/living/M = new mobtype(get_turf(src)) //Make carp non-hostile to user, and their allies if(owner) var/list/factions = owner.faction for(var/F in factions) if(F == "neutral") factions -= F - C.faction = factions - if (!owner || owner.faction != C.faction) + M.faction = factions + if (!owner || owner.faction != M.faction) visible_message("You have a bad feeling about this.") //welcome to the hostile carp enjoy your die else - visible_message("The newly grown carp looks up at you with friendly eyes.") + visible_message("The newly grown [M.name] looks up at you with friendly eyes.") qdel(src) \ No newline at end of file diff --git a/code/game/objects/items/devices/laserpointer.dm b/code/game/objects/items/devices/laserpointer.dm index 6ec1518cd18..8390649eaa2 100644 --- a/code/game/objects/items/devices/laserpointer.dm +++ b/code/game/objects/items/devices/laserpointer.dm @@ -71,7 +71,7 @@ return if(ishuman(user)) var/mob/living/carbon/human/H = user - if(H.dna.check_mutation(HULK) || NOGUNS in H.dna.species.specflags) + if(H.dna.check_mutation(HULK) || (NOGUNS in H.dna.species.specflags)) user << "Your fingers can't press the button!" return diff --git a/code/game/objects/items/devices/paicard.dm b/code/game/objects/items/devices/paicard.dm index cd473f590e7..6f989a92ac6 100644 --- a/code/game/objects/items/devices/paicard.dm +++ b/code/game/objects/items/devices/paicard.dm @@ -107,6 +107,9 @@ src.pai = personality src.overlays += "pai-null" + playsound(loc, 'sound/effects/pai_boot.ogg', 50, 1, -1) + audible_message("\The [src] plays a cheerful startup noise!") + /obj/item/device/paicard/proc/removePersonality() src.pai = null src.overlays.Cut() diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm index 7b1fa5d630e..798a8ce3614 100644 --- a/code/game/objects/items/devices/scanners.dm +++ b/code/game/objects/items/devices/scanners.dm @@ -148,7 +148,7 @@ MASS SPECTROMETER user << "\tSubject appears to have [M.getCloneLoss() > 30 ? "severe" : "minor"] cellular damage." if (M.reagents && M.reagents.get_reagent_amount("epinephrine")) user << "\tBloodstream analysis located [M.reagents:get_reagent_amount("epinephrine")] units of rejuvenation chemicals." - if (M.getBrainLoss() >= 100 || !M.getorgan(/obj/item/organ/internal/brain)) + if (M.getBrainLoss() >= 100 || !M.getorgan(/obj/item/organ/brain)) user << "\tSubject brain function is non-existant." else if (M.getBrainLoss() >= 60) user << "\tSevere brain damage detected. Subject likely to have mental retardation." @@ -158,11 +158,11 @@ MASS SPECTROMETER // Organ damage report if(istype(M, /mob/living/carbon/human) && mode == 1) var/mob/living/carbon/human/H = M - var/list/damaged = H.get_damaged_organs(1,1) + var/list/damaged = H.get_damaged_bodyparts(1,1) if(length(damaged)>0 || oxy_loss>0 || tox_loss>0 || fire_loss>0) user << "\tDamage: Brute-Burn-Toxin-Suffocation\n\t\tSpecifics: [brute_loss]-[fire_loss]-[tox_loss]-[oxy_loss]" - for(var/obj/item/organ/limb/org in damaged) - user << "\t\t[capitalize(org.getDisplayName())]: [(org.brute_dam > 0) ? "[org.brute_dam]" : "0"]-[(org.burn_dam > 0) ? "[org.burn_dam]" : "0"]" + for(var/obj/item/bodypart/org in damaged) + user << "\t\t[capitalize(org.name)]: [(org.brute_dam > 0) ? "[org.brute_dam]" : "0"]-[(org.burn_dam > 0) ? "[org.burn_dam]" : "0"]" // Species and body temperature if(ishuman(M)) @@ -196,7 +196,7 @@ MASS SPECTROMETER user << "Blood level [blood_percent] %, [blood_volume] cl, type: [blood_type]" var/implant_detect - for(var/obj/item/organ/internal/cyberimp/CI in H.internal_organs) + for(var/obj/item/organ/cyberimp/CI in H.internal_organs) if(CI.status == ORGAN_ROBOTIC) implant_detect += "[H.name] is modified with a [CI.name].
" if(implant_detect) diff --git a/code/game/objects/items/robot/robot_parts.dm b/code/game/objects/items/robot/robot_parts.dm index 3be12d0b94f..42e6d7f7280 100644 --- a/code/game/objects/items/robot/robot_parts.dm +++ b/code/game/objects/items/robot/robot_parts.dm @@ -5,31 +5,37 @@ icon_state = "blank" flags = CONDUCT slot_flags = SLOT_BELT + var/body_zone /obj/item/robot_parts/l_arm name = "cyborg left arm" desc = "A skeletal limb wrapped in pseudomuscles, with a low-conductivity case." icon_state = "l_arm" + body_zone = "l_arm" /obj/item/robot_parts/r_arm name = "cyborg right arm" desc = "A skeletal limb wrapped in pseudomuscles, with a low-conductivity case." icon_state = "r_arm" + body_zone = "r_arm" /obj/item/robot_parts/l_leg name = "cyborg left leg" desc = "A skeletal limb wrapped in pseudomuscles, with a low-conductivity case." icon_state = "l_leg" + body_zone = "l_leg" /obj/item/robot_parts/r_leg name = "cyborg right leg" desc = "A skeletal limb wrapped in pseudomuscles, with a low-conductivity case." icon_state = "r_leg" + body_zone = "r_leg" /obj/item/robot_parts/chest name = "cyborg torso" desc = "A heavily reinforced case containing cyborg logic boards, with space for a standard power cell." icon_state = "chest" + body_zone = "chest" var/wired = 0 var/obj/item/weapon/stock_parts/cell/cell = null @@ -37,6 +43,7 @@ name = "cyborg head" desc = "A standard reinforced braincase, with spine-plugged neural socket and sensor gimbals." icon_state = "head" + body_zone = "head" var/obj/item/device/assembly/flash/handheld/flash1 = null var/obj/item/device/assembly/flash/handheld/flash2 = null diff --git a/code/game/objects/items/stacks/medical.dm b/code/game/objects/items/stacks/medical.dm index b1938b51325..eb1a1d7abd0 100644 --- a/code/game/objects/items/stacks/medical.dm +++ b/code/game/objects/items/stacks/medical.dm @@ -29,8 +29,13 @@ user << "You don't know how to apply \the [src] to [M]!" return 1 + var/obj/item/bodypart/affecting if(ishuman(M)) var/mob/living/carbon/human/H = M + affecting = H.get_bodypart(check_zone(user.zone_selected)) + if(!affecting) //Missing limb? + user << "[H] doesn't have \a [parse_zone(user.zone_selected)]!" + return if(stop_bleeding) if(H.bleedsuppress) user << "[H]'s bleeding is already bandaged!" @@ -39,6 +44,7 @@ user << "[H] isn't bleeding!" return + if(isliving(M)) if(!M.can_inject(user, 1)) return @@ -71,7 +77,10 @@ if(ishuman(M)) var/mob/living/carbon/human/H = M - var/obj/item/organ/limb/affecting = H.get_organ(check_zone(user.zone_selected)) + affecting = H.get_bodypart(check_zone(user.zone_selected)) + if(!affecting) //Missing limb? + user << "[H] doesn't have \a [parse_zone(user.zone_selected)]!" + return if(stop_bleeding) if(!H.bleedsuppress) //so you can't stack bleed suppression H.suppress_bloodloss(stop_bleeding) diff --git a/code/game/objects/items/stacks/sheets/glass.dm b/code/game/objects/items/stacks/sheets/glass.dm index 3e12f0d4954..3e9329e541d 100644 --- a/code/game/objects/items/stacks/sheets/glass.dm +++ b/code/game/objects/items/stacks/sheets/glass.dm @@ -317,8 +317,8 @@ if(!H.gloves && !(PIERCEIMMUNE in H.dna.species.specflags)) // golems, etc H << "[src] cuts into your hand!" var/organ = (H.hand ? "l_" : "r_") + "arm" - var/obj/item/organ/limb/affecting = H.get_organ(organ) - if(affecting.take_damage(force / 2)) + var/obj/item/bodypart/affecting = H.get_bodypart(organ) + if(affecting && affecting.take_damage(force / 2)) H.update_damage_overlays(0) else if(ismonkey(user)) var/mob/living/carbon/monkey/M = user @@ -348,9 +348,13 @@ if(ishuman(AM)) var/mob/living/carbon/human/H = AM if(PIERCEIMMUNE in H.dna.species.specflags) - return 0 + return + var/picked_def_zone = pick("l_leg", "r_leg") + var/obj/item/bodypart/O = H.get_bodypart(picked_def_zone) + if(!istype(O)) + return if(!H.shoes) - H.apply_damage(5,BRUTE,(pick("l_leg", "r_leg"))) + H.apply_damage(5, BRUTE, picked_def_zone) H.Weaken(3) if(cooldown < world.time - 10) //cooldown to avoid message spam. H.visible_message("[H] steps in the broken glass!", \ diff --git a/code/game/objects/items/stacks/sheets/leather.dm b/code/game/objects/items/stacks/sheets/leather.dm index 537b1646462..f2b9bcd472b 100644 --- a/code/game/objects/items/stacks/sheets/leather.dm +++ b/code/game/objects/items/stacks/sheets/leather.dm @@ -157,6 +157,16 @@ var/global/list/datum/stack_recipe/sinew_recipes = list ( \ w_class = 3 layer = 4 +/obj/item/stack/sheet/animalhide/ashdrake + name = "ash drake hide" + desc = "The strong, scaled hide of an ash drake." + icon = 'icons/obj/mining.dmi' + icon_state = "dragon_hide" + singular_name = "drake plate" + flags = NOBLUDGEON + w_class = 3 + layer = 4 + //Step one - dehairing. diff --git a/code/game/objects/items/stacks/sheets/sheet_types.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm index 6c9b9254103..a12c51ed506 100644 --- a/code/game/objects/items/stacks/sheets/sheet_types.dm +++ b/code/game/objects/items/stacks/sheets/sheet_types.dm @@ -42,6 +42,7 @@ var/global/list/datum/stack_recipe/metal_recipes = list ( \ new/datum/stack_recipe("apc frame", /obj/item/wallframe/apc, 2), \ new/datum/stack_recipe("air alarm frame", /obj/item/wallframe/airalarm, 2), \ new/datum/stack_recipe("fire alarm frame", /obj/item/wallframe/firealarm, 2), \ + new/datum/stack_recipe("extinguisher cabinet frame", /obj/item/wallframe/extinguisher_cabinet, 2), \ new/datum/stack_recipe("button frame", /obj/item/wallframe/button, 1), \ null, \ new/datum/stack_recipe("iron door", /obj/structure/mineral_door/iron, 20, one_per_turf = 1, on_floor = 1), \ diff --git a/code/game/objects/items/weapons/RSF.dm b/code/game/objects/items/weapons/RSF.dm index 0ec9b84479c..ba891f89d78 100644 --- a/code/game/objects/items/weapons/RSF.dm +++ b/code/game/objects/items/weapons/RSF.dm @@ -6,7 +6,7 @@ RSF /obj/item/weapon/rsf name = "\improper Rapid-Service-Fabricator" desc = "A device used to rapidly deploy service items." - icon = 'icons/obj/items.dmi' + icon = 'icons/obj/tools.dmi' icon_state = "rcd" opacity = 0 density = 0 @@ -111,4 +111,4 @@ RSF else matter-- user << "The RSF now holds [matter]/30 fabrication-units." - desc = "A RSF. It currently holds [matter]/30 fabrication-units." \ No newline at end of file + desc = "A RSF. It currently holds [matter]/30 fabrication-units." diff --git a/code/game/objects/items/weapons/airlock_painter.dm b/code/game/objects/items/weapons/airlock_painter.dm index abdc6c16e78..8dcd492ef28 100644 --- a/code/game/objects/items/weapons/airlock_painter.dm +++ b/code/game/objects/items/weapons/airlock_painter.dm @@ -42,7 +42,7 @@ return 1 /obj/item/weapon/airlock_painter/suicide_act(mob/user) - var/obj/item/organ/internal/lungs/L = user.getorganslot("lungs") + var/obj/item/organ/lungs/L = user.getorganslot("lungs") if(can_use(user) && L) user.visible_message("[user] is inhaling toner from \the [name]! It looks like \he's trying to commit suicide.") diff --git a/code/game/objects/items/weapons/cosmetics.dm b/code/game/objects/items/weapons/cosmetics.dm index 382bc1cb7ed..8ed86c391dc 100644 --- a/code/game/objects/items/weapons/cosmetics.dm +++ b/code/game/objects/items/weapons/cosmetics.dm @@ -124,7 +124,7 @@ var/mob/living/carbon/human/H = M var/location = user.zone_selected if(location == "mouth") - if(!(H.dna.species.specflags & FACEHAIR)) + if(!(FACEHAIR in H.dna.species.specflags)) user << "There is no facial hair to shave!" return if(!get_location_accessible(H, location)) @@ -152,7 +152,7 @@ shave(H, location) else if(location == "head") - if(!(H.dna.species.specflags & HAIR)) + if(!(HAIR in H.dna.species.specflags)) user << "There is no hair to shave!" return if(!get_location_accessible(H, location)) diff --git a/code/game/objects/items/weapons/defib.dm b/code/game/objects/items/weapons/defib.dm index bc8aec98766..9e5ecd557b7 100644 --- a/code/game/objects/items/weapons/defib.dm +++ b/code/game/objects/items/weapons/defib.dm @@ -499,14 +499,14 @@ failed = "[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - Recovery of patient impossible. Further attempts futile." else if (tplus > tlimit) failed = "[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - Body has decayed for too long. Further attempts futile." - else if (!H.getorgan(/obj/item/organ/internal/heart)) + else if (!H.getorgan(/obj/item/organ/heart)) failed = "[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - Patient's heart is missing." else if(total_burn >= 180 || total_brute >= 180) failed = "[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - Severe tissue damage makes recovery of patient impossible via defibrillator. Further attempts futile." else if(H.get_ghost()) failed = "[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - No activity in patient's brain. Further attempts may be successful." else - var/obj/item/organ/internal/brain/BR = H.getorgan(/obj/item/organ/internal/brain) + var/obj/item/organ/brain/BR = H.getorgan(/obj/item/organ/brain) if(!BR || BR.damaged_brain) failed = "[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - Patient's brain is missing or damaged beyond point of no return. Further attempts futile." diff --git a/code/game/objects/items/weapons/explosives.dm b/code/game/objects/items/weapons/explosives.dm index 00da8edcade..1b784656308 100644 --- a/code/game/objects/items/weapons/explosives.dm +++ b/code/game/objects/items/weapons/explosives.dm @@ -4,20 +4,19 @@ name = "C-4" desc = "Used to put holes in specific areas without too much extra hole." gender = PLURAL - icon = 'icons/obj/assemblies.dmi' + icon = 'icons/obj/grenade.dmi' icon_state = "plastic-explosive0" item_state = "plasticx" flags = NOBLUDGEON w_class = 2 origin_tech = "syndicate=2" var/timer = 10 - var/atom/target = null var/open_panel = 0 - var/image_overlay = null + parent_type = /obj/item/weapon/grenade/plastic/c4 /obj/item/weapon/c4/New() wires = new /datum/wires/explosive/c4(src) - image_overlay = image('icons/obj/assemblies.dmi', "plastic-explosive2") + image_overlay = image('icons/obj/grenade.dmi', "plastic-explosive2") ..() /obj/item/weapon/c4/Destroy() diff --git a/code/game/objects/items/weapons/grenades/chem_grenade.dm b/code/game/objects/items/weapons/grenades/chem_grenade.dm index 54c322dee79..e7d18f91de5 100644 --- a/code/game/objects/items/weapons/grenades/chem_grenade.dm +++ b/code/game/objects/items/weapons/grenades/chem_grenade.dm @@ -267,13 +267,15 @@ var/total_volume = 0 for(var/obj/item/weapon/reagent_containers/RC in beakers) total_volume += RC.reagents.total_volume - + if(!total_volume) + qdel(src) + qdel(nadeassembly) + return var/fraction = unit_spread/total_volume var/datum/reagents/reactants = new(unit_spread) reactants.my_atom = src for(var/obj/item/weapon/reagent_containers/RC in beakers) RC.reagents.trans_to(reactants, RC.reagents.total_volume*fraction, threatscale, 1, 1) - chem_splash(get_turf(src), affected_area, list(reactants), ignition_temp, threatscale) if(nadeassembly) @@ -283,15 +285,12 @@ var/area/A = get_area(T) message_admins("grenade primed by an assembly, attached by [key_name_admin(M)](?) (FLW) and last touched by [key_name_admin(last)](?) (FLW) ([nadeassembly.a_left.name] and [nadeassembly.a_right.name]) at [A.name] (JMP).") log_game("grenade primed by an assembly, attached by [key_name(M)] and last touched by [key_name(last)] ([nadeassembly.a_left.name] and [nadeassembly.a_right.name]) at [A.name] ([T.x], [T.y], [T.z])") - + else + addtimer(src, "prime", det_time) var/turf/DT = get_turf(src) var/area/DA = get_area(DT) log_game("A grenade detonated at [DA.name] ([DT.x], [DT.y], [DT.z])") - if(total_volume < unit_spread) // If that was the last detonation, delete the grenade to prevent reusing it. Keep in mind, an explosion might destroy the grenade before it can detonate again anyways. - update_mob() - qdel(src) - diff --git a/code/game/objects/items/weapons/grenades/plastic.dm b/code/game/objects/items/weapons/grenades/plastic.dm new file mode 100644 index 00000000000..f4ec3cff3e5 --- /dev/null +++ b/code/game/objects/items/weapons/grenades/plastic.dm @@ -0,0 +1,180 @@ +/obj/item/weapon/grenade/plastic + name = "plastic explosive" + desc = "Used to put holes in specific areas without too much extra hole." + icon_state = "plastic-explosive0" + item_state = "plastic-explosive" + flags = NOBLUDGEON + det_time = 10 + display_timer = 0 + var/atom/target = null + var/image_overlay = null + var/obj/item/device/assembly_holder/nadeassembly = null + var/assemblyattacher + +/obj/item/weapon/grenade/plastic/New() + image_overlay = image('icons/obj/grenade.dmi', "[item_state]2") + ..() + +/obj/item/weapon/grenade/plastic/Destroy() + qdel(nadeassembly) + nadeassembly = null + target = null + ..() + +/obj/item/weapon/grenade/plastic/attackby(obj/item/I, mob/user, params) + if(!nadeassembly && istype(I, /obj/item/device/assembly_holder)) + var/obj/item/device/assembly_holder/A = I + if(!user.unEquip(I)) + return ..() + nadeassembly = A + A.master = src + A.loc = src + assemblyattacher = user.ckey + user << "You add [A] to the [name]." + playsound(src, 'sound/weapons/tap.ogg', 20, 1) + update_icon() + return + if(nadeassembly && istype(I, /obj/item/weapon/wirecutters)) + playsound(src, 'sound/items/Wirecutter.ogg', 20, 1) + nadeassembly.loc = get_turf(src) + nadeassembly.master = null + nadeassembly = null + update_icon() + return + ..() + +//assembly stuff +/obj/item/weapon/grenade/plastic/receive_signal() + prime() + +/obj/item/weapon/grenade/plastic/Crossed(atom/movable/AM) + if(nadeassembly) + nadeassembly.Crossed(AM) + +/obj/item/weapon/grenade/plastic/on_found(mob/finder) + if(nadeassembly) + nadeassembly.on_found(finder) + +/obj/item/weapon/grenade/plastic/attack_self(mob/user) + if(nadeassembly) + nadeassembly.attack_self(user) + return + var/newtime = input(usr, "Please set the timer.", "Timer", 10) as num + if(user.get_active_hand() == src) + newtime = Clamp(newtime, 10, 60000) + det_time = newtime + user << "Timer set for [det_time] seconds." + +/obj/item/weapon/grenade/plastic/afterattack(atom/movable/AM, mob/user, flag) + if (!flag) + return + if (istype(AM, /mob/living/carbon)) + return + user << "You start planting the [src]. The timer is set to [det_time]..." + + if(do_after(user, 50, target = AM)) + if(!user.unEquip(src)) + return + src.target = AM + loc = null + + message_admins("[key_name_admin(user)](?) (FLW) planted [src.name] on [target.name] at ([target.x],[target.y],[target.z] - JMP) with [det_time] second fuse",0,1) + log_game("[key_name(user)] planted [src.name] on [target.name] at ([target.x],[target.y],[target.z]) with [det_time] second fuse") + + target.overlays += image_overlay + if(!nadeassembly) + user << "You plant the bomb. Timer counting down from [det_time]." + addtimer(src, "prime", det_time*10) + +/obj/item/weapon/grenade/plastic/suicide_act(mob/user) + message_admins("[key_name_admin(user)](?) (FLW) suicided with [src.name] at ([user.x],[user.y],[user.z] - JMP)",0,1) + message_admins("[key_name(user)] suicided with [src.name] at ([user.x],[user.y],[user.z])") + user.visible_message("[user] activates the [src.name] and holds it above \his head! It looks like \he's going out with a bang!") + var/message_say = "FOR NO RAISIN!" + if(user.mind) + if(user.mind.special_role) + var/role = lowertext(user.mind.special_role) + if(role == "traitor" || role == "syndicate") + message_say = "FOR THE SYNDICATE!" + else if(role == "changeling") + message_say = "FOR THE HIVE!" + else if(role == "cultist") + message_say = "FOR NAR-SIE!" + else if(role == "revolutionary" || role == "head revolutionary") + message_say = "VIVA LA REVOLUTION!" + else if(user.mind.gang_datum) + message_say = "[uppertext(user.mind.gang_datum.name)] RULES!" + user.say(message_say) + target = user + sleep(10) + prime() + user.gib(no_brain = 1) + +/obj/item/weapon/grenade/plastic/update_icon() + if(nadeassembly) + icon_state = "[item_state]1" + else + icon_state = "[item_state]0" + +////////////////////////// +///// The Explosives ///// +////////////////////////// + +/obj/item/weapon/grenade/plastic/c4 + name = "C4" + desc = "Used to put holes in specific areas without too much extra hole. A saboteurs favourite." + +/obj/item/weapon/grenade/plastic/c4/prime() + var/turf/location + if(target) + if(!qdeleted(target)) + location = get_turf(target) + target.overlays -= image_overlay + else + location = get_turf(src) + if(location) + location.ex_act(2, target) + explosion(location,0,0,3) + if(istype(target, /mob)) + var/mob/M = target + M.gib() + qdel(src) + +// X4 is an upgraded directional variant of c4 which is relatively safe to be standing next to. And much less safe to be standing on the other side of. +// C4 is intended to be used for infiltration, and destroying tech. X4 is intended to be used for heavy breaching and tight spaces. +// Intended to replace C4 for nukeops, and to be a randomdrop in surplus/random traitor purchases. + +/obj/item/weapon/grenade/plastic/x4 + name = "X4" + desc = "A specialized shaped high explosive breaching charge. Designed to be safer for the user, and less so, for the wall." + var/aim_dir = NORTH + icon_state = "plasticx40" + item_state = "plasticx4" + +/obj/item/weapon/grenade/plastic/x4/prime() + var/turf/location + if(target) + if(!qdeleted(target)) + location = get_turf(target) + target.overlays -= image_overlay + else + location = get_turf(src) + if(location) + if(istype(loc, /obj/item/weapon/twohanded/spear)) + explosion(location, 0, 2, 3) + else if(target.density) + var/turf/T = get_step(location, aim_dir) + explosion(get_step(T, aim_dir),0,0,3) + explosion(T,0,2,0) + location.ex_act(2, target) + else + explosion(location, 0, 2, 3) + location.ex_act(2, target) + if(istype(target, /mob)) + var/mob/M = target + M.gib() + qdel(src) + +/obj/item/weapon/grenade/plastic/x4/afterattack(atom/movable/AM, mob/user, flag) + aim_dir = get_dir(user,AM) + ..() diff --git a/code/game/objects/items/weapons/grenades/syndieminibomb.dm b/code/game/objects/items/weapons/grenades/syndieminibomb.dm index e49edb574fe..9fe9e1fb04e 100644 --- a/code/game/objects/items/weapons/grenades/syndieminibomb.dm +++ b/code/game/objects/items/weapons/grenades/syndieminibomb.dm @@ -29,7 +29,7 @@ /obj/item/weapon/grenade/gluon desc = "An advanced grenade that releases a harmful stream of gluons inducing radiation in those nearby. These gluon streams will also make victims feel exhausted, and induce shivering. This extreme coldness will also likely wet any nearby floors." - name = "gluon grenade" + name = "gluon frag grenade" icon = 'icons/obj/grenade.dmi' icon_state = "bluefrag" item_state = "flashbang" @@ -44,7 +44,8 @@ for(var/turf/T in view(freeze_range,loc)) if(istype(T,/turf/open/floor)) var/turf/open/floor/F = T - F.wet = TURF_WET_ICE + F.wet = TURF_WET_PERMAFROST + addtimer(F, "MakeDry", rand(3000, 3100), 0, TURF_WET_PERMAFROST) for(var/mob/living/carbon/L in T) L.adjustStaminaLoss(stamina_damage) L.bodytemperature -= 230 diff --git a/code/game/objects/items/weapons/handcuffs.dm b/code/game/objects/items/weapons/handcuffs.dm index 6dda0088be5..103e0b3f07c 100644 --- a/code/game/objects/items/weapons/handcuffs.dm +++ b/code/game/objects/items/weapons/handcuffs.dm @@ -30,21 +30,24 @@ return if(!C.handcuffed) - C.visible_message("[user] is trying to put [src.name] on [C]!", \ - "[user] is trying to put [src.name] on [C]!") + if(C.get_num_arms() >= 2) + C.visible_message("[user] is trying to put [src.name] on [C]!", \ + "[user] is trying to put [src.name] on [C]!") - playsound(loc, cuffsound, 30, 1, -2) - if(do_mob(user, C, 30)) - apply_cuffs(C,user) - user << "You handcuff [C]." - if(istype(src, /obj/item/weapon/restraints/handcuffs/cable)) - feedback_add_details("handcuffs","C") + playsound(loc, cuffsound, 30, 1, -2) + if(do_mob(user, C, 30) && C.get_num_arms() >= 2) + apply_cuffs(C,user) + user << "You handcuff [C]." + if(istype(src, /obj/item/weapon/restraints/handcuffs/cable)) + feedback_add_details("handcuffs","C") + else + feedback_add_details("handcuffs","H") + + add_logs(user, C, "handcuffed") else - feedback_add_details("handcuffs","H") - - add_logs(user, C, "handcuffed") + user << "You fail to handcuff [C]!" else - user << "You fail to handcuff [C]!" + user << "[C] doesn't have two hands..." /obj/item/weapon/restraints/handcuffs/proc/apply_cuffs(mob/living/carbon/target, mob/user, var/dispense = 0) if(target.handcuffed) @@ -262,7 +265,7 @@ snap = 1 if(!C.lying) def_zone = pick("l_leg", "r_leg") - if(!C.legcuffed) //beartrap can't cuff your leg if there's already a beartrap or legcuffs. + if(!C.legcuffed && C.get_num_legs() >= 2) //beartrap can't cuff your leg if there's already a beartrap or legcuffs, or you don't have two legs. C.legcuffed = src src.loc = C C.update_inv_legcuffed() @@ -314,7 +317,7 @@ if(..() || !iscarbon(hit_atom))//if it gets caught or the target can't be cuffed, return//abort var/mob/living/carbon/C = hit_atom - if(!C.legcuffed) + if(!C.legcuffed && C.get_num_legs() >= 2) visible_message("\The [src] ensnares [C]!") C.legcuffed = src src.loc = C @@ -329,10 +332,3 @@ icon_state = "bola_r" breakouttime = 70 weaken = 1 - -/obj/item/weapon/restraints/legcuffs/bola/cult //cult variant, comes with armament talisman - name = "nar'sian bola" - desc = "A strong bola, bound with dark magic. Throw it to trip and slow your victim." - icon_state = "bola_cult" - breakouttime = 45 - weaken = 1 diff --git a/code/game/objects/items/weapons/melee/misc.dm b/code/game/objects/items/weapons/melee/misc.dm index 475f602428d..5f33b5a192d 100644 --- a/code/game/objects/items/weapons/melee/misc.dm +++ b/code/game/objects/items/weapons/melee/misc.dm @@ -93,7 +93,7 @@ /obj/item/weapon/melee/classic_baton/telescopic/suicide_act(mob/user) var/mob/living/carbon/human/H = user - var/obj/item/organ/internal/brain/B = H.getorgan(/obj/item/organ/internal/brain) + var/obj/item/organ/brain/B = H.getorgan(/obj/item/organ/brain) user.visible_message("[user] stuffs the [src] up their nose and presses the 'extend' button! It looks like they're trying to clear their mind.") if(!on) diff --git a/code/game/objects/items/weapons/storage/backpack.dm b/code/game/objects/items/weapons/storage/backpack.dm index bdea527638a..3cab28cd5f8 100644 --- a/code/game/objects/items/weapons/storage/backpack.dm +++ b/code/game/objects/items/weapons/storage/backpack.dm @@ -484,9 +484,15 @@ ..() contents = list() for(var/i in 1 to 10) - new /obj/item/weapon/c4(src) + new /obj/item/weapon/grenade/plastic/c4(src) return +/obj/item/weapon/storage/backpack/dufflebag/syndie/x4/New() + ..() + contents = list() + for(var/i in 1 to 3) + new /obj/item/weapon/grenade/plastic/x4(src) + /obj/item/weapon/storage/backpack/dufflebag/syndie/firestarter desc = "A large dufflebag containing New Russian pyro backpack sprayer, a pistol, a pipebomb, fireproof hardsuit, ammo, and other equipment." diff --git a/code/game/objects/items/weapons/storage/belt.dm b/code/game/objects/items/weapons/storage/belt.dm index 13988c9e41c..8b4549cc406 100644 --- a/code/game/objects/items/weapons/storage/belt.dm +++ b/code/game/objects/items/weapons/storage/belt.dm @@ -195,7 +195,7 @@ desc = "A syndicate belt designed to be used by boarding parties. Its style is modeled after the hardsuits they wear." icon_state = "militarybelt" item_state = "military" - max_w_class = 3 + max_w_class = 2 /obj/item/weapon/storage/belt/military/army name = "army belt" diff --git a/code/game/objects/items/weapons/storage/book.dm b/code/game/objects/items/weapons/storage/book.dm index 76a6bcba12e..d1e161f7a7f 100644 --- a/code/game/objects/items/weapons/storage/book.dm +++ b/code/game/objects/items/weapons/storage/book.dm @@ -118,7 +118,7 @@ var/global/list/bibleitemstates = list("bible", "koran", "scrapbook", "bible", " if(ishuman(M)) var/mob/living/carbon/human/H = M var/heal_amt = 10 - for(var/obj/item/organ/limb/affecting in H.organs) + for(var/obj/item/bodypart/affecting in H.bodyparts) if(affecting.status == ORGAN_ORGANIC) //No Bible can heal a robotic arm! if(affecting.heal_damage(heal_amt, heal_amt, 0)) H.update_damage_overlays(0) @@ -155,7 +155,7 @@ var/global/list/bibleitemstates = list("bible", "koran", "scrapbook", "bible", " if(ishuman(M)) var/mob/living/carbon/human/H = M var/message_halt = 0 - for(var/obj/item/organ/limb/affecting in H.organs) + for(var/obj/item/bodypart/affecting in H.bodyparts) if(affecting.status == ORGAN_ORGANIC) if(message_halt == 0) M.visible_message("[user] heals [M] with the power of [src.deity_name]!") diff --git a/code/game/objects/items/weapons/storage/boxes.dm b/code/game/objects/items/weapons/storage/boxes.dm index 3e831000e76..99b3a72e6ae 100644 --- a/code/game/objects/items/weapons/storage/boxes.dm +++ b/code/game/objects/items/weapons/storage/boxes.dm @@ -61,31 +61,32 @@ /obj/item/weapon/storage/box/survival/New() ..() - contents = list() new /obj/item/clothing/mask/breath(src) new /obj/item/weapon/tank/internals/emergency_oxygen(src) new /obj/item/weapon/reagent_containers/hypospray/medipen(src) - return /obj/item/weapon/storage/box/engineer /obj/item/weapon/storage/box/engineer/New() ..() - contents = list() new /obj/item/clothing/mask/breath(src) new /obj/item/weapon/tank/internals/emergency_oxygen/engi(src) new /obj/item/weapon/reagent_containers/hypospray/medipen(src) - return + +/obj/item/weapon/storage/box/syndie + +/obj/item/weapon/storage/box/syndie/New() + ..() + new /obj/item/clothing/mask/gas/syndicate(src) + new /obj/item/weapon/tank/internals/emergency_oxygen/engi(src) /obj/item/weapon/storage/box/security /obj/item/weapon/storage/box/security/New() ..() - contents = list() new /obj/item/clothing/mask/gas/sechailer(src) new /obj/item/weapon/tank/internals/emergency_oxygen(src) new /obj/item/weapon/reagent_containers/hypospray/medipen(src) - return /obj/item/weapon/storage/box/gloves name = "box of latex gloves" diff --git a/code/game/objects/items/weapons/storage/uplink_kits.dm b/code/game/objects/items/weapons/storage/uplink_kits.dm index 21949a40966..4ccc4803f1d 100644 --- a/code/game/objects/items/weapons/storage/uplink_kits.dm +++ b/code/game/objects/items/weapons/storage/uplink_kits.dm @@ -48,7 +48,7 @@ new /obj/item/weapon/gun/projectile/revolver(src) new /obj/item/ammo_box/a357(src) new /obj/item/weapon/card/emag(src) - new /obj/item/weapon/c4(src) + new /obj/item/weapon/grenade/plastic/c4(src) new /obj/item/clothing/gloves/color/latex/nitrile(src) new /obj/item/clothing/mask/gas/clown_hat(src) new /obj/item/clothing/under/suit_jacket/really_black(src) @@ -86,8 +86,8 @@ return if("sabotage") - new /obj/item/weapon/c4 (src) - new /obj/item/weapon/c4 (src) + new /obj/item/weapon/grenade/plastic/c4 (src) + new /obj/item/weapon/grenade/plastic/c4 (src) new /obj/item/device/doorCharge(src) new /obj/item/device/doorCharge(src) new /obj/item/device/camera_bug(src) diff --git a/code/game/objects/items/weapons/tools.dm b/code/game/objects/items/weapons/tools.dm index 38759629e95..83842b332a8 100644 --- a/code/game/objects/items/weapons/tools.dm +++ b/code/game/objects/items/weapons/tools.dm @@ -258,12 +258,12 @@ if(!istype(H)) return ..() - var/obj/item/organ/limb/affecting = H.get_organ(check_zone(user.zone_selected)) + var/obj/item/bodypart/affecting = H.get_bodypart(check_zone(user.zone_selected)) - if(affecting.status == ORGAN_ROBOTIC && user.a_intent != "harm") + if(affecting && affecting.status == ORGAN_ROBOTIC && user.a_intent != "harm") if(src.remove_fuel(1)) playsound(loc, 'sound/items/Welder.ogg', 50, 1) - user.visible_message("[user] starts to fix some of the dents on [H]'s [affecting.getDisplayName()].", "You start fixing some of the dents on [H]'s [affecting.getDisplayName()].") + user.visible_message("[user] starts to fix some of the dents on [H]'s [affecting.name].", "You start fixing some of the dents on [H]'s [affecting.name].") if(!do_mob(user, H, 50)) return item_heal_robotic(H, user, 5, 0) diff --git a/code/game/objects/items/weapons/twohanded.dm b/code/game/objects/items/weapons/twohanded.dm index 7e524588548..e8bbfbed48e 100644 --- a/code/game/objects/items/weapons/twohanded.dm +++ b/code/game/objects/items/weapons/twohanded.dm @@ -62,6 +62,9 @@ if(user.get_inactive_hand()) user << "You need your other hand to be empty!" return + if(user.get_num_arms() < 2) + user << "You don't have enough hands." + return wielded = 1 if(force_wielded) force = force_wielded @@ -318,7 +321,7 @@ explosive.prime() qdel(src) - //THIS MIGHT BE UNBALANCED SO I DUNNO + //THIS MIGHT BE UNBALANCED SO I DUNNO // it totally is. /obj/item/weapon/twohanded/spear/throw_impact(atom/target) . = ..() if(!.) //not caught @@ -326,7 +329,6 @@ explosive.prime() qdel(src) - /obj/item/weapon/twohanded/spear/AltClick() ..() if(!explosive) @@ -337,16 +339,6 @@ if(input) src.war_cry = input -//Placeholder C4 "grenade" for use on this spear -/obj/item/weapon/grenade/C4 - name = "C-4" - desc = "A brick of C-4." - -/obj/item/weapon/grenade/C4/prime() - update_mob() - explosion(src.loc,-1,1,3) - qdel(src) - /obj/item/weapon/twohanded/spear/CheckParts() if(explosive) explosive.loc = get_turf(src.loc) @@ -357,12 +349,6 @@ name = "explosive lance" desc = "A makeshift spear with [G] attached to it. Alt+click on the spear to set your war cry!" return - var/obj/item/weapon/c4/C4 = locate() in contents - if(C4) - var /obj/item/weapon/grenade/C4/C42 = new /obj/item/weapon/grenade/C4(src) - qdel(C4) - explosive = C42 - desc = "A makeshift spear with [C42] attached to it. Alt+click on the spear to set your war cry!" update_icon() // CHAINSAW @@ -403,6 +389,9 @@ var/datum/action/A = X A.UpdateButtonIcon() +/obj/item/weapon/twohanded/required/chainsaw/can_dismember() + return wielded + //GREY TIDE /obj/item/weapon/twohanded/spear/grey_tide diff --git a/code/game/objects/structures/aliens.dm b/code/game/objects/structures/aliens.dm index c28db9e3375..ffe82b4c3c3 100644 --- a/code/game/objects/structures/aliens.dm +++ b/code/game/objects/structures/aliens.dm @@ -275,7 +275,7 @@ return attack_hand(user) /obj/structure/alien/egg/attack_hand(mob/living/user) - if(user.getorgan(/obj/item/organ/internal/alien/plasmavessel)) + if(user.getorgan(/obj/item/organ/alien/plasmavessel)) switch(status) if(BURST) user << "You clear the hatched egg." @@ -343,7 +343,7 @@ return var/mob/living/carbon/C = AM - if(C.stat == CONSCIOUS && C.getorgan(/obj/item/organ/internal/body_egg/alien_embryo)) + if(C.stat == CONSCIOUS && C.getorgan(/obj/item/organ/body_egg/alien_embryo)) return Burst(0) diff --git a/code/game/objects/structures/beds_chairs/alien_nest.dm b/code/game/objects/structures/beds_chairs/alien_nest.dm index c196e946244..5186309b65e 100644 --- a/code/game/objects/structures/beds_chairs/alien_nest.dm +++ b/code/game/objects/structures/beds_chairs/alien_nest.dm @@ -22,7 +22,7 @@ for(var/buck in buckled_mobs) //breaking a nest releases all the buckled mobs, because the nest isn't holding them down anymore var/mob/living/M = buck - if(user.getorgan(/obj/item/organ/internal/alien/plasmavessel)) + if(user.getorgan(/obj/item/organ/alien/plasmavessel)) unbuckle_mob(M) add_fingerprint(user) return @@ -55,9 +55,9 @@ if ( !ismob(M) || (get_dist(src, user) > 1) || (M.loc != src.loc) || user.incapacitated() || M.buckled ) return - if(M.getorgan(/obj/item/organ/internal/alien/plasmavessel)) + if(M.getorgan(/obj/item/organ/alien/plasmavessel)) return - if(!user.getorgan(/obj/item/organ/internal/alien/plasmavessel)) + if(!user.getorgan(/obj/item/organ/alien/plasmavessel)) return if(buckled_mobs.len) diff --git a/code/game/objects/structures/crates_lockers/closets/job_closets.dm b/code/game/objects/structures/crates_lockers/closets/job_closets.dm index 65cb20bee21..9da2cc06a11 100644 --- a/code/game/objects/structures/crates_lockers/closets/job_closets.dm +++ b/code/game/objects/structures/crates_lockers/closets/job_closets.dm @@ -24,7 +24,7 @@ new /obj/item/weapon/reagent_containers/glass/rag(src) new /obj/item/weapon/reagent_containers/glass/rag(src) new /obj/item/weapon/storage/box/beanbag(src) - new /obj/item/clothing/suit/armor/vest(src) + new /obj/item/clothing/suit/armor/vest/alt(src) new /obj/item/clothing/glasses/sunglasses/reagent(src) new /obj/item/weapon/storage/belt/bandolier(src) diff --git a/code/game/objects/structures/crates_lockers/closets/secure/freezer.dm b/code/game/objects/structures/crates_lockers/closets/secure/freezer.dm index 79a66cda856..f84d9889d59 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/freezer.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/freezer.dm @@ -12,6 +12,20 @@ new /obj/item/weapon/reagent_containers/food/condiment/rice(src) new /obj/item/weapon/reagent_containers/food/condiment/sugar(src) +/obj/structure/closet/secure_closet/freezer/kitchen/maintenance + name = "maintenance refrigerator" + desc = "This refrigerator looks quite dusty, is there anything edible still inside?" + req_access = list() + +/obj/structure/closet/secure_closet/freezer/kitchen/maintenance/New() + ..() + for(var/i = 0, i < 5, i++) + new /obj/item/weapon/reagent_containers/food/condiment/milk(src) + for(var/i = 0, i < 5, i++) + new /obj/item/weapon/reagent_containers/food/condiment/soymilk(src) + for(var/i = 0, i < 2, i++) + new /obj/item/weapon/storage/fancy/egg_box(src) + /obj/structure/closet/secure_closet/freezer/kitchen/mining req_access = list() diff --git a/code/game/objects/structures/crates_lockers/closets/secure/medical.dm b/code/game/objects/structures/crates_lockers/closets/secure/medical.dm index bb313695cf6..68599a34216 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/medical.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/medical.dm @@ -68,7 +68,7 @@ new /obj/item/weapon/storage/belt/medical(src) new /obj/item/device/assembly/flash/handheld(src) new /obj/item/weapon/reagent_containers/hypospray/CMO(src) - new /obj/item/organ/internal/cyberimp/eyes/hud/medical(src) + new /obj/item/organ/cyberimp/eyes/hud/medical(src) new /obj/item/weapon/door_remote/chief_medical_officer(src) /obj/structure/closet/secure_closet/animal diff --git a/code/game/objects/structures/crates_lockers/closets/secure/secure_closets.dm b/code/game/objects/structures/crates_lockers/closets/secure/secure_closets.dm index 67292b52f2d..6b16c70b7ba 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/secure_closets.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/secure_closets.dm @@ -1,6 +1,6 @@ /obj/structure/closet/secure_closet name = "secure locker" - desc = "It's an immobile card-locked storage unit." + desc = "It's a card-locked storage unit." locked = 1 icon_state = "secure" health = 200 diff --git a/code/game/objects/structures/crates_lockers/closets/secure/security.dm b/code/game/objects/structures/crates_lockers/closets/secure/security.dm index 2cb1eae867f..c8fa71c24dc 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/security.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/security.dm @@ -43,7 +43,7 @@ new /obj/item/weapon/storage/box/ids(src) new /obj/item/weapon/storage/box/ids(src) new /obj/item/device/megaphone/command(src) - new /obj/item/clothing/suit/armor/vest(src) + new /obj/item/clothing/suit/armor/vest/alt(src) new /obj/item/device/assembly/flash/handheld(src) new /obj/item/clothing/glasses/sunglasses(src) new /obj/item/weapon/restraints/handcuffs/cable/zipties(src) diff --git a/code/game/objects/structures/displaycase.dm b/code/game/objects/structures/displaycase.dm index ccc043c0188..16b903709f3 100644 --- a/code/game/objects/structures/displaycase.dm +++ b/code/game/objects/structures/displaycase.dm @@ -253,12 +253,5 @@ /obj/structure/displaycase/labcage name = "lab cage" desc = "A glass lab container for storing interesting creatures." - -/obj/structure/displaycase/labcage/New() - ..() - var/obj/item/clothing/mask/facehugger/A = new /obj/item/clothing/mask/facehugger(src) - A.sterile = 1 - A.name = "Lamarr" - showpiece = A - update_icon() + start_showpiece_type = /obj/item/clothing/mask/facehugger/lamarr diff --git a/code/game/objects/structures/extinguisher.dm b/code/game/objects/structures/extinguisher.dm index 8741c8698e0..e011d83fa6e 100644 --- a/code/game/objects/structures/extinguisher.dm +++ b/code/game/objects/structures/extinguisher.dm @@ -5,9 +5,19 @@ icon_state = "extinguisher_closed" anchored = 1 density = 0 - var/obj/item/weapon/extinguisher/has_extinguisher = new/obj/item/weapon/extinguisher + var/obj/item/weapon/extinguisher/has_extinguisher var/opened = 0 +/obj/structure/extinguisher_cabinet/New(loc, ndir, building) + ..() + if(building) + dir = ndir + pixel_x = (dir & 3)? 0 : (dir == 4 ? -27 : 27) + pixel_y = (dir & 3)? (dir ==1 ? -30 : 30) : 0 + opened = 1 + icon_state = "extinguisher_empty" + else + has_extinguisher = new /obj/item/weapon/extinguisher(src) /obj/structure/extinguisher_cabinet/ex_act(severity, target) switch(severity) @@ -24,16 +34,26 @@ return -/obj/structure/extinguisher_cabinet/attackby(obj/item/O, mob/user, params) +/obj/structure/extinguisher_cabinet/attackby(obj/item/I, mob/user, params) + if(istype(I, /obj/item/weapon/wrench) && !has_extinguisher) + user << "You start unsecuring [name]..." + playsound(loc, 'sound/items/Ratchet.ogg', 50, 1) + if(do_after(user, 60/I.toolspeed, target = src)) + playsound(loc, 'sound/items/Deconstruct.ogg', 50, 1) + user << "You unsecure [name]." + new /obj/item/wallframe/extinguisher_cabinet(loc) + qdel(src) + return + if(isrobot(user) || isalien(user)) return - if(istype(O, /obj/item/weapon/extinguisher)) + if(istype(I, /obj/item/weapon/extinguisher)) if(!has_extinguisher && opened) if(!user.drop_item()) return - contents += O - has_extinguisher = O - user << "You place [O] in [src]." + contents += I + has_extinguisher = I + user << "You place [I] in [src]." else opened = !opened else @@ -84,3 +104,10 @@ icon_state = "extinguisher_full" else icon_state = "extinguisher_empty" + +/obj/item/wallframe/extinguisher_cabinet + name = "extinguisher cabinet frame" + desc = "Used for building wall-mounted extinguisher cabinets." + icon = 'icons/obj/apc_repair.dmi' + icon_state = "extinguisher_frame" + result_path = /obj/structure/extinguisher_cabinet diff --git a/code/game/objects/structures/mirror.dm b/code/game/objects/structures/mirror.dm index e2d7d3f1d47..bf412453520 100644 --- a/code/game/objects/structures/mirror.dm +++ b/code/game/objects/structures/mirror.dm @@ -198,7 +198,7 @@ H.update_body() H.update_hair() - H.update_mutcolor() + H.update_body_parts() H.update_mutations_overlay() // no hulk lizard if("gender") diff --git a/code/game/objects/structures/tables_racks.dm b/code/game/objects/structures/tables_racks.dm index 1a1ece0837b..199c3ddae49 100644 --- a/code/game/objects/structures/tables_racks.dm +++ b/code/game/objects/structures/tables_racks.dm @@ -264,23 +264,27 @@ canSmoothWith = null health = 50 -/obj/structure/table/glass/tablepush(obj/item/I, mob/user) - if(..()) - visible_message("[src] breaks!") - playsound(src.loc, "shatter", 50, 1) - new frame(src.loc) - new /obj/item/weapon/shard(src.loc) - qdel(src) +/obj/structure/table/glass/Crossed(atom/movable/AM) + . = ..() + if(flags & NODECONSTRUCT) + return + // Don't break if they're just flying past + if(AM.throwing) + return + if(istype(AM, /mob/living)) + var/mob/living/M = AM + if(has_gravity(M) && M.mob_size > MOB_SIZE_SMALL) + table_shatter(M) -/obj/structure/table/glass/climb_structure(mob/user) - if(..()) - visible_message("[src] breaks!") - playsound(src.loc, "shatter", 50, 1) - new frame(src.loc) - new /obj/item/weapon/shard(src.loc) - qdel(src) - user.Weaken(5) +/obj/structure/table/glass/proc/table_shatter(mob/M) + visible_message("[src] breaks!") + playsound(src.loc, "shatter", 50, 1) + new frame(src.loc) + var/obj/item/weapon/shard/S = new(src.loc) + S.throw_impact(M) + M.Weaken(5) + qdel(src) /* * Wooden tables diff --git a/code/game/objects/structures/watercloset.dm b/code/game/objects/structures/watercloset.dm index 39d63affdfe..099f0da18fa 100644 --- a/code/game/objects/structures/watercloset.dm +++ b/code/game/objects/structures/watercloset.dm @@ -425,7 +425,7 @@ user << "You fill [RG] from [src]." return 1 - else if(istype(O, /obj/item/weapon/melee/baton)) + if(istype(O, /obj/item/weapon/melee/baton)) var/obj/item/weapon/melee/baton/B = O if(B.bcell) if(B.bcell.charge > 0 && B.status == 1) @@ -440,12 +440,12 @@ playsound(src, "sparks", 50, 1) return - else if(istype(O, /obj/item/weapon/mop)) + if(istype(O, /obj/item/weapon/mop)) O.reagents.add_reagent("water", 5) user << "You wet [O] in [src]." playsound(loc, 'sound/effects/slosh.ogg', 25, 1) - else if(istype(O, /obj/item/weapon/reagent_containers/food/snacks/monkeycube)) + if(istype(O, /obj/item/weapon/reagent_containers/food/snacks/monkeycube)) var/obj/item/weapon/reagent_containers/food/snacks/monkeycube/M = O user << "You place [src] under a stream of water..." user.drop_item() @@ -453,22 +453,21 @@ M.Expand() return - var/obj/item/I = O - if(!I || !istype(I)) + if(!istype(O)) return - if(I.flags & ABSTRACT) //Abstract items like grabs won't wash. No-drop items will though because it's still technically an item in your hand. + if(O.flags & ABSTRACT) //Abstract items like grabs won't wash. No-drop items will though because it's still technically an item in your hand. return if(user.a_intent != "harm") - user << "You start washing [I]..." + user << "You start washing [O]..." busy = 1 if(!do_after(user, 40, target = src)) busy = 0 return 1 busy = 0 O.clean_blood() - user.visible_message("[user] washes [I] using [src].", \ - "You wash [I] using [src].") + user.visible_message("[user] washes [O] using [src].", \ + "You wash [O] using [src].") return 1 else return ..() diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm index e701e606b97..d56212c5835 100644 --- a/code/game/objects/structures/window.dm +++ b/code/game/objects/structures/window.dm @@ -185,7 +185,7 @@ else if(!reinf) user << (anchored ? "You begin to unscrew the window from the floor..." : "You begin to screw the window to the floor...") - if(do_after(user, 40/I.toolspeed, target = src)) + if(do_after(user, 30/I.toolspeed, target = src)) if(reinf && (state == 1 || state == 2)) //If state was unfastened, fasten it, else do the reverse state = (state == 1 ? 2 : 1) diff --git a/code/game/turfs/open.dm b/code/game/turfs/open.dm index 1094c43a496..068f0b945a6 100644 --- a/code/game/turfs/open.dm +++ b/code/game/turfs/open.dm @@ -96,19 +96,39 @@ wet_overlay = null var/turf/open/floor/F = src if(istype(F)) - wet_overlay = image('icons/effects/water.dmi', src, "wet_floor_static") + if(wet_setting == TURF_WET_ICE) + wet_overlay = image('icons/turf/overlays.dmi', src, "snowfloor") + else + 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)) //Because turfs don't get deleted, they change, adapt, transform, evolve and deform. they are one and they are all. - return - MakeDry(wet_setting) + if(wet < TURF_WET_ICE) + addtimer(src, "MakeDry", rand(790, 820)) /turf/open/proc/MakeDry(wet_setting = TURF_WET_WATER) - if(wet > wet_setting) + if(!istype(src, /turf)) //Because turfs don't get deleted, they change, adapt, transform, evolve and deform. they are one and they are all. return - wet = TURF_DRY - if(wet_overlay) - overlays -= wet_overlay \ No newline at end of file + if(wet > wet_setting || !wet) + return + if(wet == TURF_WET_PERMAFROST) + wet = TURF_WET_ICE + else + wet = TURF_DRY + if(wet_overlay) + overlays -= wet_overlay + +/turf/open/proc/HandleWet() + if(!istype(src, /turf)) + return + if(!wet || wet > TURF_WET_ICE) + return + if(air.temperature < T0C && wet != TURF_WET_ICE) + MakeDry(TURF_WET_ICE) + MakeSlippery(TURF_WET_ICE) + else if (wet == TURF_WET_ICE) + MakeDry(TURF_WET_ICE) + MakeSlippery(TURF_WET_WATER) + else if (air.temperature > T0C + 40) // Warm rooms will dry up rather quickly. + addtimer(src, "MakeDry", 100, 1, TURF_WET_ICE) diff --git a/code/game/turfs/simulated/floor/misc_floor.dm b/code/game/turfs/simulated/floor/misc_floor.dm index c528d622549..c8b395a0c84 100644 --- a/code/game/turfs/simulated/floor/misc_floor.dm +++ b/code/game/turfs/simulated/floor/misc_floor.dm @@ -69,7 +69,7 @@ temperature = 180 baseturf = /turf/open/floor/plating/ice slowdown = 1 - wet = TURF_WET_ICE + wet = TURF_WET_PERMAFROST /turf/open/floor/plating/ice/colder temperature = 140 diff --git a/code/game/turfs/simulated/river.dm b/code/game/turfs/simulated/river.dm index b102cb7ce75..50a7d92bcf7 100644 --- a/code/game/turfs/simulated/river.dm +++ b/code/game/turfs/simulated/river.dm @@ -4,11 +4,11 @@ #define RANDOM_LOWER_X 50 #define RANDOM_LOWER_Y 50 -/proc/spawn_rivers(target_z = 5, nodes = 4, turf_type = /turf/open/floor/plating/lava/smooth/lava_land_surface, whitelist_area = /area/lavaland/surface/outdoors) +/proc/spawn_rivers(target_z = 5, nodes = 4, turf_type = /turf/open/floor/plating/lava/smooth/lava_land_surface, whitelist_area = /area/lavaland/surface/outdoors, min_x = RANDOM_LOWER_X, min_y = RANDOM_LOWER_Y, max_x = RANDOM_UPPER_X, max_y = RANDOM_UPPER_Y) var/list/river_nodes = list() var/num_spawned = 0 while(num_spawned < nodes) - var/turf/F = locate(rand(RANDOM_LOWER_X, RANDOM_UPPER_X), rand(RANDOM_LOWER_Y, RANDOM_UPPER_Y), target_z) + var/turf/F = locate(rand(min_x, max_x), rand(min_y, max_y), target_z) river_nodes += new /obj/effect/landmark/river_waypoint(F) num_spawned++ diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index d59cc3f0462..ea8622dd70b 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -105,7 +105,7 @@ M.inertia_dir = 0 if(TURF_WET_LUBE) M.slip(0, 7, null, (SLIDE|GALOSHES_DONT_HELP)) - if(TURF_WET_ICE) + if(TURF_WET_ICE || TURF_WET_PERMAFROST) M.slip(0, 4, null, (SLIDE|NO_SLIP_WHEN_WALKING)) /turf/proc/is_plasteel_floor() diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index 032be33b187..60129c99d52 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -6,6 +6,10 @@ var/global/BSACooldown = 0 msg = "ADMIN LOG: [msg]" admins << msg +/proc/relay_msg_admins(msg) + msg = "RELAY: [msg]" + admins << msg + ///////////////////////////////////////////////////////////////////////////////////////////////Panels diff --git a/code/modules/admin/create_mob.dm b/code/modules/admin/create_mob.dm index d2f35bb1a80..8edcfbedb7e 100644 --- a/code/modules/admin/create_mob.dm +++ b/code/modules/admin/create_mob.dm @@ -21,4 +21,5 @@ H.eye_color = random_eye_color() H.dna.blood_type = random_blood_type() H.update_body() - H.update_hair() \ No newline at end of file + H.update_hair() + H.update_body_parts() \ No newline at end of file diff --git a/code/modules/admin/player_panel.dm b/code/modules/admin/player_panel.dm index d0aae03c7b1..b8e4aee8728 100644 --- a/code/modules/admin/player_panel.dm +++ b/code/modules/admin/player_panel.dm @@ -474,6 +474,8 @@ var/mob/M = N.current if(M) dat += "Red Deity: [M.real_name][M.client ? "" : " (ghost)"][M.stat == 2 ? " (DEAD)" : ""]" + dat += "PM" + dat += "FLW" dat += "" if(ticker.mode.blue_deities.len) @@ -482,6 +484,8 @@ var/mob/M = N.current if(M) dat += "Blue Deity: [M.real_name][M.client ? "" : " (ghost)"][M.stat == 2 ? " (DEAD)" : ""]" + dat += "PM" + dat += "FLW" dat += "" if(ticker.mode.red_deity_prophets.len) @@ -490,6 +494,8 @@ var/mob/M = N.current if(M) dat += "Red Deity Prophet: [M.real_name][M.client ? "" : " (ghost)"][M.stat == 2 ? " (DEAD)" : ""]" + dat += "PM" + dat += "FLW" dat += "" if(ticker.mode.blue_deity_prophets.len) @@ -498,6 +504,8 @@ var/mob/M = N.current if(M) dat += "Blue Deity Prophet: [M.real_name][M.client ? "" : " (ghost)"][M.stat == 2 ? " (DEAD)" : ""]" + dat += "PM" + dat += "FLW" dat += "" if(ticker.mode.red_deity_followers.len) @@ -506,6 +514,8 @@ var/mob/M = N.current if(M) dat += "Red Deity Followers: [M.real_name][M.client ? "" : " (ghost)"][M.stat == 2 ? " (DEAD)" : ""]" + dat += "PM" + dat += "FLW" dat += "" if(ticker.mode.blue_deity_followers.len) @@ -514,6 +524,8 @@ var/mob/M = N.current if(M) dat += "Blue Deity Followers: [M.real_name][M.client ? "" : " (ghost)"][M.stat == 2 ? " (DEAD)" : ""]" + dat += "PM" + dat += "FLW" dat += "" if(ticker.mode.traitors.len > 0) diff --git a/code/modules/admin/verbs/adminhelp.dm b/code/modules/admin/verbs/adminhelp.dm index 16d57a12677..1776f8106b5 100644 --- a/code/modules/admin/verbs/adminhelp.dm +++ b/code/modules/admin/verbs/adminhelp.dm @@ -137,12 +137,26 @@ var/list/adm = get_admin_counts(requiredflags) . = adm["present"] if(. <= 0) + var/final = "" if(!adm["afk"] && !adm["stealth"] && !adm["noflags"]) - send2irc(source, "[msg] - No admins online") + final = "[msg] - No admins online" else - send2irc(source, "[msg] - All admins AFK ([adm["afk"]]/[adm["total"]]), stealthminned ([adm["stealth"]]/[adm["total"]]), or lack[rights2text(requiredflags, " ")] ([adm["noflags"]]/[adm["total"]])") + final = "[msg] - All admins AFK ([adm["afk"]]/[adm["total"]]), stealthminned ([adm["stealth"]]/[adm["total"]]), or lack[rights2text(requiredflags, " ")] ([adm["noflags"]]/[adm["total"]])" + send2irc(source,final) + send2otherserver(source,final) + /proc/send2irc(msg,msg2) if(config.useircbot) shell("python nudge.py [msg] [msg2]") return + +/proc/send2otherserver(source,msg,type = "Ahelp") + if(global.cross_allowed) + var/list/message = list() + message["message"] = "[source]: [msg]" + message["source"] = "([config.cross_name])" + message["key"] = global.comms_key + message["crossmessage"] = type + + world.Export("[global.cross_address]?[list2params(message)]") \ No newline at end of file diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm index ed3c081fc7e..e65dab41781 100644 --- a/code/modules/admin/verbs/debug.dm +++ b/code/modules/admin/verbs/debug.dm @@ -362,7 +362,7 @@ var/list/TYPES_SHORTCUTS = list( /obj/machinery/portable_atmospherics = "PORT_ATMOS", /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/missile_rack = "MECHA_MISSILE_RACK", /obj/item/mecha_parts/mecha_equipment = "MECHA_EQUIP", - /obj/item/organ/internal = "ORGAN_INT", + /obj/item/organ = "ORGAN", ) var/global/list/g_fancy_list_of_types = null diff --git a/code/modules/admin/verbs/diagnostics.dm b/code/modules/admin/verbs/diagnostics.dm index 76a7c851fe2..fae5f96e1b9 100644 --- a/code/modules/admin/verbs/diagnostics.dm +++ b/code/modules/admin/verbs/diagnostics.dm @@ -98,6 +98,6 @@ if(confirm !="Yes") return - message_admins("[key_name_admin(usr)] manually reloaded admins") load_admins() feedback_add_details("admin_verb","RLDA") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + message_admins("[key_name_admin(usr)] manually reloaded admins") \ No newline at end of file diff --git a/code/modules/admin/verbs/manipulate_organs.dm b/code/modules/admin/verbs/manipulate_organs.dm index 7b9349403f5..82703edaa3e 100644 --- a/code/modules/admin/verbs/manipulate_organs.dm +++ b/code/modules/admin/verbs/manipulate_organs.dm @@ -6,11 +6,11 @@ var/list/organs = list() switch(operation) if("add organ") - for(var/path in subtypesof(/obj/item/organ/internal)) - var/dat = replacetext("[path]", "/obj/item/organ/internal/", ":") + for(var/path in subtypesof(/obj/item/organ)) + var/dat = replacetext("[path]", "/obj/item/organ/", ":") organs[dat] = path - var/obj/item/organ/internal/organ = input("Select organ type:", "Organ Manipulation", null) in organs + var/obj/item/organ/organ = input("Select organ type:", "Organ Manipulation", null) in organs organ = organs[organ] organ = new organ organ.Insert(C) @@ -26,7 +26,7 @@ organ.implant(C) if("drop organ/implant", "remove organ/implant") - for(var/obj/item/organ/internal/I in C.internal_organs) + for(var/obj/item/organ/I in C.internal_organs) organs["[I.name] ([I.type])"] = I for(var/obj/item/weapon/implant/I in C) @@ -35,7 +35,7 @@ var/obj/item/organ = input("Select organ/implant:", "Organ Manipulation", null) in organs organ = organs[organ] if(!organ) return - var/obj/item/organ/internal/O + var/obj/item/organ/O var/obj/item/weapon/implant/I if(isorgan(organ)) diff --git a/code/modules/admin/verbs/modifyvariables.dm b/code/modules/admin/verbs/modifyvariables.dm index 308489beabe..8ff8989edc3 100644 --- a/code/modules/admin/verbs/modifyvariables.dm +++ b/code/modules/admin/verbs/modifyvariables.dm @@ -5,7 +5,7 @@ var/list/forbidden_varedit_object_types = list( /datum/admin_rank //editing my own rank? it's more likely than you think ) -var/list/VVlocked = list("vars", "client", "virus", "viruses", "cuffed", "last_eaten", "unlock_content", "step_x", "step_y", "force_ending") +var/list/VVlocked = list("vars", "var_edited", "client", "virus", "viruses", "cuffed", "last_eaten", "unlock_content", "step_x", "step_y", "force_ending") var/list/VVicon_edit_lock = list("icon", "icon_state", "overlays", "underlays", "resize") var/list/VVckey_edit = list("key", "ckey") diff --git a/code/modules/assembly/mousetrap.dm b/code/modules/assembly/mousetrap.dm index 632eb8e423e..dfdb4b9cca6 100644 --- a/code/modules/assembly/mousetrap.dm +++ b/code/modules/assembly/mousetrap.dm @@ -40,7 +40,7 @@ /obj/item/device/assembly/mousetrap/proc/triggered(mob/target, type = "feet") if(!armed) return - var/obj/item/organ/limb/affecting = null + var/obj/item/bodypart/affecting = null if(ishuman(target)) var/mob/living/carbon/human/H = target if(PIERCEIMMUNE in H.dna.species.specflags) @@ -52,11 +52,11 @@ switch(type) if("feet") if(!H.shoes) - affecting = H.get_organ(pick("l_leg", "r_leg")) + affecting = H.get_bodypart(pick("l_leg", "r_leg")) H.Weaken(3) if("l_hand", "r_hand") if(!H.gloves) - affecting = H.get_organ(type) + affecting = H.get_bodypart(type) H.Stun(3) if(affecting) if(affecting.take_damage(1, 0)) diff --git a/code/modules/atmospherics/environmental/LINDA_turf_tile.dm b/code/modules/atmospherics/environmental/LINDA_turf_tile.dm index a0e9c90e029..cbc9232520c 100644 --- a/code/modules/atmospherics/environmental/LINDA_turf_tile.dm +++ b/code/modules/atmospherics/environmental/LINDA_turf_tile.dm @@ -192,6 +192,7 @@ if(air.temperature > MINIMUM_TEMPERATURE_START_SUPERCONDUCTION) if(consider_superconductivity(starting = 1)) remove = 0 + HandleWet() // if the tile is wet, and cold, make ice. Or if it's wet, and warm, dry it off. if(!our_excited_group && remove == 1) SSair.remove_from_active(src) diff --git a/code/modules/awaymissions/capture_the_flag.dm b/code/modules/awaymissions/capture_the_flag.dm index 7108940c287..094bcb2cc40 100644 --- a/code/modules/awaymissions/capture_the_flag.dm +++ b/code/modules/awaymissions/capture_the_flag.dm @@ -284,6 +284,7 @@ health = INFINITY maxhealth = INFINITY var/team = WHITE_TEAM + constructable = FALSE time_between_triggers = 1 alpha = 255 diff --git a/code/modules/awaymissions/corpse.dm b/code/modules/awaymissions/corpse.dm index be2ba99ead4..6c45742bb27 100644 --- a/code/modules/awaymissions/corpse.dm +++ b/code/modules/awaymissions/corpse.dm @@ -387,12 +387,27 @@ /obj/effect/mob_spawn/human/bartender/alive death = FALSE roundstart = FALSE - mob_name = "Space Bartender" - name = "sleeper" + random = TRUE + name = "bartender sleeper" icon = 'icons/obj/Cryogenic2.dmi' icon_state = "sleeper" flavour_text = "You are a space bartender!" +/obj/effect/mob_spawn/human/beach + glasses = /obj/item/clothing/glasses/sunglasses + uniform = /obj/item/clothing/under/shorts/red + pocket1 = /obj/item/weapon/storage/wallet/random + +/obj/effect/mob_spawn/human/beach/alive + death = FALSE + roundstart = FALSE + random = TRUE + mob_name = "Beach Bum" + name = "beach bum sleeper" + icon = 'icons/obj/Cryogenic2.dmi' + icon_state = "sleeper" + flavour_text = "You are a beach bum!" + /////////////////Officers+Nanotrasen Security////////////////////// /obj/effect/mob_spawn/human/bridgeofficer diff --git a/code/modules/awaymissions/mission_code/snowdin.dm b/code/modules/awaymissions/mission_code/snowdin.dm index fc452c13888..35dcdc3b70d 100644 --- a/code/modules/awaymissions/mission_code/snowdin.dm +++ b/code/modules/awaymissions/mission_code/snowdin.dm @@ -124,7 +124,7 @@ obj/item/weapon/paper/crumpled/snowdin/shovel /obj/item/weapon/storage/firstaid/brute = 27, /obj/item/weapon/storage/firstaid/fire = 27, /obj/item/weapon/storage/toolbox/syndicate = 12, - /obj/item/weapon/c4 = 7, + /obj/item/weapon/grenade/plastic/c4 = 7, /obj/item/weapon/grenade/clusterbuster/smoke = 15, /obj/item/clothing/under/chameleon = 13, /obj/item/clothing/shoes/chameleon = 10, @@ -163,9 +163,9 @@ obj/item/weapon/paper/crumpled/snowdin/shovel loot = list(/obj/item/weapon/twohanded/singularityhammer = 25, /obj/item/weapon/twohanded/mjollnir = 10, /obj/item/weapon/twohanded/fireaxe = 25, - /obj/item/organ/internal/brain/alien = 17, + /obj/item/organ/brain/alien = 17, /obj/item/weapon/twohanded/dualsaber = 15, - /obj/item/organ/internal/heart/demon = 7, + /obj/item/organ/heart/demon = 7, /obj/item/weapon/gun/projectile/automatic/c20r/unrestricted = 16, /obj/item/weapon/gun/magic/wand/resurrection/inert = 15, /obj/item/weapon/gun/magic/wand/resurrection = 10, diff --git a/code/modules/cargo/exports/organs.dm b/code/modules/cargo/exports/organs.dm index 285e6dfdfa1..99db6127221 100644 --- a/code/modules/cargo/exports/organs.dm +++ b/code/modules/cargo/exports/organs.dm @@ -10,22 +10,22 @@ /datum/export/organ/alien/brain cost = 2000 unit_name = "alien brain" - export_types = list(/obj/item/organ/internal/brain/alien) + export_types = list(/obj/item/organ/brain/alien) /datum/export/organ/alien/acid cost = 1500 unit_name = "alien acid gland" - export_types = list(/obj/item/organ/internal/alien/acid) + export_types = list(/obj/item/organ/alien/acid) /datum/export/organ/alien/hivenode cost = 2000 unit_name = "alien hive node" - export_types = list(/obj/item/organ/internal/alien/hivenode) + export_types = list(/obj/item/organ/alien/hivenode) /datum/export/organ/alien/neurotoxin cost = 2000 unit_name = "alien neurotoxin gland" - export_types = list(/obj/item/organ/internal/alien/neurotoxin) + export_types = list(/obj/item/organ/alien/neurotoxin) /datum/export/organ/alien/resinspinner cost = 1000 @@ -34,9 +34,9 @@ /datum/export/organ/alien/plasmavessel cost = 1000 unit_name = "alien plasma vessel" - export_types = list(/obj/item/organ/internal/alien/plasmavessel) + export_types = list(/obj/item/organ/alien/plasmavessel) -/datum/export/organ/alien/plasmavessel/get_cost(obj/item/organ/internal/alien/plasmavessel/P) +/datum/export/organ/alien/plasmavessel/get_cost(obj/item/organ/alien/plasmavessel/P) return ..() + (P.max_plasma * 2) + (P.plasma_rate * 20) @@ -44,32 +44,32 @@ /datum/export/organ/alien/embryo cost = 5000 // Allows buyer to set up his own alien farm. unit_name = "alien embryo" - export_types = list(/obj/item/organ/internal/body_egg/alien_embryo) + export_types = list(/obj/item/organ/body_egg/alien_embryo) /datum/export/organ/alien/eggsac cost = 10000 // Even better than a single embryo. unit_name = "alien egg sac" - export_types = list(/obj/item/organ/internal/alien/eggsac) + export_types = list(/obj/item/organ/alien/eggsac) // Other alien organs. /datum/export/organ/alien/abductor cost = 2500 unit_name = "abductor gland" - export_types = list(/obj/item/organ/internal/gland) + export_types = list(/obj/item/organ/gland) /datum/export/organ/alien/changeling_egg cost = 50000 // Holy. Fuck. unit_name = "changeling egg" - export_types = list(/obj/item/organ/internal/body_egg/changeling_egg) + export_types = list(/obj/item/organ/body_egg/changeling_egg) /datum/export/organ/hivelord cost = 1500 unit_name = "active hivelord core" - export_types = list(/obj/item/organ/internal/hivelord_core) + export_types = list(/obj/item/organ/hivelord_core) -/datum/export/organ/alien/plasmavessel/get_cost(obj/item/organ/internal/hivelord_core/C) +/datum/export/organ/alien/plasmavessel/get_cost(obj/item/organ/hivelord_core/C) if(C.inert) return ..() / 3 if(C.preserved) @@ -89,20 +89,20 @@ /datum/export/organ/human/heart cost = 500 unit_name = "heart" - export_types = list(/obj/item/organ/internal/heart) + export_types = list(/obj/item/organ/heart) /datum/export/organ/human/lungs cost = 400 unit_name = "pair" message = "of lungs" - export_types = list(/obj/item/organ/internal/lungs) + export_types = list(/obj/item/organ/lungs) /datum/export/organ/human/appendix cost = 50 unit_name = "appendix" - export_types = list(/obj/item/organ/internal/appendix) + export_types = list(/obj/item/organ/appendix) -/datum/export/organ/human/appendix/get_cost(obj/item/organ/internal/appendix/O) +/datum/export/organ/human/appendix/get_cost(obj/item/organ/appendix/O) if(O.inflamed) return 0 return ..() \ No newline at end of file diff --git a/code/modules/cargo/packs.dm b/code/modules/cargo/packs.dm index 97d8066f690..ef1c1ef85cd 100644 --- a/code/modules/cargo/packs.dm +++ b/code/modules/cargo/packs.dm @@ -1317,6 +1317,7 @@ /obj/item/clothing/head/collectable/wizard, /obj/item/clothing/head/collectable/hardhat, /obj/item/clothing/head/collectable/HoS, + /obj/item/clothing/head/collectable/HoP, /obj/item/clothing/head/collectable/thunderdome, /obj/item/clothing/head/collectable/swat, /obj/item/clothing/head/collectable/slime, @@ -1418,3 +1419,18 @@ /obj/item/ammo_box/magazine/toy/pistol, /obj/item/ammo_box/magazine/toy/pistol) crate_name = "foam force crate" + +/datum/supply_pack/misc/artsupply + name = "Art Supplies" + cost = 800 + contains = list(/obj/structure/easel, + /obj/structure/easel, + /obj/item/weapon/canvas/nineteenXnineteen, + /obj/item/weapon/canvas/nineteenXnineteen, + /obj/item/weapon/canvas/twentythreeXnineteen, + /obj/item/weapon/canvas/twentythreeXnineteen, + /obj/item/weapon/canvas/twentythreeXtwentythree, + /obj/item/weapon/canvas/twentythreeXtwentythree, + /obj/item/toy/crayon/rainbow, + /obj/item/toy/crayon/rainbow) + crate_name= "art supply crate" diff --git a/code/modules/client/client defines.dm b/code/modules/client/client defines.dm index bb3889ced3e..78b19cb7198 100644 --- a/code/modules/client/client defines.dm +++ b/code/modules/client/client defines.dm @@ -49,4 +49,5 @@ //datum that controls the displaying and hiding of tooltips var/datum/tooltip/tooltips - + //Used for var edit flagging, also defined in datums (clients are not a child of datums for some reason) + var/var_edited = 0 \ No newline at end of file diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index 7ffb0c72eb0..333b764203a 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -1191,4 +1191,4 @@ var/list/preferences_datums = list() if(icon_updates) character.update_body() character.update_hair() - character.update_mutcolor() + character.update_body_parts() diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm index 6f8f9f0b464..c459acf5217 100644 --- a/code/modules/clothing/clothing.dm +++ b/code/modules/clothing/clothing.dm @@ -19,6 +19,38 @@ var/gang //Is this a gang outfit? var/scan_reagents = 0 //Can the wearer see reagents while it's equipped? + //Var modification - PLEASE be careful with this I know who you are and where you live + var/list/user_vars_to_edit = list() //VARNAME = VARVALUE eg: "name" = "butts" + var/list/user_vars_remembered = list() //Auto built by the above + dropped() + equipped() + + +/obj/item/clothing/Destroy() + dropped() + user_vars_remembered = null //Oh god somebody put REFERENCES in here? not to worry, we'll clean it up + return ..() + + +/obj/item/clothing/dropped(mob/user) + ..() + if(user_vars_remembered && user_vars_remembered.len) + for(var/variable in user_vars_remembered) + if(variable in user.vars) + if(user.vars[variable] == user_vars_to_edit[variable]) //Is it still what we set it to? (if not we best not change it) + user.vars[variable] = user_vars_remembered[variable] + user_vars_remembered = list() + + +/obj/item/clothing/equipped(mob/user, slot) + ..() + + if(slot_flags & slotdefine2slotbit(slot)) //Was equipped to a valid slot for this item? + for(var/variable in user_vars_to_edit) + if(variable in user.vars) + user_vars_remembered[variable] = user.vars[variable] + user.vars[variable] = user_vars_to_edit[variable] + + + //Ears: currently only used for headsets and earmuffs /obj/item/clothing/ears name = "ears" diff --git a/code/modules/clothing/head/collectable.dm b/code/modules/clothing/head/collectable.dm index 54b704195e2..c969147f9a3 100644 --- a/code/modules/clothing/head/collectable.dm +++ b/code/modules/clothing/head/collectable.dm @@ -126,6 +126,12 @@ desc = "Now you too can beat prisoners, set silly sentences, and arrest for no reason!" icon_state = "hoscap" +/obj/item/clothing/head/collectable/HoP + name = "collectable HoP hat" + desc = "It's your turn to demand excessive paperwork, signatures, stamps, and hire more clowns! Papers, please!" + icon_state = "hopcap" + dog_fashion = /datum/dog_fashion/head/hop + /obj/item/clothing/head/collectable/thunderdome name = "collectable Thunderdome helmet" desc = "Go Red! I mean Green! I mean Red! No Green!" diff --git a/code/modules/clothing/outfits/standard.dm b/code/modules/clothing/outfits/standard.dm index e32ca287c73..e1f8ad0bdcc 100644 --- a/code/modules/clothing/outfits/standard.dm +++ b/code/modules/clothing/outfits/standard.dm @@ -167,7 +167,7 @@ sec_briefcase.handle_item_insertion(new /obj/item/weapon/gun/energy/kinetic_accelerator/crossbow,1) sec_briefcase.handle_item_insertion(new /obj/item/weapon/gun/projectile/revolver/mateba,1) sec_briefcase.handle_item_insertion(new /obj/item/ammo_box/a357,1) - sec_briefcase.handle_item_insertion(new /obj/item/weapon/c4,1) + sec_briefcase.handle_item_insertion(new /obj/item/weapon/grenade/plastic/x4,1) var/obj/item/device/pda/heads/pda = H.belt pda.owner = H.real_name @@ -347,7 +347,7 @@ /obj/item/weapon/storage/firstaid/regular=1,\ /obj/item/weapon/storage/box/flashbangs=1,\ /obj/item/device/flashlight=1,\ - /obj/item/weapon/c4=1) + /obj/item/weapon/grenade/plastic/x4=1) /datum/outfit/death_commando/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE) if(visualsOnly) diff --git a/code/modules/clothing/shoes/bananashoes.dm b/code/modules/clothing/shoes/bananashoes.dm index 0f7accc2e5d..da3698024d0 100644 --- a/code/modules/clothing/shoes/bananashoes.dm +++ b/code/modules/clothing/shoes/bananashoes.dm @@ -20,10 +20,11 @@ else footstep++ - new/obj/item/weapon/grown/bananapeel/specialpeel(get_step(src,turn(usr.dir, 180)), 5) //honk + new/obj/item/weapon/grown/bananapeel/specialpeel(get_step(src,turn(usr.dir, 180))) //honk bananium.use_amount_type(100, MAT_BANANIUM) if(bananium.amount(MAT_BANANIUM) < 100) on = !on + flags &= ~NOSLIP update_icon() loc << "You ran out of bananium!" else @@ -37,8 +38,6 @@ user << "You cannot retrieve any bananium from the prototype shoes." /obj/item/clothing/shoes/clown_shoes/banana_shoes/attackby(obj/item/O, mob/user, params) - if(!istype(O,/obj/item/stack/sheet)) - return if(!bananium.get_item_material_amount(O)) user << "This item has no bananium!" return @@ -46,10 +45,10 @@ user << "You can't drop [O]!" return - var/obj/item/stack/sheet/S = O - var/sheet_amount = bananium.insert_stack(O,S.amount) - if(sheet_amount) - user << "You insert [sheet_amount] bananium sheets into the prototype shoes." + var/bananium_amount = bananium.insert_item(O) + if(bananium_amount) + user << "You insert [O] into the prototype shoes." + qdel(O) else user << "You are unable to insert more bananium!" @@ -63,6 +62,10 @@ on = !on update_icon() user << "You [on ? "activate" : "deactivate"] the prototype shoes." + if(on) + flags |= NOSLIP + else + flags &= ~NOSLIP else user << "You need bananium to turn the prototype shoes on!" diff --git a/code/modules/clothing/suits/armor.dm b/code/modules/clothing/suits/armor.dm index 6e15dfebe7a..2dd3343470f 100644 --- a/code/modules/clothing/suits/armor.dm +++ b/code/modules/clothing/suits/armor.dm @@ -12,12 +12,17 @@ /obj/item/clothing/suit/armor/vest name = "armor" desc = "A slim armored vest that protects against most types of damage." - icon_state = "armor" - item_state = "armor" + icon_state = "armoralt" + item_state = "armoralt" blood_overlay_type = "armor" armor = list(melee = 25, bullet = 15, laser = 25, energy = 10, bomb = 25, bio = 0, rad = 0) dog_fashion = /datum/dog_fashion/back +/obj/item/clothing/suit/armor/vest/alt + desc = "An armored vest that protects against most types of damage." + icon_state = "armor" + item_state = "armor" + /obj/item/clothing/suit/armor/hos name = "armored greatcoat" desc = "A greatcoat enchanced with a special alloy for some protection and style for those with a commanding presence." @@ -40,8 +45,8 @@ /obj/item/clothing/suit/armor/vest/warden name = "warden's jacket" - desc = "A red jacket with silver rank pips and body armor strapped on top." - icon_state = "warden_jacket" + desc = "A navy-blue armored jacket with blue shoulder designations and '/Warden/' stitched into one of the chest pockets." + icon_state = "warden_alt" item_state = "armor" body_parts_covered = CHEST|GROIN|ARMS cold_protection = CHEST|GROIN|ARMS|HANDS @@ -52,8 +57,8 @@ /obj/item/clothing/suit/armor/vest/warden/alt name = "warden's armored jacket" - desc = "A navy-blue armored jacket with blue shoulder designations and '/Warden/' stitched into one of the chest pockets." - icon_state = "warden_alt" + desc = "A red jacket with silver rank pips and body armor strapped on top." + icon_state = "warden_jacket" /obj/item/clothing/suit/armor/vest/leather name = "security overcoat" diff --git a/code/modules/clothing/suits/cloaks.dm b/code/modules/clothing/suits/cloaks.dm index f74ff4feb36..b91ac8ab04f 100644 --- a/code/modules/clothing/suits/cloaks.dm +++ b/code/modules/clothing/suits/cloaks.dm @@ -5,9 +5,18 @@ desc = "It's a cape that can be worn on your back." icon = 'icons/obj/clothing/cloaks.dmi' icon_state = "qmcloak" + item_state = "qmcloak" w_class = 2 body_parts_covered = CHEST|GROIN|LEGS|ARMS +/obj/item/clothing/head/cloakhood + name = "cloak hood" + icon = 'icons/obj/clothing/hats.dmi' + icon_state = "golhood" + desc = "A hood for a cloak" + body_parts_covered = HEAD + flags = NODROP + flags_inv = HIDEHAIR|HIDEEARS /obj/item/clothing/cloak/suicide_act(mob/user) user.visible_message("[user] is strangling themself with [src]! It looks like they're trying to commit suicide.") @@ -52,6 +61,27 @@ allowed = list(/obj/item/weapon/gun/energy/laser/captain) armor = list(melee = 30, bullet = 30, laser = 30, energy = 10, bomb = 25, bio = 10, rad = 10) +/obj/item/clothing/suit/hooded/cloak/drake + name = "ash drake hide cloak" + icon_state = "golclo" + desc = "A cloak fashioned from the hide of an ash drake, offers incredible defense while still remaining lightweight. " + allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank/internals, /obj/item/weapon/resonator, /obj/item/device/mining_scanner, /obj/item/device/t_scanner/adv_mining_scanner, /obj/item/weapon/gun/energy/kinetic_accelerator, /obj/item/weapon/pickaxe, /obj/item/weapon/twohanded/spear) + armor = list(melee = 70, bullet = 30, laser = 50, energy = 40, bomb = 70, bio = 60, rad = 50) + hooded = 1 + hoodtype = /obj/item/clothing/head/cloakhood/drake + heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS + max_heat_protection_temperature = FIRE_IMMUNITY_SUIT_MAX_TEMP_PROTECT + unacidable = 1 + +/obj/item/clothing/head/cloakhood/drake + name = "ash drake hide hood" + icon_state = "golhood" + desc = "A stiff hood made of ash drake hide." + armor = list(melee = 70, bullet = 30, laser = 50, energy = 40, bomb = 70, bio = 60, rad = 50) + heat_protection = HEAD + max_heat_protection_temperature = FIRE_IMMUNITY_HELM_MAX_TEMP_PROTECT + unacidable = 1 + /* //wip /obj/item/clothing/cloak/wizard //Not actually obtainable until proper balancing can be done name = "cloak of invisibility" diff --git a/code/modules/clothing/suits/labcoat.dm b/code/modules/clothing/suits/labcoat.dm index ae65b790782..d3bb738735c 100644 --- a/code/modules/clothing/suits/labcoat.dm +++ b/code/modules/clothing/suits/labcoat.dm @@ -5,7 +5,7 @@ item_state = "labcoat" blood_overlay_type = "coat" body_parts_covered = CHEST|ARMS - allowed = list(/obj/item/device/analyzer,/obj/item/stack/medical,/obj/item/weapon/dnainjector,/obj/item/weapon/reagent_containers/dropper,/obj/item/weapon/reagent_containers/syringe,/obj/item/weapon/reagent_containers/hypospray,/obj/item/device/healthanalyzer,/obj/item/device/flashlight/pen,/obj/item/weapon/reagent_containers/glass/bottle,/obj/item/weapon/reagent_containers/glass/beaker,/obj/item/weapon/reagent_containers/pill,/obj/item/weapon/storage/pill_bottle,/obj/item/weapon/paper,/obj/item/weapon/melee/classic_baton/telescopic,/obj/item/weapon/soap,/obj/item/device/sensor_device) + allowed = list(/obj/item/device/analyzer,/obj/item/stack/medical,/obj/item/weapon/dnainjector,/obj/item/weapon/reagent_containers/dropper,/obj/item/weapon/reagent_containers/syringe,/obj/item/weapon/reagent_containers/hypospray,/obj/item/device/healthanalyzer,/obj/item/device/flashlight/pen,/obj/item/weapon/reagent_containers/glass/bottle,/obj/item/weapon/reagent_containers/glass/beaker,/obj/item/weapon/reagent_containers/pill,/obj/item/weapon/storage/pill_bottle,/obj/item/weapon/paper,/obj/item/weapon/melee/classic_baton/telescopic,/obj/item/weapon/soap,/obj/item/device/sensor_device,/obj/item/weapon/tank/internals/emergency_oxygen) armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 50, rad = 0) togglename = "buttons" diff --git a/code/modules/clothing/suits/miscellaneous.dm b/code/modules/clothing/suits/miscellaneous.dm index 1842f608827..9fcc55c5ad1 100644 --- a/code/modules/clothing/suits/miscellaneous.dm +++ b/code/modules/clothing/suits/miscellaneous.dm @@ -490,3 +490,10 @@ /obj/item/clothing/head/winterhood/miner icon_state = "winterhood_miner" + +/obj/item/clothing/suit/spookyghost + name = "spooky ghost" + desc = "this is obviously just a bedsheet, but maybe try it on?" + icon_state = "bedsheet" + user_vars_to_edit = list("name" = "Spooky Ghost", "real_name" = "Spooky Ghost" , "incorporeal_move" = 1, "appearance_flags" = KEEP_TOGETHER|TILE_BOUND, "alpha" = 150) + alternate_worn_layer = ABOVE_BODY_FRONT_LAYER //so the bedsheet goes over everything but fire diff --git a/code/modules/clothing/suits/toggles.dm b/code/modules/clothing/suits/toggles.dm index fab30b8d4e3..5f7b4386db7 100644 --- a/code/modules/clothing/suits/toggles.dm +++ b/code/modules/clothing/suits/toggles.dm @@ -56,8 +56,7 @@ if(H.head) H << "You're already wearing something on your head!" return - else - H.equip_to_slot_if_possible(hood,slot_head,0,0,1) + else if(H.equip_to_slot_if_possible(hood,slot_head,0,0,1)) suittoggled = 1 src.icon_state = "[initial(icon_state)]_t" H.update_inv_wear_suit() @@ -172,9 +171,8 @@ if(H.head) H << "You're already wearing something on your head!" return - else + else if(H.equip_to_slot_if_possible(helmet,slot_head,0,0,1)) H << "You engage the helmet on the hardsuit." - H.equip_to_slot_if_possible(helmet,slot_head,0,0,1) suittoggled = 1 H.update_inv_wear_suit() playsound(src.loc, 'sound/mecha/mechmove03.ogg', 50, 1) diff --git a/code/modules/clothing/under/jobs/security.dm b/code/modules/clothing/under/jobs/security.dm index 975af383f15..6f7f9224e6e 100644 --- a/code/modules/clothing/under/jobs/security.dm +++ b/code/modules/clothing/under/jobs/security.dm @@ -13,17 +13,17 @@ name = "security jumpsuit" desc = "A tactical security jumpsuit for officers complete with nanotrasen belt buckle." icon_state = "security" - item_state = "r_suit" + item_state = "gy_suit" item_color = "security" armor = list(melee = 10, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0) strip_delay = 50 alt_covers_chest = 1 /obj/item/clothing/under/rank/warden - name = "warden's jumpsuit" - desc = "A tactical security jumpsuit for the warden with silver desginations and '/Warden/' stiched into the shoulders." + name = "security suit" + desc = "A formal security suit for officers complete with nanotrasen belt buckle." icon_state = "warden" - item_state = "r_suit" + item_state = "gy_suit" item_color = "warden" armor = list(melee = 10, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0) strip_delay = 50 @@ -57,7 +57,7 @@ name = "head of security's jumpsuit" desc = "A security jumpsuit decorated for those few with the dedication to achieve the position of Head of Security." icon_state = "hos" - item_state = "r_suit" + item_state = "gy_suit" item_color = "hos" armor = list(melee = 10, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0) strip_delay = 60 diff --git a/code/modules/crafting/recipes.dm b/code/modules/crafting/recipes.dm index e8f28379376..2c68ecb4ff9 100644 --- a/code/modules/crafting/recipes.dm +++ b/code/modules/crafting/recipes.dm @@ -31,7 +31,7 @@ category = CAT_WEAPON /datum/table_recipe/lance - name = "explosive lance (grenade)" + name = "explosive lance" result = /obj/item/weapon/twohanded/spear reqs = list(/obj/item/weapon/twohanded/spear = 1, /obj/item/weapon/grenade = 1) @@ -39,15 +39,6 @@ time = 15 category = CAT_WEAPON -/datum/table_recipe/lance2 - name = "explosive lance (C4)" - result = /obj/item/weapon/twohanded/spear - reqs = list(/obj/item/weapon/twohanded/spear = 1, - /obj/item/weapon/c4 = 1) - parts = list(/obj/item/weapon/c4 = 1) - time = 40 - category = CAT_WEAPON - /datum/table_recipe/molotov name = "Molotov" @@ -88,7 +79,7 @@ /datum/table_recipe/tailclub name = "Tail Club" result = /obj/item/weapon/tailclub - reqs = list(/obj/item/organ/severedtail = 1, + reqs = list(/obj/item/severedtail = 1, /obj/item/stack/sheet/metal = 1) time = 40 category = CAT_WEAPON @@ -96,7 +87,7 @@ /datum/table_recipe/tailwhip name = "Liz O' Nine Tails" result = /obj/item/weapon/melee/chainofcommand/tailwhip - reqs = list(/obj/item/organ/severedtail = 1, + reqs = list(/obj/item/severedtail = 1, /obj/item/stack/cable_coil = 1) time = 40 category = CAT_WEAPON @@ -287,7 +278,7 @@ name = "Lizard Cloche Hat" result = /obj/item/clothing/head/lizard time = 10 - reqs = list(/obj/item/organ/severedtail = 1) + reqs = list(/obj/item/severedtail = 1) category = CAT_MISC /datum/table_recipe/lizardhat_alternate @@ -321,11 +312,11 @@ category = CAT_MISC /datum/table_recipe/chemical_payload - name = "chemical payload (C4)" + name = "Chemical Payload (C4)" result = /obj/item/weapon/bombcore/chemical reqs = list( - /obj/item/weapon/stock_parts/matter_bin/super = 1, - /obj/item/weapon/c4 = 1, + /obj/item/weapon/stock_parts/matter_bin = 1, + /obj/item/weapon/grenade/plastic/c4 = 1, /obj/item/weapon/grenade/chem_grenade = 2 ) parts = list(/obj/item/weapon/stock_parts/matter_bin = 1, /obj/item/weapon/grenade/chem_grenade = 2) @@ -333,7 +324,7 @@ category = CAT_WEAPON /datum/table_recipe/chemical_payload2 - name = "chemical payload (gibtonite)" + name = "Chemical Payload (gibtonite)" result = /obj/item/weapon/bombcore/chemical reqs = list( /obj/item/weapon/stock_parts/matter_bin = 1, @@ -372,4 +363,13 @@ result = /obj/item/clothing/head/helmet/skull time = 30 reqs = list(/obj/item/stack/sheet/bone = 4) + category = CAT_PRIMAL + +/datum/table_recipe/drakecloak + name = "Ash Drake Cloak" + result = /obj/item/clothing/suit/hooded/cloak/drake + time = 60 + reqs = list(/obj/item/stack/sheet/bone = 10, + /obj/item/stack/sheet/sinew = 2, + /obj/item/stack/sheet/animalhide/ashdrake = 5) category = CAT_PRIMAL \ No newline at end of file diff --git a/code/modules/events/wizard/greentext.dm b/code/modules/events/wizard/greentext.dm index 31123ef86ce..cd4911f231a 100644 --- a/code/modules/events/wizard/greentext.dm +++ b/code/modules/events/wizard/greentext.dm @@ -28,6 +28,7 @@ var/mob/living/last_holder var/mob/living/new_holder var/list/color_altered_mobs = list() + burn_state = FIRE_PROOF /obj/item/weapon/greentext/New() ..() @@ -75,6 +76,8 @@ last_holder = new_holder //long live the king /obj/item/weapon/greentext/Destroy() + if(burn_state != ON_FIRE) + return QDEL_HINT_LETMELIVE poi_list.Remove(src) for(var/mob/M in mob_list) var/message = "A dark temptation has passed from this world" @@ -83,4 +86,4 @@ M.color = initial(M.color) message += "..." M << message - return ..() \ No newline at end of file + return ..() diff --git a/code/modules/flufftext/Hallucination.dm b/code/modules/flufftext/Hallucination.dm index 70c2a6f2870..9eca1592029 100644 --- a/code/modules/flufftext/Hallucination.dm +++ b/code/modules/flufftext/Hallucination.dm @@ -467,9 +467,9 @@ var/list/non_fakeattack_weapons = list(/obj/item/weapon/gun/projectile, /obj/ite /obj/item/weapon/cartridge/syndicate, /obj/item/clothing/under/chameleon,\ /obj/item/clothing/shoes/chameleon, /obj/item/weapon/card/id/syndicate,\ /obj/item/clothing/mask/chameleon, /obj/item/clothing/glasses/thermal,\ - /obj/item/device/chameleon, /obj/item/weapon/card/emag,\ + /obj/item/device/chameleon, /obj/item/weapon/card/emag, /obj/item/weapon/grenade/plastic/x4,\ /obj/item/weapon/storage/toolbox/syndicate, /obj/item/weapon/aiModule,\ - /obj/item/device/radio/headset/syndicate, /obj/item/weapon/c4,\ + /obj/item/device/radio/headset/syndicate, /obj/item/weapon/grenade/plastic/c4,\ /obj/item/device/powersink, /obj/item/weapon/storage/box/syndie_kit,\ /obj/item/toy/syndicateballoon, /obj/item/weapon/gun/energy/laser/captain,\ /obj/item/weapon/hand_tele, /obj/item/weapon/rcd, /obj/item/weapon/tank/jetpack,\ @@ -642,7 +642,7 @@ var/list/non_fakeattack_weapons = list(/obj/item/weapon/gun/projectile, /obj/ite halitem.icon_state = "revolver" halitem.name = "Revolver" if(2) //c4 - halitem.icon = 'icons/obj/assemblies.dmi' + halitem.icon = 'icons/obj/grenade.dmi' halitem.icon_state = "plastic-explosive0" halitem.name = "Mysterious Package" if(prob(25)) @@ -685,7 +685,7 @@ var/list/non_fakeattack_weapons = list(/obj/item/weapon/gun/projectile, /obj/ite halimage = image('icons/effects/fire.dmi',target,"1",TURF_LAYER) if(3) //src << "C4" - halimage = image('icons/obj/assemblies.dmi',target,"plastic-explosive2",OBJ_LAYER+0.01) + halimage = image('icons/obj/grenade.dmi',target,"plastic-explosive2",OBJ_LAYER+0.01) if(client) client.images += halimage diff --git a/code/modules/food&drinks/drinks/drinks/bottle.dm b/code/modules/food&drinks/drinks/drinks/bottle.dm index 9ea0b9d7bb1..c71b1aa2a71 100644 --- a/code/modules/food&drinks/drinks/drinks/bottle.dm +++ b/code/modules/food&drinks/drinks/drinks/bottle.dm @@ -59,7 +59,7 @@ force = 15 //Smashing bottles over someoen's head hurts. - var/obj/item/organ/limb/affecting = user.zone_selected //Find what the player is aiming at + var/obj/item/bodypart/affecting = user.zone_selected //Find what the player is aiming at var/armor_block = 0 //Get the target's armor values for normal attack damage. var/armor_duration = 0 //The more force the bottle has, the longer the duration. @@ -236,16 +236,58 @@ list_reagents = list("wine" = 100) /obj/item/weapon/reagent_containers/food/drinks/bottle/absinthe - name = "T&T Extra-Strong Absinthe" - desc = "An strong alcoholic drink brewed and distributed by Terb & Tonte Inc." + name = "Extra-Strong Absinthe" + desc = "An strong alcoholic drink brewed and distributed by" icon_state = "absinthebottle" list_reagents = list("absinthe" = 100) +/obj/item/weapon/reagent_containers/food/drinks/bottle/absinthe/New() + ..() + redact() + +/obj/item/weapon/reagent_containers/food/drinks/bottle/absinthe/proc/redact() + // There was a large fight in the coderbus about a player reference + // in absinthe. Ergo, this is why the name generation is now so + // complicated. Judge us kindly. + var/shortname = pickweight( + list("T&T" = 1, "A&A" = 1, "Generic" = 1)) + var/fullname + switch(shortname) + if("T&T") + fullname = "Teal and Tealer" + if("A&A") + fullname = "Ash and Asher" + if("Generic") + fullname = "Nanotrasen Cheap Imitations" + var/removals = list("\[REDACTED\]", "\[EXPLETIVE DELETED\]", + "\[EXPUNGED\]", "\[INFORMATION ABOVE YOUR SECURITY CLEARANCE\]", + "\[MOVE ALONG CITIZEN\]", "\[NOTHING TO SEE HERE\]") + var/chance = 50 + + if(prob(chance)) + shortname = pick_n_take(removals) + + var/list/final_fullname = list() + for(var/word in splittext(fullname, " ")) + if(prob(chance)) + word = pick_n_take(removals) + final_fullname += word + + fullname = jointext(final_fullname, " ") + + // Actually finally setting the new name and desc + name = "[shortname] [name]" + desc = "[desc] [fullname] Inc." + + /obj/item/weapon/reagent_containers/food/drinks/bottle/absinthe/premium name = "Gwyn's Premium Absinthe" desc = "A potent alcoholic beverage, almost makes you forget the ash in your lungs." icon_state = "absinthepremium" +/obj/item/weapon/reagent_containers/food/drinks/bottle/absinthe/premium/redact() + return + //////////////////////////JUICES AND STUFF /////////////////////// /obj/item/weapon/reagent_containers/food/drinks/bottle/orangejuice diff --git a/code/modules/food&drinks/food/snacks_other.dm b/code/modules/food&drinks/food/snacks_other.dm index 21d3b51ff7d..babef429153 100644 --- a/code/modules/food&drinks/food/snacks_other.dm +++ b/code/modules/food&drinks/food/snacks_other.dm @@ -308,4 +308,11 @@ icon_state = "honeybar" bonus_reagents = list("nutriment" = 2, "honey" = 2, "vitamin" = 2) list_reagents = list("nutriment" = 5, "honey" = 5) - filling_color = "#F2CE91" \ No newline at end of file + filling_color = "#F2CE91" + +/obj/item/weapon/reagent_containers/food/snacks/stuffedlegion + name = "stuffed legion" + desc = "The former skull of a damned human, filled with goliath meat. It has a decorative lava pool made of ketchup and hotsauce." + icon_state = "stuffed_legion" + bonus_reagents = list("vitamin" = 3, "capsaicin" = 1, "tricordrazine" = 5) + list_reagents = list("nutriment" = 5, "vitamin" = 5, "capsaicin" = 2, "tricordrazine" = 10,) \ No newline at end of file diff --git a/code/modules/food&drinks/recipes/tablecraft/recipes_burger.dm b/code/modules/food&drinks/recipes/tablecraft/recipes_burger.dm index a775bcbad99..e3c86d5732e 100644 --- a/code/modules/food&drinks/recipes/tablecraft/recipes_burger.dm +++ b/code/modules/food&drinks/recipes/tablecraft/recipes_burger.dm @@ -39,7 +39,7 @@ /datum/table_recipe/appendixburger name = "Appendix burger" reqs = list( - /obj/item/organ/internal/appendix = 1, + /obj/item/organ/appendix = 1, /obj/item/weapon/reagent_containers/food/snacks/bun = 1 ) result = /obj/item/weapon/reagent_containers/food/snacks/burger/appendix @@ -48,7 +48,7 @@ /datum/table_recipe/brainburger name = "Brain burger" reqs = list( - /obj/item/organ/internal/brain = 1, + /obj/item/organ/brain = 1, /obj/item/weapon/reagent_containers/food/snacks/bun = 1 ) result = /obj/item/weapon/reagent_containers/food/snacks/burger/brain diff --git a/code/modules/food&drinks/recipes/tablecraft/recipes_cake.dm b/code/modules/food&drinks/recipes/tablecraft/recipes_cake.dm index 902a398a6c3..63890d8b83f 100644 --- a/code/modules/food&drinks/recipes/tablecraft/recipes_cake.dm +++ b/code/modules/food&drinks/recipes/tablecraft/recipes_cake.dm @@ -78,7 +78,7 @@ /datum/table_recipe/braincake name = "Brain cake" reqs = list( - /obj/item/organ/internal/brain = 1, + /obj/item/organ/brain = 1, /obj/item/weapon/reagent_containers/food/snacks/store/cake/plain = 1 ) result = /obj/item/weapon/reagent_containers/food/snacks/store/cake/brain diff --git a/code/modules/food&drinks/recipes/tablecraft/recipes_meat.dm b/code/modules/food&drinks/recipes/tablecraft/recipes_meat.dm index 10e2fb70558..eba85761993 100644 --- a/code/modules/food&drinks/recipes/tablecraft/recipes_meat.dm +++ b/code/modules/food&drinks/recipes/tablecraft/recipes_meat.dm @@ -33,7 +33,7 @@ name = "Lizard tail kebab" reqs = list( /obj/item/stack/rods = 1, - /obj/item/organ/severedtail = 1 + /obj/item/severedtail = 1 ) result = /obj/item/weapon/reagent_containers/food/snacks/kebab/tail category = CAT_FOOD diff --git a/code/modules/food&drinks/recipes/tablecraft/recipes_misc.dm b/code/modules/food&drinks/recipes/tablecraft/recipes_misc.dm index 8db215dae2c..6f299b87d31 100644 --- a/code/modules/food&drinks/recipes/tablecraft/recipes_misc.dm +++ b/code/modules/food&drinks/recipes/tablecraft/recipes_misc.dm @@ -256,4 +256,17 @@ /datum/reagent/consumable/honey = 5 ) result = /obj/item/weapon/reagent_containers/food/snacks/honeybar + category = CAT_FOOD + + +/datum/table_recipe/stuffedlegion + name = "Stuffed legion" + time = 40 + reqs = list( + /obj/item/weapon/reagent_containers/food/snacks/meat/steak/goliath = 1, + /obj/item/weapon/legion_skull = 1, + /datum/reagent/consumable/ketchup = 2, + /datum/reagent/consumable/capsaicin = 2 + ) + result = /obj/item/weapon/reagent_containers/food/snacks/stuffedlegion category = CAT_FOOD \ No newline at end of file diff --git a/code/modules/games/cas.dm b/code/modules/games/cas.dm index f4798b32f4e..8f1616f882e 100644 --- a/code/modules/games/cas.dm +++ b/code/modules/games/cas.dm @@ -53,6 +53,7 @@ var/global/list/cards_against_space P.name = "Blank Card" P.card_icon = "cas_white" cards += P + shuffle(cards) // distribute blank cards throughout deck /obj/item/toy/cards/deck/cas/attack_hand(mob/user) if(user.lying) @@ -75,6 +76,21 @@ var/global/list/cards_against_space user.visible_message("[user] draws a card from the deck.", "You draw a card from the deck.") update_icon() +/obj/item/toy/cards/deck/cas/attackby(obj/item/I, mob/living/user, params) + if(istype(I, /obj/item/toy/cards/singlecard/cas)) + var/obj/item/toy/cards/singlecard/cas/SC = I + if(!user.unEquip(SC)) + user << "The card is stuck to your hand, you can't add it to the deck!" + return + var/datum/playingcard/RC // replace null datum for the re-added card + RC = new() + RC.name = "[SC.name]" + RC.card_icon = SC.card_face + cards += RC + user.visible_message("[user] adds a card to the bottom of the deck.","You add the card to the bottom of the deck.") + qdel(SC) + update_icon() + /obj/item/toy/cards/deck/cas/update_icon() if(cards.len < 26) icon_state = "deck_[deckstyle]_low" diff --git a/code/modules/hydroponics/grown/banana.dm b/code/modules/hydroponics/grown/banana.dm index 343c655a6e7..c5abc2caf69 100644 --- a/code/modules/hydroponics/grown/banana.dm +++ b/code/modules/hydroponics/grown/banana.dm @@ -114,5 +114,7 @@ desc = "A synthetic banana peel." /obj/item/weapon/grown/bananapeel/specialpeel/Crossed(AM) - if(..()) - qdel(src) \ No newline at end of file + if(iscarbon(AM)) + var/mob/living/carbon/carbon = AM + if(carbon.slip(2, 2, src, FALSE)) + qdel(src) \ No newline at end of file diff --git a/code/modules/hydroponics/grown/nettle.dm b/code/modules/hydroponics/grown/nettle.dm index acc3d489f09..86927e59be2 100644 --- a/code/modules/hydroponics/grown/nettle.dm +++ b/code/modules/hydroponics/grown/nettle.dm @@ -57,8 +57,8 @@ if(H.gloves) return 0 var/organ = ((H.hand ? "l_":"r_") + "arm") - var/obj/item/organ/limb/affecting = H.get_organ(organ) - if(affecting.take_damage(0, force)) + var/obj/item/bodypart/affecting = H.get_bodypart(organ) + if(affecting && affecting.take_damage(0, force)) H.update_damage_overlays(0) else C.take_organ_damage(0,force) diff --git a/code/modules/jobs/job_types/cargo_service.dm b/code/modules/jobs/job_types/cargo_service.dm index 8a7f561fde5..ed87fcae838 100644 --- a/code/modules/jobs/job_types/cargo_service.dm +++ b/code/modules/jobs/job_types/cargo_service.dm @@ -120,7 +120,7 @@ Bartender belt = /obj/item/device/pda/bar ears = /obj/item/device/radio/headset/headset_srv uniform = /obj/item/clothing/under/rank/bartender - suit = /obj/item/clothing/suit/armor/vest + suit = /obj/item/clothing/suit/armor/vest/alt backpack_contents = list(/obj/item/weapon/storage/box/beanbag=1) shoes = /obj/item/clothing/shoes/laceup diff --git a/code/modules/jobs/job_types/security.dm b/code/modules/jobs/job_types/security.dm index e62a8e155a2..457eed53abd 100644 --- a/code/modules/jobs/job_types/security.dm +++ b/code/modules/jobs/job_types/security.dm @@ -99,7 +99,7 @@ Warden shoes = /obj/item/clothing/shoes/jackboots suit = /obj/item/clothing/suit/armor/vest/warden gloves = /obj/item/clothing/gloves/color/black - head = /obj/item/clothing/head/warden + head = /obj/item/clothing/head/beret/sec/navywarden glasses = /obj/item/clothing/glasses/hud/security/sunglasses r_pocket = /obj/item/device/assembly/flash/handheld l_pocket = /obj/item/weapon/restraints/handcuffs diff --git a/code/modules/mining/abandoned_crates.dm b/code/modules/mining/abandoned_crates.dm index fb38ee97255..399cae5df69 100644 --- a/code/modules/mining/abandoned_crates.dm +++ b/code/modules/mining/abandoned_crates.dm @@ -106,11 +106,11 @@ if(87) //1% chance new /obj/item/weed_extract(src) if(88) - new /obj/item/organ/internal/brain(src) + new /obj/item/organ/brain(src) if(89) - new /obj/item/organ/internal/brain/alien(src) + new /obj/item/organ/brain/alien(src) if(90) - new /obj/item/organ/internal/heart(src) + new /obj/item/organ/heart(src) if(91) new /obj/item/device/soulstone/anybody(src) if(92) diff --git a/code/modules/mining/equipment_locker.dm b/code/modules/mining/equipment_locker.dm index 88c19bda7c2..58a7559c55c 100644 --- a/code/modules/mining/equipment_locker.dm +++ b/code/modules/mining/equipment_locker.dm @@ -1072,9 +1072,9 @@ w_class = 1 origin_tech = "biotech=1" -/obj/item/weapon/hivelordstabilizer/afterattack(obj/item/organ/internal/M, mob/user) - var/obj/item/organ/internal/hivelord_core/C = M - if(!istype(C, /obj/item/organ/internal/hivelord_core)) +/obj/item/weapon/hivelordstabilizer/afterattack(obj/item/organ/M, mob/user) + var/obj/item/organ/hivelord_core/C = M + if(!istype(C, /obj/item/organ/hivelord_core)) user << "The stabilizer only works on certain types of monster organs, generally regenerative in nature." return ..() C.preserved = 1 diff --git a/code/modules/mining/lavaland/necropolis_chests.dm b/code/modules/mining/lavaland/necropolis_chests.dm index 06f39e36eb4..4ff2c3d0c03 100644 --- a/code/modules/mining/lavaland/necropolis_chests.dm +++ b/code/modules/mining/lavaland/necropolis_chests.dm @@ -32,11 +32,11 @@ new /obj/item/clothing/suit/cultrobes(src) new /obj/item/weapon/bedsheet/cult(src) if(9) - new /obj/item/organ/internal/brain/alien(src) + new /obj/item/organ/brain/alien(src) if(10) - new /obj/item/organ/internal/heart/cursed(src) + new /obj/item/organ/heart/cursed(src) if(11) - new /obj/vehicle/lavaboat/dragon(src) + new /obj/item/ship_in_a_bottle(src) if(12) new /obj/item/clothing/suit/space/hardsuit/ert/paranormal/beserker(src) if(13) @@ -384,6 +384,19 @@ //Dragon Boat + +/obj/item/ship_in_a_bottle + name = "ship in a bottle" + desc = "A tiny ship inside a bottle." + icon = 'icons/obj/lavaland/artefacts.dmi' + icon_state = "ship_bottle" + +/obj/item/ship_in_a_bottle/attack_self(mob/user) + user << "You're not sure how they get the ships in these things, but you're pretty sure you know how to get it out." + playsound(user.loc, 'sound/effects/Glassbr1.ogg', 100, 1) + new /obj/vehicle/lavaboat/dragon(get_turf(src)) + qdel(src) + /obj/vehicle/lavaboat/dragon name = "mysterious boat" desc = "This boat moves where you will it, without the need for an oar." diff --git a/code/modules/mob/interactive.dm b/code/modules/mob/interactive.dm index 98f27b45659..6301af936fa 100644 --- a/code/modules/mob/interactive.dm +++ b/code/modules/mob/interactive.dm @@ -256,39 +256,12 @@ equip_to_slot_or_del(MYPDA, slot_belt) zone_selected = "chest" //arms - if(prob((FUZZY_CHANCE_LOW+FUZZY_CHANCE_HIGH)/4)) - var/obj/item/organ/limb/r_arm/R = locate(/obj/item/organ/limb/r_arm) in organs - qdel(R) - organs += new /obj/item/organ/limb/robot/r_arm - else - var/obj/item/organ/limb/l_arm/L = locate(/obj/item/organ/limb/l_arm) in organs - qdel(L) - organs += new /obj/item/organ/limb/robot/l_arm - //legs - if(prob((FUZZY_CHANCE_LOW+FUZZY_CHANCE_HIGH)/4)) - var/obj/item/organ/limb/r_leg/R = locate(/obj/item/organ/limb/r_leg) in organs - qdel(R) - organs += new /obj/item/organ/limb/robot/r_leg - else - var/obj/item/organ/limb/l_leg/L = locate(/obj/item/organ/limb/l_leg) in organs - qdel(L) - organs += new /obj/item/organ/limb/robot/l_leg - //chest and head - if(prob((FUZZY_CHANCE_LOW+FUZZY_CHANCE_HIGH)/4)) - var/obj/item/organ/limb/chest/R = locate(/obj/item/organ/limb/chest) in organs - qdel(R) - organs += new /obj/item/organ/limb/robot/chest - else - var/obj/item/organ/limb/head/L = locate(/obj/item/organ/limb/head) in organs - qdel(L) - organs += new /obj/item/organ/limb/robot/head - for(var/LIMB in organs) - if(LIMB) // prevents a runtime - var/obj/item/organ/limb/L = LIMB - L.owner = src + for(var/X in bodyparts) + var/obj/item/bodypart/BP = X + if(prob((FUZZY_CHANCE_LOW+FUZZY_CHANCE_HIGH)/4)) + BP.change_bodypart_status(ORGAN_ROBOTIC) update_icons() update_damage_overlays(0) - update_augments() hand = 0 functions = list("nearbyscan","combat","shitcurity","chatter") // stop customize adding multiple copies of a function diff --git a/code/modules/mob/living/carbon/alien/alien.dm b/code/modules/mob/living/carbon/alien/alien.dm index abcf6eb065d..7ecb3f6683f 100644 --- a/code/modules/mob/living/carbon/alien/alien.dm +++ b/code/modules/mob/living/carbon/alien/alien.dm @@ -33,11 +33,11 @@ verbs += /mob/living/proc/mob_sleep verbs += /mob/living/proc/lay_down - internal_organs += new /obj/item/organ/internal/brain/alien - internal_organs += new /obj/item/organ/internal/alien/hivenode - internal_organs += new /obj/item/organ/internal/tongue/alien + internal_organs += new /obj/item/organ/brain/alien + internal_organs += new /obj/item/organ/alien/hivenode + internal_organs += new /obj/item/organ/tongue/alien - for(var/obj/item/organ/internal/I in internal_organs) + for(var/obj/item/organ/I in internal_organs) I.Insert(src) AddAbility(new/obj/effect/proc_holder/alien/nightvisiontoggle(null)) @@ -150,7 +150,7 @@ Des: Gives the client of the alien an image on each infected mob. if (client) for (var/mob/living/C in mob_list) if(C.status_flags & XENO_HOST) - var/obj/item/organ/internal/body_egg/alien_embryo/A = C.getorgan(/obj/item/organ/internal/body_egg/alien_embryo) + var/obj/item/organ/body_egg/alien_embryo/A = C.getorgan(/obj/item/organ/body_egg/alien_embryo) if(A) var/I = image('icons/mob/alien.dmi', loc = C, icon_state = "infected[A.stage]") client.images += I @@ -210,7 +210,7 @@ Des: Removes all infected images from the alien. if(A.update_remote_sight(src)) //returns 1 if we override all other sight updates. return - for(var/obj/item/organ/internal/cyberimp/eyes/E in internal_organs) + for(var/obj/item/organ/cyberimp/eyes/E in internal_organs) sight |= E.sight_flags if(E.dark_view) see_in_dark = max(see_in_dark, E.dark_view) diff --git a/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm b/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm index a9710f07572..d5256375e21 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm @@ -87,7 +87,16 @@ Doesn't work on other aliens/AI.*/ if(msg) log_say("AlienWhisper: [key_name(user)]->[M.key] : [msg]") M << "You hear a strange, alien voice in your head...[msg]" - user << {"You said: "[msg]" to [M]"} + user << "You said: \"[msg]\" to [M]" + for(var/ded in dead_mob_list) + if(!isobserver(ded)) + continue + ded << "(F) \ + [user] \ + Alien Whisper --> \ + (F) \ + [M] \ + [msg]" else return 0 return 1 @@ -101,7 +110,7 @@ Doesn't work on other aliens/AI.*/ /obj/effect/proc_holder/alien/transfer/fire(mob/living/carbon/user) var/list/mob/living/carbon/aliens_around = list() for(var/mob/living/carbon/A in oview(user)) - if(A.getorgan(/obj/item/organ/internal/alien/plasmavessel)) + if(A.getorgan(/obj/item/organ/alien/plasmavessel)) aliens_around.Add(A) var/mob/living/carbon/M = input("Select who to transfer to:","Transfer plasma to?",null) as mob in aliens_around if(!M) @@ -113,7 +122,7 @@ Doesn't work on other aliens/AI.*/ M.adjustPlasma(amount) user.adjustPlasma(-amount) M << "[user] has transfered [amount] plasma to you." - user << {"You trasfer [amount] plasma to [M]"} + user << "You trasfer [amount] plasma to [M]" else user << "You need to be closer!" return @@ -285,13 +294,13 @@ Doesn't work on other aliens/AI.*/ /mob/living/carbon/proc/getPlasma() - var/obj/item/organ/internal/alien/plasmavessel/vessel = getorgan(/obj/item/organ/internal/alien/plasmavessel) + var/obj/item/organ/alien/plasmavessel/vessel = getorgan(/obj/item/organ/alien/plasmavessel) if(!vessel) return 0 return vessel.storedPlasma /mob/living/carbon/proc/adjustPlasma(amount) - var/obj/item/organ/internal/alien/plasmavessel/vessel = getorgan(/obj/item/organ/internal/alien/plasmavessel) + var/obj/item/organ/alien/plasmavessel/vessel = getorgan(/obj/item/organ/alien/plasmavessel) if(!vessel) return 0 vessel.storedPlasma = max(vessel.storedPlasma + amount,0) vessel.storedPlasma = min(vessel.storedPlasma, vessel.max_plasma) //upper limit of max_plasma, lower limit of 0 diff --git a/code/modules/mob/living/carbon/alien/humanoid/caste/drone.dm b/code/modules/mob/living/carbon/alien/humanoid/caste/drone.dm index d4343cba280..31896a81da8 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/caste/drone.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/caste/drone.dm @@ -7,9 +7,9 @@ /mob/living/carbon/alien/humanoid/drone/New() - internal_organs += new /obj/item/organ/internal/alien/plasmavessel/large - internal_organs += new /obj/item/organ/internal/alien/resinspinner - internal_organs += new /obj/item/organ/internal/alien/acid + internal_organs += new /obj/item/organ/alien/plasmavessel/large + internal_organs += new /obj/item/organ/alien/resinspinner + internal_organs += new /obj/item/organ/alien/acid AddAbility(new/obj/effect/proc_holder/alien/evolve(null)) ..() @@ -25,7 +25,7 @@ action_icon_state = "alien_evolve_drone" /obj/effect/proc_holder/alien/evolve/fire(mob/living/carbon/alien/humanoid/user) - var/obj/item/organ/internal/alien/hivenode/node = user.getorgan(/obj/item/organ/internal/alien/hivenode) + var/obj/item/organ/alien/hivenode/node = user.getorgan(/obj/item/organ/alien/hivenode) if(!node) //Players are Murphy's Law. We may not expect there to ever be a living xeno with no hivenode, but they _WILL_ make it happen. user << "Without the hivemind, you can't possibly hold the responsibility of leadership!" return 0 diff --git a/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm b/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm index 707fb458493..c18c1e6ab2c 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm @@ -7,7 +7,7 @@ var/obj/screen/leap_icon = null /mob/living/carbon/alien/humanoid/hunter/New() - internal_organs += new /obj/item/organ/internal/alien/plasmavessel/small + internal_organs += new /obj/item/organ/alien/plasmavessel/small ..() /mob/living/carbon/alien/humanoid/hunter/movement_delay() diff --git a/code/modules/mob/living/carbon/alien/humanoid/caste/praetorian.dm b/code/modules/mob/living/carbon/alien/humanoid/caste/praetorian.dm index fbd201d3bc7..8a15c4b4c9e 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/caste/praetorian.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/caste/praetorian.dm @@ -11,10 +11,10 @@ real_name = name - internal_organs += new /obj/item/organ/internal/alien/plasmavessel/large - internal_organs += new /obj/item/organ/internal/alien/resinspinner - internal_organs += new /obj/item/organ/internal/alien/acid - internal_organs += new /obj/item/organ/internal/alien/neurotoxin + internal_organs += new /obj/item/organ/alien/plasmavessel/large + internal_organs += new /obj/item/organ/alien/resinspinner + internal_organs += new /obj/item/organ/alien/acid + internal_organs += new /obj/item/organ/alien/neurotoxin AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/repulse/xeno(src)) AddAbility(new /obj/effect/proc_holder/alien/royal/praetorian/evolve()) ..() @@ -31,7 +31,7 @@ action_icon_state = "alien_evolve_praetorian" /obj/effect/proc_holder/alien/royal/praetorian/evolve/fire(mob/living/carbon/alien/humanoid/user) - var/obj/item/organ/internal/alien/hivenode/node = user.getorgan(/obj/item/organ/internal/alien/hivenode) + var/obj/item/organ/alien/hivenode/node = user.getorgan(/obj/item/organ/alien/hivenode) if(!node) //Just in case this particular Praetorian gets violated and kept by the RD as a replacement for Lamarr. user << "Without the hivemind, you would be unfit to rule as queen!" return 0 diff --git a/code/modules/mob/living/carbon/alien/humanoid/caste/sentinel.dm b/code/modules/mob/living/carbon/alien/humanoid/caste/sentinel.dm index eb53eb5c1b5..a22ab106dd4 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/caste/sentinel.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/caste/sentinel.dm @@ -7,9 +7,9 @@ /mob/living/carbon/alien/humanoid/sentinel/New() - internal_organs += new /obj/item/organ/internal/alien/plasmavessel - internal_organs += new /obj/item/organ/internal/alien/acid - internal_organs += new /obj/item/organ/internal/alien/neurotoxin + internal_organs += new /obj/item/organ/alien/plasmavessel + internal_organs += new /obj/item/organ/alien/acid + internal_organs += new /obj/item/organ/alien/neurotoxin AddAbility(new /obj/effect/proc_holder/alien/sneak) ..() diff --git a/code/modules/mob/living/carbon/alien/humanoid/death.dm b/code/modules/mob/living/carbon/alien/humanoid/death.dm index 987c626f8dc..b237ca3698b 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/death.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/death.dm @@ -21,7 +21,7 @@ for(var/mob/living/carbon/C in living_mob_list) if(C == src) //Make sure not to proc it on ourselves. continue - var/obj/item/organ/internal/alien/hivenode/node = C.getorgan(/obj/item/organ/internal/alien/hivenode) + var/obj/item/organ/alien/hivenode/node = C.getorgan(/obj/item/organ/alien/hivenode) if(istype(node)) // just in case someone would ever add a diffirent node to hivenode slot node.queen_death() diff --git a/code/modules/mob/living/carbon/alien/humanoid/queen.dm b/code/modules/mob/living/carbon/alien/humanoid/queen.dm index 508629153d7..c93ad1ead74 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/queen.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/queen.dm @@ -37,11 +37,11 @@ real_name = src.name - internal_organs += new /obj/item/organ/internal/alien/plasmavessel/large/queen - internal_organs += new /obj/item/organ/internal/alien/resinspinner - internal_organs += new /obj/item/organ/internal/alien/acid - internal_organs += new /obj/item/organ/internal/alien/neurotoxin - internal_organs += new /obj/item/organ/internal/alien/eggsac + internal_organs += new /obj/item/organ/alien/plasmavessel/large/queen + internal_organs += new /obj/item/organ/alien/resinspinner + internal_organs += new /obj/item/organ/alien/acid + internal_organs += new /obj/item/organ/alien/neurotoxin + internal_organs += new /obj/item/organ/alien/eggsac AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/repulse/xeno(src)) AddAbility(new/obj/effect/proc_holder/alien/royal/queen/promote()) ..() diff --git a/code/modules/mob/living/carbon/alien/larva/larva.dm b/code/modules/mob/living/carbon/alien/larva/larva.dm index 53db809a9d0..be000619379 100644 --- a/code/modules/mob/living/carbon/alien/larva/larva.dm +++ b/code/modules/mob/living/carbon/alien/larva/larva.dm @@ -18,7 +18,7 @@ //This is fine right now, if we're adding organ specific damage this needs to be updated /mob/living/carbon/alien/larva/New() regenerate_icons() - internal_organs += new /obj/item/organ/internal/alien/plasmavessel/small/tiny + internal_organs += new /obj/item/organ/alien/plasmavessel/small/tiny AddAbility(new/obj/effect/proc_holder/alien/hide(null)) AddAbility(new/obj/effect/proc_holder/alien/larva_evolve(null)) diff --git a/code/modules/mob/living/carbon/alien/larva/life.dm b/code/modules/mob/living/carbon/alien/larva/life.dm index 9728c08e2c6..d63654ce9e7 100644 --- a/code/modules/mob/living/carbon/alien/larva/life.dm +++ b/code/modules/mob/living/carbon/alien/larva/life.dm @@ -17,7 +17,7 @@ if(status_flags & GODMODE) return if(stat != DEAD) - if(health<= -maxHealth || !getorgan(/obj/item/organ/internal/brain)) + if(health<= -maxHealth || !getorgan(/obj/item/organ/brain)) death() return if(paralysis || sleeping || getOxyLoss() > 50 || (status_flags & FAKEDEATH) || health <= config.health_threshold_crit) diff --git a/code/modules/mob/living/carbon/alien/organs.dm b/code/modules/mob/living/carbon/alien/organs.dm index eea07add748..8ac9093906b 100644 --- a/code/modules/mob/living/carbon/alien/organs.dm +++ b/code/modules/mob/living/carbon/alien/organs.dm @@ -1,33 +1,33 @@ -/obj/item/organ/internal/alien +/obj/item/organ/alien origin_tech = "biotech=5" icon_state = "xgibmid2" var/list/alien_powers = list() -/obj/item/organ/internal/alien/New() +/obj/item/organ/alien/New() for(var/A in alien_powers) if(ispath(A)) alien_powers -= A alien_powers += new A(src) ..() -/obj/item/organ/internal/alien/Insert(mob/living/carbon/M, special = 0) +/obj/item/organ/alien/Insert(mob/living/carbon/M, special = 0) ..() for(var/obj/effect/proc_holder/alien/P in alien_powers) M.AddAbility(P) -/obj/item/organ/internal/alien/Remove(mob/living/carbon/M, special = 0) +/obj/item/organ/alien/Remove(mob/living/carbon/M, special = 0) for(var/obj/effect/proc_holder/alien/P in alien_powers) M.RemoveAbility(P) ..() -/obj/item/organ/internal/alien/prepare_eat() +/obj/item/organ/alien/prepare_eat() var/obj/S = ..() S.reagents.add_reagent("sacid", 10) return S -/obj/item/organ/internal/alien/plasmavessel +/obj/item/organ/alien/plasmavessel name = "plasma vessel" icon_state = "plasma" origin_tech = "biotech=5;plasmatech=2" @@ -41,12 +41,12 @@ var/heal_rate = 5 var/plasma_rate = 10 -/obj/item/organ/internal/alien/plasmavessel/prepare_eat() +/obj/item/organ/alien/plasmavessel/prepare_eat() var/obj/S = ..() S.reagents.add_reagent("plasma", storedPlasma/10) return S -/obj/item/organ/internal/alien/plasmavessel/large +/obj/item/organ/alien/plasmavessel/large name = "large plasma vessel" icon_state = "plasma_large" w_class = 4 @@ -54,11 +54,11 @@ max_plasma = 500 plasma_rate = 15 -/obj/item/organ/internal/alien/plasmavessel/large/queen +/obj/item/organ/alien/plasmavessel/large/queen origin_tech = "biotech=6;plasmatech=3" plasma_rate = 20 -/obj/item/organ/internal/alien/plasmavessel/small +/obj/item/organ/alien/plasmavessel/small name = "small plasma vessel" icon_state = "plasma_small" w_class = 2 @@ -66,14 +66,14 @@ max_plasma = 150 plasma_rate = 5 -/obj/item/organ/internal/alien/plasmavessel/small/tiny +/obj/item/organ/alien/plasmavessel/small/tiny name = "tiny plasma vessel" icon_state = "plasma_tiny" w_class = 1 max_plasma = 100 alien_powers = list(/obj/effect/proc_holder/alien/transfer) -/obj/item/organ/internal/alien/plasmavessel/on_life() +/obj/item/organ/alien/plasmavessel/on_life() //If there are alien weeds on the ground then heal if needed or give some plasma if(locate(/obj/structure/alien/weeds) in owner.loc) if(owner.health >= owner.maxHealth) @@ -88,20 +88,20 @@ owner.adjustOxyLoss(-heal_amt) owner.adjustCloneLoss(-heal_amt) -/obj/item/organ/internal/alien/plasmavessel/Insert(mob/living/carbon/M, special = 0) +/obj/item/organ/alien/plasmavessel/Insert(mob/living/carbon/M, special = 0) ..() if(isalien(M)) var/mob/living/carbon/alien/A = M A.updatePlasmaDisplay() -/obj/item/organ/internal/alien/plasmavessel/Remove(mob/living/carbon/M, special = 0) +/obj/item/organ/alien/plasmavessel/Remove(mob/living/carbon/M, special = 0) ..() if(isalien(M)) var/mob/living/carbon/alien/A = M A.updatePlasmaDisplay() -/obj/item/organ/internal/alien/hivenode +/obj/item/organ/alien/hivenode name = "hive node" icon_state = "hivenode" zone = "head" @@ -111,16 +111,16 @@ var/recent_queen_death = 0 //Indicates if the queen died recently, aliens are heavily weakened while this is active. alien_powers = list(/obj/effect/proc_holder/alien/whisper) -/obj/item/organ/internal/alien/hivenode/Insert(mob/living/carbon/M, special = 0) +/obj/item/organ/alien/hivenode/Insert(mob/living/carbon/M, special = 0) ..() M.faction |= "alien" -/obj/item/organ/internal/alien/hivenode/Remove(mob/living/carbon/M, special = 0) +/obj/item/organ/alien/hivenode/Remove(mob/living/carbon/M, special = 0) M.faction -= "alien" ..() //When the alien queen dies, all aliens suffer a penalty as punishment for failing to protect her. -/obj/item/organ/internal/alien/hivenode/proc/queen_death() +/obj/item/organ/alien/hivenode/proc/queen_death() if(!owner|| owner.stat == DEAD) return if(isalien(owner)) //Different effects for aliens than humans @@ -150,7 +150,7 @@ owner.clear_alert("alien_noqueen") -/obj/item/organ/internal/alien/resinspinner +/obj/item/organ/alien/resinspinner name = "resin spinner" icon_state = "stomach-x" zone = "mouth" @@ -159,7 +159,7 @@ alien_powers = list(/obj/effect/proc_holder/alien/resin) -/obj/item/organ/internal/alien/acid +/obj/item/organ/alien/acid name = "acid gland" icon_state = "acid" zone = "mouth" @@ -168,7 +168,7 @@ alien_powers = list(/obj/effect/proc_holder/alien/acid) -/obj/item/organ/internal/alien/neurotoxin +/obj/item/organ/alien/neurotoxin name = "neurotoxin gland" icon_state = "neurotox" zone = "mouth" @@ -177,7 +177,7 @@ alien_powers = list(/obj/effect/proc_holder/alien/neurotoxin) -/obj/item/organ/internal/alien/eggsac +/obj/item/organ/alien/eggsac name = "egg sac" icon_state = "eggsac" zone = "groin" diff --git a/code/modules/mob/living/carbon/alien/say.dm b/code/modules/mob/living/carbon/alien/say.dm index 5d2efa25004..e72008ba098 100644 --- a/code/modules/mob/living/carbon/alien/say.dm +++ b/code/modules/mob/living/carbon/alien/say.dm @@ -16,6 +16,6 @@ ..(message, shown_name) /mob/living/carbon/hivecheck() - var/obj/item/organ/internal/alien/hivenode/N = getorgan(/obj/item/organ/internal/alien/hivenode) + var/obj/item/organ/alien/hivenode/N = getorgan(/obj/item/organ/alien/hivenode) if(N && !N.recent_queen_death) //Mob has alien hive node and is not under the dead queen special effect. return N \ No newline at end of file diff --git a/code/modules/mob/living/carbon/alien/special/alien_embryo.dm b/code/modules/mob/living/carbon/alien/special/alien_embryo.dm index 68d14b3a75b..012c0876cfb 100644 --- a/code/modules/mob/living/carbon/alien/special/alien_embryo.dm +++ b/code/modules/mob/living/carbon/alien/special/alien_embryo.dm @@ -2,13 +2,13 @@ // It functions almost identically (see code/datums/diseases/alien_embryo.dm) var/const/ALIEN_AFK_BRACKET = 450 // 45 seconds -/obj/item/organ/internal/body_egg/alien_embryo +/obj/item/organ/body_egg/alien_embryo name = "alien embryo" icon = 'icons/mob/alien.dmi' icon_state = "larva0_dead" var/stage = 0 -/obj/item/organ/internal/body_egg/alien_embryo/on_find(mob/living/finder) +/obj/item/organ/body_egg/alien_embryo/on_find(mob/living/finder) ..() if(stage < 4) finder << "It's small and weak, barely the size of a foetus." @@ -17,12 +17,12 @@ var/const/ALIEN_AFK_BRACKET = 450 // 45 seconds if(prob(10)) AttemptGrow(0) -/obj/item/organ/internal/body_egg/alien_embryo/prepare_eat() +/obj/item/organ/body_egg/alien_embryo/prepare_eat() var/obj/S = ..() S.reagents.add_reagent("sacid", 10) return S -/obj/item/organ/internal/body_egg/alien_embryo/on_life() +/obj/item/organ/body_egg/alien_embryo/on_life() switch(stage) if(2, 3) if(prob(2)) @@ -50,7 +50,7 @@ var/const/ALIEN_AFK_BRACKET = 450 // 45 seconds owner << "You feel something tearing its way out of your stomach..." owner.adjustToxLoss(10) -/obj/item/organ/internal/body_egg/alien_embryo/egg_process() +/obj/item/organ/body_egg/alien_embryo/egg_process() if(stage < 5 && prob(3)) stage++ spawn(0) @@ -65,7 +65,7 @@ var/const/ALIEN_AFK_BRACKET = 450 // 45 seconds -/obj/item/organ/internal/body_egg/alien_embryo/proc/AttemptGrow(gib_on_success = 1) +/obj/item/organ/body_egg/alien_embryo/proc/AttemptGrow(gib_on_success = 1) if(!owner) return var/list/candidates = get_candidates(ROLE_ALIEN, ALIEN_AFK_BRACKET, "alien candidate") var/client/C = null @@ -110,7 +110,7 @@ var/const/ALIEN_AFK_BRACKET = 450 // 45 seconds Proc: AddInfectionImages(C) Des: Adds the infection image to all aliens for this embryo ----------------------------------------*/ -/obj/item/organ/internal/body_egg/alien_embryo/AddInfectionImages() +/obj/item/organ/body_egg/alien_embryo/AddInfectionImages() for(var/mob/living/carbon/alien/alien in player_list) if(alien.client) var/I = image('icons/mob/alien.dmi', loc = owner, icon_state = "infected[stage]") @@ -120,7 +120,7 @@ Des: Adds the infection image to all aliens for this embryo Proc: RemoveInfectionImage(C) Des: Removes all images from the mob infected by this embryo ----------------------------------------*/ -/obj/item/organ/internal/body_egg/alien_embryo/RemoveInfectionImages() +/obj/item/organ/body_egg/alien_embryo/RemoveInfectionImages() for(var/mob/living/carbon/alien/alien in player_list) if(alien.client) for(var/image/I in alien.client.images) diff --git a/code/modules/mob/living/carbon/alien/special/facehugger.dm b/code/modules/mob/living/carbon/alien/special/facehugger.dm index 08e5d444116..040046a08dd 100644 --- a/code/modules/mob/living/carbon/alien/special/facehugger.dm +++ b/code/modules/mob/living/carbon/alien/special/facehugger.dm @@ -29,6 +29,10 @@ var/const/MAX_ACTIVE_TIME = 400 var/attached = 0 +/obj/item/clothing/mask/facehugger/lamarr + name = "Lamarr" + sterile = 1 + /obj/item/clothing/mask/facehugger/attack_alien(mob/user) //can be picked up by aliens attack_hand(user) return @@ -114,9 +118,9 @@ var/const/MAX_ACTIVE_TIME = 400 attached++ spawn(MAX_IMPREGNATION_TIME) attached = 0 - if(M.getorgan(/obj/item/organ/internal/alien/hivenode)) + if(M.getorgan(/obj/item/organ/alien/hivenode)) return 0 - if(M.getorgan(/obj/item/organ/internal/body_egg/alien_embryo)) + if(M.getorgan(/obj/item/organ/body_egg/alien_embryo)) return 0 if(loc == M) return 0 @@ -179,8 +183,9 @@ var/const/MAX_ACTIVE_TIME = 400 Die() icon_state = "[initial(icon_state)]_impregnated" - if(!target.getlimb(/obj/item/organ/limb/robot/chest) && !target.getorgan(/obj/item/organ/internal/body_egg/alien_embryo)) - new /obj/item/organ/internal/body_egg/alien_embryo(target) + var/obj/item/bodypart/chest/LC = target.get_bodypart("chest") + if((!LC || LC.status != ORGAN_ROBOTIC) && !target.getorgan(/obj/item/organ/body_egg/alien_embryo)) + new /obj/item/organ/body_egg/alien_embryo(target) if(iscorgi(target)) var/mob/living/simple_animal/pet/dog/corgi/C = target @@ -223,7 +228,7 @@ var/const/MAX_ACTIVE_TIME = 400 return 0 if(M.stat == DEAD) return 0 - if(M.getorgan(/obj/item/organ/internal/alien/hivenode)) + if(M.getorgan(/obj/item/organ/alien/hivenode)) return 0 if(iscorgi(M) || ismonkey(M)) diff --git a/code/modules/mob/living/carbon/brain/MMI.dm b/code/modules/mob/living/carbon/brain/MMI.dm index a9ef5f416b0..d5020b6dd6f 100644 --- a/code/modules/mob/living/carbon/brain/MMI.dm +++ b/code/modules/mob/living/carbon/brain/MMI.dm @@ -13,11 +13,11 @@ var/mob/living/carbon/brain/brainmob = null //The current occupant. var/mob/living/silicon/robot = null //Appears unused. var/obj/mecha = null //This does not appear to be used outside of reference in mecha.dm. - var/obj/item/organ/internal/brain/brain = null //The actual brain + var/obj/item/organ/brain/brain = null //The actual brain /obj/item/device/mmi/update_icon() if(brain) - if(istype(brain,/obj/item/organ/internal/brain/alien)) + if(istype(brain,/obj/item/organ/brain/alien)) if(brainmob && brainmob.stat == DEAD) icon_state = "mmi_alien_dead" else @@ -41,8 +41,8 @@ /obj/item/device/mmi/attackby(obj/item/O, mob/user, params) user.changeNext_move(CLICK_CD_MELEE) - if(istype(O,/obj/item/organ/internal/brain)) //Time to stick a brain in it --NEO - var/obj/item/organ/internal/brain/newbrain = O + if(istype(O,/obj/item/organ/brain)) //Time to stick a brain in it --NEO + var/obj/item/organ/brain/newbrain = O if(brain) user << "There's already a brain in the MMI!" return @@ -119,7 +119,7 @@ if(ishuman(L)) var/mob/living/carbon/human/H = L - var/obj/item/organ/internal/brain/newbrain = H.getorgan(/obj/item/organ/internal/brain) + var/obj/item/organ/brain/newbrain = H.getorgan(/obj/item/organ/brain) newbrain.loc = src brain = newbrain else if(!brain) diff --git a/code/modules/mob/living/carbon/brain/brain.dm b/code/modules/mob/living/carbon/brain/brain.dm index 3fd3661ffcf..b51044a221c 100644 --- a/code/modules/mob/living/carbon/brain/brain.dm +++ b/code/modules/mob/living/carbon/brain/brain.dm @@ -12,7 +12,7 @@ /mob/living/carbon/brain/New(loc) ..() if(isturf(loc)) //not spawned in an MMI or brain organ (most likely adminspawned) - var/obj/item/organ/internal/brain/OB = new(loc) //we create a new brain organ for it. + var/obj/item/organ/brain/OB = new(loc) //we create a new brain organ for it. src.loc = OB OB.brainmob = src diff --git a/code/modules/mob/living/carbon/brain/brain_item.dm b/code/modules/mob/living/carbon/brain/brain_item.dm index 81389febbcb..17584a81feb 100644 --- a/code/modules/mob/living/carbon/brain/brain_item.dm +++ b/code/modules/mob/living/carbon/brain/brain_item.dm @@ -1,4 +1,4 @@ -/obj/item/organ/internal/brain +/obj/item/organ/brain name = "brain" desc = "A piece of juicy meat found in a person's head." icon_state = "brain" @@ -13,7 +13,7 @@ var/mob/living/carbon/brain/brainmob = null var/damaged_brain = 0 //whether the brain organ is damaged. -/obj/item/organ/internal/brain/Insert(mob/living/carbon/M, special = 0) +/obj/item/organ/brain/Insert(mob/living/carbon/M, special = 0) ..() name = "brain" if(brainmob) @@ -32,7 +32,7 @@ var/mob/living/carbon/human/H = M H.update_hair(0) -/obj/item/organ/internal/brain/Remove(mob/living/carbon/M, special = 0) +/obj/item/organ/brain/Remove(mob/living/carbon/M, special = 0) ..() if(!special) transfer_identity(M) @@ -40,10 +40,10 @@ var/mob/living/carbon/human/H = M H.update_hair(0) -/obj/item/organ/internal/brain/prepare_eat() +/obj/item/organ/brain/prepare_eat() return // Too important to eat. -/obj/item/organ/internal/brain/proc/transfer_identity(mob/living/L) +/obj/item/organ/brain/proc/transfer_identity(mob/living/L) name = "[L.name]'s brain" brainmob = new(src) brainmob.name = L.real_name @@ -58,12 +58,12 @@ L.mind.transfer_to(brainmob) brainmob << "You feel slightly disoriented. That's normal when you're just a brain." -/obj/item/organ/internal/brain/attackby(obj/item/O, mob/user, params) +/obj/item/organ/brain/attackby(obj/item/O, mob/user, params) user.changeNext_move(CLICK_CD_MELEE) if(brainmob) O.attack(brainmob, user) //Oh noooeeeee -/obj/item/organ/internal/brain/examine(mob/user) +/obj/item/organ/brain/examine(mob/user) ..() if(brainmob) @@ -77,7 +77,7 @@ else user << "This one is completely devoid of life." -/obj/item/organ/internal/brain/attack(mob/living/carbon/M, mob/user) +/obj/item/organ/brain/attack(mob/living/carbon/M, mob/user) if(!istype(M)) return ..() @@ -87,21 +87,22 @@ return ..() var/mob/living/carbon/human/H = M - if(istype(M, /mob/living/carbon/human) && ((H.head && H.head.flags_cover & HEADCOVERSEYES) || (H.wear_mask && H.wear_mask.flags_cover & MASKCOVERSEYES) || (H.glasses && H.glasses.flags & GLASSESCOVERSEYES))) + if(istype(H) && ((H.head && H.head.flags_cover & HEADCOVERSEYES) || (H.wear_mask && H.wear_mask.flags_cover & MASKCOVERSEYES) || (H.glasses && H.glasses.flags & GLASSESCOVERSEYES))) user << "You're going to need to remove their head cover first!" return //since these people will be dead M != usr - if(!M.getorgan(/obj/item/organ/internal/brain)) + if(!M.getorgan(/obj/item/organ/brain)) + if(istype(H) && !H.get_bodypart("head")) + return user.drop_item() - for(var/mob/O in viewers(M, null)) - if(O == (user || M)) - continue - if(M == user) - O << "[user] inserts [src] into \his head!" - else - O << "[M] has [src] inserted into \his head by [user]." + var/msg = "[M] has [src] inserted into \his head by [user]." + if(M == user) + msg = "[user] inserts [src] into \his head!" + + M.visible_message("[msg]", + "[msg]") if(M != user) M << "[user] inserts [src] into your head." @@ -113,13 +114,13 @@ else ..() -/obj/item/organ/internal/brain/Destroy() //copypasted from MMIs. +/obj/item/organ/brain/Destroy() //copypasted from MMIs. if(brainmob) qdel(brainmob) brainmob = null return ..() -/obj/item/organ/internal/brain/alien +/obj/item/organ/brain/alien name = "alien brain" desc = "We barely understand the brains of terrestial animals. Who knows what we may find in the brain of such an advanced species?" icon_state = "brain-x" diff --git a/code/modules/mob/living/carbon/brain/death.dm b/code/modules/mob/living/carbon/brain/death.dm index cf5df7b526a..67b700b2b08 100644 --- a/code/modules/mob/living/carbon/brain/death.dm +++ b/code/modules/mob/living/carbon/brain/death.dm @@ -15,6 +15,6 @@ if(container) qdel(container)//Gets rid of the MMI if there is one if(loc) - if(istype(loc,/obj/item/organ/internal/brain)) + if(istype(loc,/obj/item/organ/brain)) qdel(loc)//Gets rid of the brain item ..() \ No newline at end of file diff --git a/code/modules/mob/living/carbon/brain/life.dm b/code/modules/mob/living/carbon/brain/life.dm index 1e5454f90ee..dc05ef62dbb 100644 --- a/code/modules/mob/living/carbon/brain/life.dm +++ b/code/modules/mob/living/carbon/brain/life.dm @@ -25,10 +25,10 @@ if(health <= config.health_threshold_dead) if(stat != DEAD) death() - var/obj/item/organ/internal/brain/BR + var/obj/item/organ/brain/BR if(container && container.brain) BR = container.brain - else if(istype(loc, /obj/item/organ/internal/brain)) + else if(istype(loc, /obj/item/organ/brain)) BR = loc if(BR) BR.damaged_brain = 1 //beaten to a pulp diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index ef329195264..34d64e5dc01 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -2,24 +2,14 @@ create_reagents(1000) ..() -/mob/living/carbon/prepare_huds() - ..() - prepare_data_huds() - -/mob/living/carbon/proc/prepare_data_huds() - ..() - med_hud_set_health() - med_hud_set_status() - -/mob/living/carbon/updatehealth() - ..() - med_hud_set_health() - /mob/living/carbon/Destroy() for(var/atom/movable/guts in internal_organs) qdel(guts) for(var/atom/movable/food in stomach_contents) qdel(food) + for(var/BP in bodyparts) + qdel(BP) + bodyparts = list() remove_from_all_data_huds() if(dna) qdel(dna) @@ -37,9 +27,9 @@ var/d = rand(round(I.force / 4), I.force) if(istype(src, /mob/living/carbon/human)) var/mob/living/carbon/human/H = src - var/organ = H.get_organ("chest") - if (istype(organ, /obj/item/organ/limb)) - var/obj/item/organ/limb/temp = organ + var/organ = H.get_bodypart("chest") + if (istype(organ, /obj/item/bodypart)) + var/obj/item/bodypart/temp = organ if(temp.take_damage(d, 0)) H.update_damage_overlays(0) H.updatehealth() @@ -511,13 +501,13 @@ I.throw_at(target,I.throw_range,I.throw_speed,src) /mob/living/carbon/emp_act(severity) - for(var/obj/item/organ/internal/O in internal_organs) + for(var/obj/item/organ/O in internal_organs) O.emp_act(severity) ..() /mob/living/carbon/check_eye_prot() var/number = ..() - for(var/obj/item/organ/internal/cyberimp/eyes/EFP in internal_organs) + for(var/obj/item/organ/cyberimp/eyes/EFP in internal_organs) number += EFP.flash_protect return number @@ -541,7 +531,7 @@ /mob/living/carbon/Stat() ..() if(statpanel("Status")) - var/obj/item/organ/internal/alien/plasmavessel/vessel = getorgan(/obj/item/organ/internal/alien/plasmavessel) + var/obj/item/organ/alien/plasmavessel/vessel = getorgan(/obj/item/organ/alien/plasmavessel) if(vessel) stat(null, "Plasma Stored: [vessel.storedPlasma]/[vessel.max_plasma]") if(locate(/obj/item/device/assembly/health) in src) @@ -610,7 +600,7 @@ if(A.update_remote_sight(src)) //returns 1 if we override all other sight updates. return - for(var/obj/item/organ/internal/cyberimp/eyes/E in internal_organs) + for(var/obj/item/organ/cyberimp/eyes/E in internal_organs) sight |= E.sight_flags if(E.dark_view) see_in_dark = max(see_in_dark,E.dark_view) @@ -725,7 +715,7 @@ if(status_flags & GODMODE) return if(stat != DEAD) - if(health<= config.health_threshold_dead || !getorgan(/obj/item/organ/internal/brain)) + if(health<= config.health_threshold_dead || !getorgan(/obj/item/organ/brain)) death() return if(paralysis || sleeping || getOxyLoss() > 50 || (status_flags & FAKEDEATH) || health <= config.health_threshold_crit) @@ -759,7 +749,7 @@ /mob/living/carbon/fully_heal(admin_revive = 0) if(reagents) reagents.clear_reagents() - var/obj/item/organ/internal/brain/B = getorgan(/obj/item/organ/internal/brain) + var/obj/item/organ/brain/B = getorgan(/obj/item/organ/brain) if(B) B.damaged_brain = 0 if(admin_revive) @@ -776,14 +766,14 @@ /mob/living/carbon/can_be_revived() . = ..() - if(!getorgan(/obj/item/organ/internal/brain)) + if(!getorgan(/obj/item/organ/brain)) return 0 /mob/living/carbon/harvest(mob/living/user) if(qdeleted(src)) return var/organs_amt = 0 - for(var/obj/item/organ/internal/O in internal_organs) + for(var/obj/item/organ/O in internal_organs) if(prob(50)) organs_amt++ O.Remove(src) diff --git a/code/modules/mob/living/carbon/carbon_defines.dm b/code/modules/mob/living/carbon/carbon_defines.dm index 544a023160b..5baebc33aec 100644 --- a/code/modules/mob/living/carbon/carbon_defines.dm +++ b/code/modules/mob/living/carbon/carbon_defines.dm @@ -1,8 +1,7 @@ /mob/living/carbon gender = MALE - hud_possible = list(HEALTH_HUD,STATUS_HUD,ANTAG_HUD) var/list/stomach_contents = list() - var/list/internal_organs = list() //List of /obj/item/organ/internal in the mob. They don't go in the contents for some reason I don't want to know. + var/list/internal_organs = list() //List of /obj/item/organ in the mob. They don't go in the contents for some reason I don't want to know. var/list/internal_organs_slot = list() //Same as above, but stores "slot ID" - "organ" pairs for easy access. var/silent = 0 //Can't talk. Value goes down every life proc. //NOTE TO FUTURE CODERS: DO NOT INITIALIZE NUMERICAL VARS AS NULL OR I WILL MURDER YOU. @@ -31,3 +30,5 @@ var/rotate_on_lying = 1 var/tinttotal = 0 // Total level of visualy impairing items + + var/list/bodyparts = list() //Gets filled up in the constructor (New() proc in human.dm and monkey.dm) diff --git a/code/modules/mob/living/carbon/carbon_movement.dm b/code/modules/mob/living/carbon/carbon_movement.dm index 1bd1210c2f7..2e77a20baa8 100644 --- a/code/modules/mob/living/carbon/carbon_movement.dm +++ b/code/modules/mob/living/carbon/carbon_movement.dm @@ -20,7 +20,7 @@ var/const/GALOSHES_DONT_HELP = 4 return 0 // Do we have a jetpack implant (and is it on)? - var/obj/item/organ/internal/cyberimp/chest/thrusters/T = getorganslot("thrusters") + var/obj/item/organ/cyberimp/chest/thrusters/T = getorganslot("thrusters") if(istype(T) && movement_dir && T.allow_thrust(0.01)) return 1 diff --git a/code/modules/mob/living/carbon/death.dm b/code/modules/mob/living/carbon/death.dm index 17b01a33957..3db1d738a96 100644 --- a/code/modules/mob/living/carbon/death.dm +++ b/code/modules/mob/living/carbon/death.dm @@ -1,8 +1,6 @@ /mob/living/carbon/death(gibbed) silent = 0 losebreath = 0 - med_hud_set_health() - med_hud_set_status() ..() /mob/living/carbon/gib(no_brain, no_organs) @@ -14,8 +12,8 @@ ..() /mob/living/carbon/spill_organs(no_brain) - for(var/obj/item/organ/internal/I in internal_organs) - if(no_brain && istype(I, /obj/item/organ/internal/brain)) + for(var/obj/item/organ/I in internal_organs) + if(no_brain && istype(I, /obj/item/organ/brain)) continue if(I) I.Remove(src) diff --git a/code/modules/mob/living/carbon/examine.dm b/code/modules/mob/living/carbon/examine.dm index 1da6b212e10..21f8bdb6cb4 100644 --- a/code/modules/mob/living/carbon/examine.dm +++ b/code/modules/mob/living/carbon/examine.dm @@ -53,7 +53,7 @@ if(digitalcamo) msg += "It is moving its body in an unnatural and blatantly unsimian manner.\n" - if(!getorgan(/obj/item/organ/internal/brain)) + if(!getorgan(/obj/item/organ/brain)) msg += "It appears that it's brain is missing...\n" msg += "*---------*" diff --git a/code/modules/mob/living/carbon/human/blood.dm b/code/modules/mob/living/carbon/human/blood.dm index b80c8ffdc34..f67b3a4008f 100644 --- a/code/modules/mob/living/carbon/human/blood.dm +++ b/code/modules/mob/living/carbon/human/blood.dm @@ -111,12 +111,13 @@ var/const/BLOOD_VOLUME_SURVIVE = 122 //Bleeding out blood_max = 0 - for(var/obj/item/organ/limb/org in organs) - var/brutedamage = org.brute_dam + for(var/X in bodyparts) + var/obj/item/bodypart/BP = X + var/brutedamage = BP.brute_dam //We want an accurate reading of .len - listclearnulls(org.embedded_objects) - blood_max += 0.5*org.embedded_objects.len + listclearnulls(BP.embedded_objects) + blood_max += 0.5*BP.embedded_objects.len if(brutedamage > 30) blood_max += 0.5 @@ -223,10 +224,10 @@ var/const/BLOOD_VOLUME_SURVIVE = 122 var/datum/reagent/blood/our = get_blood(vessel) - if (!injected || !our) + if (!injected || !our || !dna) return - if(blood_incompatible(injected.data["blood_type"],our.data["blood_type"],injected.data["species"],our.data["species"]) ) + if(blood_incompatible(injected.data["blood_type"], dna.blood_type,injected.data["species"], dna.species.id) ) reagents.add_reagent("toxin",amount * 0.5) our.on_merge(injected.data) //still transfer viruses and such, even if incompatibles bloods reagents.update_total() diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm index 5227981c056..68c786f3d10 100644 --- a/code/modules/mob/living/carbon/human/examine.dm +++ b/code/modules/mob/living/carbon/human/examine.dm @@ -94,7 +94,9 @@ else msg += "[t_He] [t_has] \icon[gloves] \a [gloves] on [t_his] hands.\n" else if(blood_DNA) - msg += "[t_He] [t_has] blood-stained hands!\n" + var/hand_number = get_num_arms() + if(hand_number) + msg += "[t_He] [t_has] [hand_number > 1 ? "" : "a"] blood-stained hand[hand_number > 1 ? "s" : ""]!\n" //handcuffed? @@ -169,7 +171,7 @@ var/appears_dead = 0 if(stat == DEAD || (status_flags & FAKEDEATH)) appears_dead = 1 - if(getorgan(/obj/item/organ/internal/brain))//Only perform these checks if there is no brain + if(getorgan(/obj/item/organ/brain))//Only perform these checks if there is no brain if(suiciding) msg += "[t_He] appears to have commited suicide... there is no hope of recovery.\n" msg += "[t_He] [t_is] limp and unresponsive; there are no signs of life" @@ -185,13 +187,26 @@ if(!foundghost) msg += " and [t_his] soul has departed" msg += "...\n" - else//Brain is gone, doesn't matter if they are AFK or present + else if(get_bodypart("head")) //Brain is gone, doesn't matter if they are AFK or present. Check for head first tho. Decapitation has similar message. msg += "It appears that [t_his] brain is missing...\n" var/temp = getBruteLoss() //no need to calculate each of these twice msg += "" + var/list/missing = list("head", "chest", "l_arm", "r_arm", "l_leg", "r_leg") + for(var/X in bodyparts) + var/obj/item/bodypart/BP = X + missing -= BP.body_zone + for(var/obj/item/I in BP.embedded_objects) + msg += "[t_He] [t_has] \a \icon[I] [I] embedded in [t_his] [BP.name]!\n" + + for(var/t in missing) + if(t=="head") + msg += "[capitalize(t_his)] [parse_zone(t)] is missing!\n" + continue + msg += "[capitalize(t_his)] [parse_zone(t)] is missing!\n" + if(temp) if(temp < 30) msg += "[t_He] [t_has] minor bruising.\n" @@ -213,11 +228,6 @@ msg += "[t_He] [t_has] severe cellular damage.\n" - for(var/obj/item/organ/limb/L in organs) - for(var/obj/item/I in L.embedded_objects) - msg += "[t_He] [t_has] \a \icon[I] [I] embedded in [t_his] [L.getDisplayName()]!\n" - - if(fire_stacks > 0) msg += "[t_He] [t_is] covered in something flammable.\n" if(fire_stacks < 0) @@ -269,7 +279,7 @@ else if(getBrainLoss() >= 60) msg += "[t_He] [t_has] a stupid expression on [t_his] face.\n" - if(getorgan(/obj/item/organ/internal/brain)) + if(getorgan(/obj/item/organ/brain)) if(istype(src,/mob/living/carbon/human/interactive)) msg += "[t_He] [t_is] appears to be some sort of sick automaton, [t_his] eyes are glazed over and [t_his] mouth is slightly agape.\n" else if(!key) @@ -285,7 +295,7 @@ if(istype(user, /mob/living/carbon/human)) var/mob/living/carbon/human/H = user - var/obj/item/organ/internal/cyberimp/eyes/hud/CIH = H.getorgan(/obj/item/organ/internal/cyberimp/eyes/hud) + var/obj/item/organ/cyberimp/eyes/hud/CIH = H.getorgan(/obj/item/organ/cyberimp/eyes/hud) if(istype(H.glasses, /obj/item/clothing/glasses/hud) || CIH) var/perpname = get_face_name(get_id_name("")) if(perpname) @@ -294,9 +304,9 @@ msg += "Rank: [R.fields["rank"]]
" msg += "\[Front photo\] " msg += "\[Side photo\]
" - if(istype(H.glasses, /obj/item/clothing/glasses/hud/health) || istype(CIH,/obj/item/organ/internal/cyberimp/eyes/hud/medical)) + if(istype(H.glasses, /obj/item/clothing/glasses/hud/health) || istype(CIH,/obj/item/organ/cyberimp/eyes/hud/medical)) var/implant_detect - for(var/obj/item/organ/internal/cyberimp/CI in internal_organs) + for(var/obj/item/organ/cyberimp/CI in internal_organs) if(CI.status == ORGAN_ROBOTIC) implant_detect += "[name] is modified with a [CI.name].
" if(implant_detect) @@ -312,7 +322,7 @@ msg += "\[Medical evaluation\]
" - if(istype(H.glasses, /obj/item/clothing/glasses/hud/security) || istype(CIH,/obj/item/organ/internal/cyberimp/eyes/hud/security)) + if(istype(H.glasses, /obj/item/clothing/glasses/hud/security) || istype(CIH,/obj/item/organ/cyberimp/eyes/hud/security)) if(!user.stat && user != src) //|| !user.canmove || user.restrained()) Fluff: Sechuds have eye-tracking technology and sets 'arrest' to people that the wearer looks and blinks at. var/criminal = "None" diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 49381eb5445..9ae245d91b8 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -17,6 +17,13 @@ verbs += /mob/living/proc/mob_sleep verbs += /mob/living/proc/lay_down + //initialize limbs first + bodyparts = newlist(/obj/item/bodypart/chest, /obj/item/bodypart/head, /obj/item/bodypart/l_arm, + /obj/item/bodypart/r_arm, /obj/item/bodypart/r_leg, /obj/item/bodypart/l_leg) + for(var/X in bodyparts) + var/obj/item/bodypart/O = X + O.owner = src + //initialize dna. for spawned humans; overwritten by other code create_dna(src) randomize_human(src) @@ -26,18 +33,14 @@ set_species(dna.species.type) //initialise organs - organs = newlist(/obj/item/organ/limb/chest, /obj/item/organ/limb/head, /obj/item/organ/limb/l_arm, - /obj/item/organ/limb/r_arm, /obj/item/organ/limb/r_leg, /obj/item/organ/limb/l_leg) - for(var/obj/item/organ/limb/O in organs) - O.owner = src - internal_organs += new /obj/item/organ/internal/appendix - internal_organs += new /obj/item/organ/internal/lungs - internal_organs += new /obj/item/organ/internal/heart - internal_organs += new /obj/item/organ/internal/brain + internal_organs += new /obj/item/organ/appendix + internal_organs += new /obj/item/organ/lungs + internal_organs += new /obj/item/organ/heart + internal_organs += new /obj/item/organ/brain //Note: Additional organs are generated/replaced on the dna.species level - for(var/obj/item/organ/internal/I in internal_organs) + for(var/obj/item/organ/I in internal_organs) I.Insert(src) make_blood() @@ -56,12 +59,6 @@ //...and display them. add_to_all_human_data_huds() -/mob/living/carbon/human/Destroy() - for(var/atom/movable/organelle in organs) - qdel(organelle) - organs = list() - return ..() - /mob/living/carbon/human/Stat() ..() @@ -113,10 +110,12 @@ /mob/living/carbon/human/ex_act(severity, ex_target) var/b_loss = null var/f_loss = null + var/bomb_armor = getarmor(null, "bomb") + switch (severity) if (1) b_loss += 500 - if (prob(getarmor(null, "bomb"))) + if (prob(bomb_armor)) shred_clothing(1,150) var/atom/target = get_edge_target_turf(src, get_dir(src, get_step_away(src, src))) throw_at(target, 200, 4) @@ -128,7 +127,7 @@ b_loss += 60 f_loss += 60 - if (prob(getarmor(null, "bomb"))) + if (prob(bomb_armor)) b_loss = b_loss/1.5 f_loss = f_loss/1.5 shred_clothing(1,25) @@ -142,7 +141,7 @@ if(3) b_loss += 30 - if (prob(getarmor(null, "bomb"))) + if (prob(bomb_armor)) b_loss = b_loss/2 if (!istype(ears, /obj/item/clothing/ears/earmuffs)) adjustEarDamage(15,60) @@ -150,7 +149,16 @@ Paralyse(10) take_overall_damage(b_loss,f_loss) - + //attempt to dismember bodyparts + if(severity >= 2 || !bomb_armor) + var/max_limb_loss = round(4/severity) //so you don't lose four limbs at severity 3. + for(var/X in bodyparts) + var/obj/item/bodypart/BP = X + if(prob(50/severity) && !prob(getarmor(BP, "bomb")) && BP.body_zone != "head" && BP.body_zone != "chest") + BP.dismember() + max_limb_loss-- + if(!max_limb_loss) + break ..() /mob/living/carbon/human/blob_act(obj/effect/blob/B) @@ -158,7 +166,7 @@ return show_message("The blob attacks you!") var/dam_zone = pick("chest", "l_hand", "r_hand", "l_leg", "r_leg") - var/obj/item/organ/limb/affecting = get_organ(ran_zone(dam_zone)) + var/obj/item/bodypart/affecting = get_bodypart(ran_zone(dam_zone)) apply_damage(5, BRUTE, affecting, run_armor_check(affecting, "melee")) return @@ -172,6 +180,11 @@ return 0 ..() +/mob/living/carbon/human/attack_ui(slot) + if(!get_bodypart(hand ? "l_arm" : "r_arm")) + return 0 + return ..() + /mob/living/carbon/human/show_inv(mob/user) user.set_machine(src) var/has_breathable_mask = istype(wear_mask, /obj/item/clothing/mask) @@ -304,11 +317,11 @@ if(href_list["embedded_object"]) var/obj/item/I = locate(href_list["embedded_object"]) - var/obj/item/organ/limb/L = locate(href_list["embedded_limb"]) + var/obj/item/bodypart/L = locate(href_list["embedded_limb"]) if(!I || !L || I.loc != src || !(I in L.embedded_objects)) //no item, no limb, or item is not in limb or in the person anymore return var/time_taken = I.embedded_unsafe_removal_time*I.w_class - usr.visible_message("[usr] attempts to remove [I] from their [L.getDisplayName()].","You attempt to remove [I] from your [L.getDisplayName()]... (It will take [time_taken/10] seconds.)") + usr.visible_message("[usr] attempts to remove [I] from their [L.name].","You attempt to remove [I] from your [L.name]... (It will take [time_taken/10] seconds.)") if(do_after(usr, time_taken, needhand = 1, target = src)) if(!I || !L || I.loc != src || !(I in L.embedded_objects)) return @@ -317,7 +330,7 @@ I.loc = get_turf(src) usr.put_in_hands(I) usr.emote("scream") - usr.visible_message("[usr] successfully rips [I] out of their [L.getDisplayName()]!","You successfully remove [I] from your [L.getDisplayName()].") + usr.visible_message("[usr] successfully rips [I] out of their [L.name]!","You successfully remove [I] from your [L.name].") if(!has_embedded_objects()) clear_alert("embeddedobject") return @@ -415,8 +428,9 @@ var/status = "" if(getBruteLoss()) usr << "Physical trauma analysis:" - for(var/obj/item/organ/limb/org in organs) - var/brutedamage = org.brute_dam + for(var/X in bodyparts) + var/obj/item/bodypart/BP = X + var/brutedamage = BP.brute_dam if(brutedamage > 0) status = "received minor physical injuries." span = "notice" @@ -427,11 +441,12 @@ status = "sustained major trauma!" span = "userdanger" if(brutedamage) - usr << "The [org.getDisplayName()] appears to have [status]" + usr << "[BP] appears to have [status]" if(getFireLoss()) usr << "Analysis of skin burns:" - for(var/obj/item/organ/limb/org in organs) - var/burndamage = org.burn_dam + for(var/X in bodyparts) + var/obj/item/bodypart/BP = X + var/burndamage = BP.burn_dam if(burndamage > 0) status = "signs of minor burns." span = "notice" @@ -442,7 +457,7 @@ status = "major burns!" span = "userdanger" if(burndamage) - usr << "The [org.getDisplayName()] appears to have [status]" + usr << "[BP] appears to have [status]" if(getOxyLoss()) usr << "Patient has signs of suffocation, emergency treatment may be required!" if(getToxLoss() > 20) @@ -576,7 +591,7 @@ . = 1 // Default to returning true. if(user && !target_zone) target_zone = user.zone_selected - if(dna && PIERCEIMMUNE in dna.species.specflags) + if(dna && (PIERCEIMMUNE in dna.species.specflags)) . = 0 // If targeting the head, see if the head item is thin enough. // If targeting anything else, see if the wear suit is thin enough. @@ -736,10 +751,13 @@ "[src] examines \himself.", \ "You check yourself for injuries.") - for(var/obj/item/organ/limb/org in organs) + var/list/missing = list("head", "chest", "l_arm", "r_arm", "l_leg", "r_leg") + for(var/X in bodyparts) + var/obj/item/bodypart/LB = X + missing -= LB.body_zone var/status = "" - var/brutedamage = org.brute_dam - var/burndamage = org.burn_dam + var/brutedamage = LB.brute_dam + var/burndamage = LB.burn_dam if(hallucination) if(prob(30)) brutedamage += rand(30,40) @@ -763,10 +781,13 @@ status += "numb" if(status == "") status = "OK" - src << "\t [status == "OK" ? "\blue" : "\red"] Your [org.getDisplayName()] is [status]." + src << "\t [status == "OK" ? "\blue" : "\red"] Your [LB.name] is [status]." - for(var/obj/item/I in org.embedded_objects) - src << "\t \red There is \a [I] embedded in your [org.getDisplayName()]!" + for(var/obj/item/I in LB.embedded_objects) + src << "\t \red There is \a [I] embedded in your [LB.name]!" + + for(var/t in missing) + src << "Your [parse_zone(t)] is missing!" if(blood_max) src << "You are bleeding!" @@ -857,16 +878,9 @@ /mob/living/carbon/human/proc/electrocution_animation(anim_duration) //Handle mutant parts if possible if(dna && dna.species) - dna.species.handle_mutant_bodyparts(src,"black") - dna.species.handle_hair(src,"black") - dna.species.update_color(src,"black") overlays += "electrocuted_base" spawn(anim_duration) if(src) - if(dna && dna.species) - dna.species.handle_mutant_bodyparts(src) - dna.species.handle_hair(src) - dna.species.update_color(src) overlays -= "electrocuted_base" else //or just do a generic animation @@ -936,9 +950,10 @@ hud_used.healthdoll.overlays.Cut() if(stat != DEAD) hud_used.healthdoll.icon_state = "healthdoll_OVERLAY" - for(var/obj/item/organ/limb/L in organs) - var/damage = L.burn_dam + L.brute_dam - var/comparison = (L.max_damage/5) + for(var/X in bodyparts) + var/obj/item/bodypart/BP = X + var/damage = BP.burn_dam + BP.brute_dam + var/comparison = (BP.max_damage/5) var/icon_num = 0 if(damage) icon_num = 1 @@ -953,16 +968,20 @@ if(hal_screwyhud == 5) icon_num = 0 if(icon_num) - hud_used.healthdoll.overlays += image('icons/mob/screen_gen.dmi',"[L.name][icon_num]") + hud_used.healthdoll.overlays += image('icons/mob/screen_gen.dmi',"[BP.body_zone][icon_num]") + for(var/t in get_missing_limbs()) //Missing limbs + hud_used.healthdoll.overlays += image('icons/mob/screen_gen.dmi',"[t]6") else hud_used.healthdoll.icon_state = "healthdoll_DEAD" /mob/living/carbon/human/fully_heal(admin_revive = 0) + if(admin_revive) + regenerate_limbs() if(!getorganslot("lungs")) - var/obj/item/organ/internal/lungs/L = new() + var/obj/item/organ/lungs/L = new() L.Insert(src) if(!getorganslot("tongue")) - var/obj/item/organ/internal/tongue/T = new() + var/obj/item/organ/tongue/T = new() T.Insert(src) restore_blood() remove_all_embedded_objects() diff --git a/code/modules/mob/living/carbon/human/human_attackalien.dm b/code/modules/mob/living/carbon/human/human_attackalien.dm index 10e19dfd198..3f7acda2524 100644 --- a/code/modules/mob/living/carbon/human/human_attackalien.dm +++ b/code/modules/mob/living/carbon/human/human_attackalien.dm @@ -13,7 +13,7 @@ visible_message("[M] has lunged at [src]!", \ "[M] has lunged at [src]!") return 0 - var/obj/item/organ/limb/affecting = get_organ(ran_zone(M.zone_selected)) + var/obj/item/bodypart/affecting = get_bodypart(ran_zone(M.zone_selected)) var/armor_block = run_armor_check(affecting, "melee","","",10) playsound(loc, 'sound/weapons/slice.ogg', 25, 1, -1) diff --git a/code/modules/mob/living/carbon/human/human_attackpaw.dm b/code/modules/mob/living/carbon/human/human_attackpaw.dm index 54c47761514..63dcd230169 100644 --- a/code/modules/mob/living/carbon/human/human_attackpaw.dm +++ b/code/modules/mob/living/carbon/human/human_attackpaw.dm @@ -1,6 +1,6 @@ /mob/living/carbon/human/attack_paw(mob/living/carbon/monkey/M) var/dam_zone = pick("chest", "l_hand", "r_hand", "l_leg", "r_leg") - var/obj/item/organ/limb/affecting = get_organ(ran_zone(dam_zone)) + var/obj/item/bodypart/affecting = get_bodypart(ran_zone(dam_zone)) if(M.a_intent == "help") ..() //shaking diff --git a/code/modules/mob/living/carbon/human/human_damage.dm b/code/modules/mob/living/carbon/human/human_damage.dm index f7e020147e1..ca45f109c58 100644 --- a/code/modules/mob/living/carbon/human/human_damage.dm +++ b/code/modules/mob/living/carbon/human/human_damage.dm @@ -1,15 +1,16 @@ -//Updates the mob's health from organs and mob damage variables +//Updates the mob's health from bodyparts and mob damage variables /mob/living/carbon/human/updatehealth() if(status_flags & GODMODE) return var/total_burn = 0 var/total_brute = 0 - for(var/obj/item/organ/limb/O in organs) //hardcoded to streamline things a bit - total_brute += O.brute_dam - total_burn += O.burn_dam + for(var/X in bodyparts) //hardcoded to streamline things a bit + var/obj/item/bodypart/BP = X + total_brute += BP.brute_dam + total_burn += BP.burn_dam health = maxHealth - getOxyLoss() - getToxLoss() - getCloneLoss() - total_burn - total_brute update_stat() - if( ((maxHealth - total_burn) < config.health_threshold_dead) && stat == DEAD ) + if(((maxHealth - total_burn) < config.health_threshold_dead) && stat == DEAD ) ChangeToHusk() if(on_fire) shred_clothing() @@ -17,17 +18,19 @@ med_hud_set_status() -//These procs fetch a cumulative total damage from all organs +//These procs fetch a cumulative total damage from all bodyparts /mob/living/carbon/human/getBruteLoss() var/amount = 0 - for(var/obj/item/organ/limb/O in organs) - amount += O.brute_dam + for(var/X in bodyparts) + var/obj/item/bodypart/BP = X + amount += BP.brute_dam return amount /mob/living/carbon/human/getFireLoss() var/amount = 0 - for(var/obj/item/organ/limb/O in organs) - amount += O.burn_dam + for(var/X in bodyparts) + var/obj/item/bodypart/BP = X + amount += BP.burn_dam return amount @@ -59,30 +62,32 @@ //////////////////////////////////////////// -//Returns a list of damaged organs -/mob/living/carbon/human/proc/get_damaged_organs(brute, burn) - var/list/obj/item/organ/limb/parts = list() - for(var/obj/item/organ/limb/O in organs) - if((brute && O.brute_dam) || (burn && O.burn_dam)) - parts += O +//Returns a list of damaged bodyparts +/mob/living/carbon/human/proc/get_damaged_bodyparts(brute, burn) + var/list/obj/item/bodypart/parts = list() + for(var/X in bodyparts) + var/obj/item/bodypart/BP = X + if((brute && BP.brute_dam) || (burn && BP.burn_dam)) + parts += BP return parts -//Returns a list of damageable organs -/mob/living/carbon/human/proc/get_damageable_organs() - var/list/obj/item/organ/limb/parts = list() - for(var/obj/item/organ/limb/O in organs) - if(O.brute_dam + O.burn_dam < O.max_damage) - parts += O +//Returns a list of damageable bodyparts +/mob/living/carbon/human/proc/get_damageable_bodyparts() + var/list/obj/item/bodypart/parts = list() + for(var/X in bodyparts) + var/obj/item/bodypart/BP = X + if(BP.brute_dam + BP.burn_dam < BP.max_damage) + parts += BP return parts //Heals ONE external organ, organ gets randomly selected from damaged ones. //It automatically updates damage overlays if necesary //It automatically updates health status /mob/living/carbon/human/heal_organ_damage(brute, burn) - var/list/obj/item/organ/limb/parts = get_damaged_organs(brute,burn) + var/list/obj/item/bodypart/parts = get_damaged_bodyparts(brute,burn) if(!parts.len) return - var/obj/item/organ/limb/picked = pick(parts) + var/obj/item/bodypart/picked = pick(parts) if(picked.heal_damage(brute,burn,0)) update_damage_overlays(0) updatehealth() @@ -91,22 +96,22 @@ //It automatically updates damage overlays if necesary //It automatically updates health status /mob/living/carbon/human/take_organ_damage(brute, burn) - var/list/obj/item/organ/limb/parts = get_damageable_organs() + var/list/obj/item/bodypart/parts = get_damageable_bodyparts() if(!parts.len) return - var/obj/item/organ/limb/picked = pick(parts) + var/obj/item/bodypart/picked = pick(parts) if(picked.take_damage(brute,burn)) update_damage_overlays(0) updatehealth() -//Heal MANY external organs, in random order +//Heal MANY bodyparts, in random order /mob/living/carbon/human/heal_overall_damage(brute, burn, updating_health=1) - var/list/obj/item/organ/limb/parts = get_damaged_organs(brute,burn) + var/list/obj/item/bodypart/parts = get_damaged_bodyparts(brute,burn) var/update = 0 while(parts.len && (brute>0 || burn>0) ) - var/obj/item/organ/limb/picked = pick(parts) + var/obj/item/bodypart/picked = pick(parts) var/brute_was = picked.brute_dam var/burn_was = picked.burn_dam @@ -122,15 +127,15 @@ if(update) update_damage_overlays(0) -// damage MANY external organs, in random order +// damage MANY bodyparts, in random order /mob/living/carbon/human/take_overall_damage(brute, burn) if(status_flags & GODMODE) return //godmode - var/list/obj/item/organ/limb/parts = get_damageable_organs() + var/list/obj/item/bodypart/parts = get_damageable_bodyparts() var/update = 0 while(parts.len && (brute>0 || burn>0) ) - var/obj/item/organ/limb/picked = pick(parts) + var/obj/item/bodypart/picked = pick(parts) var/brute_per_part = brute/parts.len var/burn_per_part = burn/parts.len @@ -156,15 +161,6 @@ //////////////////////////////////////////// -/mob/living/carbon/human/proc/get_organ(zone) - if(!zone) - zone = "chest" - for(var/obj/item/organ/limb/O in organs) - if(O.name == zone) - return O - return null - - /mob/living/carbon/human/apply_damage(damage = 0,damagetype = BRUTE, def_zone = null, blocked = 0) // depending on the species, it will run the corresponding apply_damage code there return dna.species.apply_damage(damage, damagetype, def_zone, blocked, src) diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index 88069a6498f..7eab6c1d4f0 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -5,18 +5,19 @@ if(def_zone) if(islimb(def_zone)) return checkarmor(def_zone, type) - var/obj/item/organ/limb/affecting = get_organ(ran_zone(def_zone)) + var/obj/item/bodypart/affecting = get_bodypart(ran_zone(def_zone)) return checkarmor(affecting, type) //If a specific bodypart is targetted, check how that bodypart is protected and return the value. //If you don't specify a bodypart, it checks ALL your bodyparts for protection, and averages out the values - for(var/obj/item/organ/limb/organ in organs) - armorval += checkarmor(organ, type) + for(var/X in bodyparts) + var/obj/item/bodypart/BP = X + armorval += checkarmor(BP, type) organnum++ return (armorval/max(organnum, 1)) -/mob/living/carbon/human/proc/checkarmor(obj/item/organ/limb/def_zone, type) +/mob/living/carbon/human/proc/checkarmor(obj/item/bodypart/def_zone, type) if(!type) return 0 var/protection = 0 @@ -94,23 +95,21 @@ return 0 -/mob/living/carbon/human/attacked_by(obj/item/I, mob/living/user, def_zone) +/mob/living/carbon/human/attacked_by(obj/item/I, mob/living/user) if(!I || !user) return 0 - var/obj/item/organ/limb/target_limb = get_organ(check_zone(user.zone_selected)) - var/obj/item/organ/limb/affecting = get_organ(ran_zone(user.zone_selected)) - var/hit_area = parse_zone(affecting.name) - var/target_area = parse_zone(target_limb.name) + var/obj/item/bodypart/affecting = get_bodypart(ran_zone(user.zone_selected)) + var/target_area = parse_zone(check_zone(user.zone_selected)) feedback_add_details("item_used_for_combat","[I.type]|[I.force]") feedback_add_details("zone_targeted","[target_area]") // the attacked_by code varies among species - return dna.species.spec_attacked_by(I, user, def_zone, affecting, hit_area, a_intent, target_limb, target_area, src) + return dna.species.spec_attacked_by(I, user, affecting, a_intent, target_area, src) /mob/living/carbon/human/emp_act(severity) var/informed = 0 - for(var/obj/item/organ/limb/L in src.organs) + for(var/obj/item/bodypart/L in src.bodyparts) if(L.status == ORGAN_ROBOTIC) if(!informed) src << "You feel a sharp pain as your robotic limbs overload." @@ -149,7 +148,7 @@ else src << "Your [head_clothes.name] protects your head and face from the acid!" else - . = get_organ("head") + . = get_bodypart("head") if(.) damaged += . if(ears) @@ -170,7 +169,7 @@ else src << "Your [chest_clothes.name] protects your body from the acid!" else - . = get_organ("chest") + . = get_bodypart("chest") if(.) damaged += . if(wear_id) @@ -201,10 +200,10 @@ else src << "Your [arm_clothes.name] protects your arms and hands from the acid!" else - . = get_organ("r_arm") + . = get_bodypart("r_arm") if(.) damaged += . - . = get_organ("l_arm") + . = get_bodypart("l_arm") if(.) damaged += . @@ -227,16 +226,16 @@ else src << "Your [leg_clothes.name] protects your legs and feet from the acid!" else - . = get_organ("r_leg") + . = get_bodypart("r_leg") if(.) damaged += . - . = get_organ("l_leg") + . = get_bodypart("l_leg") if(.) damaged += . //DAMAGE// - for(var/obj/item/organ/limb/affecting in damaged) + for(var/obj/item/bodypart/affecting in damaged) affecting.take_damage(acidity, 2*acidity) if(affecting.name == "head") @@ -277,7 +276,7 @@ if(check_shields(damage, "the [M.name]", null, MELEE_ATTACK, M.armour_penetration)) return 0 var/dam_zone = pick("chest", "l_hand", "r_hand", "l_leg", "r_leg") - var/obj/item/organ/limb/affecting = get_organ(ran_zone(dam_zone)) + var/obj/item/bodypart/affecting = get_bodypart(ran_zone(dam_zone)) var/armor = run_armor_check(affecting, "melee") apply_damage(damage, M.melee_damage_type, affecting, armor, "", "", M.armour_penetration) updatehealth() @@ -291,7 +290,7 @@ return 0 if(stat != DEAD) L.amount_grown = min(L.amount_grown + damage, L.max_grown) - var/obj/item/organ/limb/affecting = get_organ(ran_zone(L.zone_selected)) + var/obj/item/bodypart/affecting = get_bodypart(ran_zone(L.zone_selected)) var/armor_block = run_armor_check(affecting, "melee") apply_damage(damage, BRUTE, affecting, armor_block) updatehealth() @@ -308,7 +307,7 @@ var/dam_zone = pick("head", "chest", "l_arm", "r_arm", "l_leg", "r_leg", "groin") - var/obj/item/organ/limb/affecting = get_organ(ran_zone(dam_zone)) + var/obj/item/bodypart/affecting = get_bodypart(ran_zone(dam_zone)) var/armor_block = run_armor_check(affecting, "melee") apply_damage(damage, BRUTE, affecting, armor_block) @@ -318,7 +317,7 @@ M.do_attack_animation(src) if(M.damtype == "brute") step_away(src,M,15) - var/obj/item/organ/limb/temp = get_organ(pick("chest", "chest", "chest", "head")) + var/obj/item/bodypart/temp = get_bodypart(pick("chest", "chest", "chest", "head")) if(temp) var/update = 0 switch(M.damtype) @@ -360,12 +359,12 @@ if(can_embed(I)) if(prob(I.embed_chance) && !(dna && (PIERCEIMMUNE in dna.species.specflags))) throw_alert("embeddedobject", /obj/screen/alert/embeddedobject) - var/obj/item/organ/limb/L = pick(organs) + var/obj/item/bodypart/L = pick(bodyparts) L.embedded_objects |= I I.add_blood(src)//it embedded itself in you, of course it's bloody! I.loc = src L.take_damage(I.w_class*I.embedded_impact_pain_multiplier) - visible_message("\the [I.name] embeds itself in [src]'s [L.getDisplayName()]!","\the [I.name] embeds itself in your [L.getDisplayName()]!") + visible_message("\the [I.name] embeds itself in [src]'s [L.name]!","\the [I.name] embeds itself in your [L.name]!") hitpush = 0 skipcatch = 1 //can't catch the now embedded item diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm index af9cdb04fb0..150dfeca61b 100644 --- a/code/modules/mob/living/carbon/human/human_defines.dm +++ b/code/modules/mob/living/carbon/human/human_defines.dm @@ -47,8 +47,6 @@ var/global/default_martial_art = new/datum/martial_art var/blood_max = 0 //how much are we bleeding var/bleedsuppress = 0 //for stopping bloodloss, eventually this will be limb-based like bleeding - var/list/organs = list() //Gets filled up in the constructor (human.dm, New() proc. - var/datum/martial_art/martial_art = null var/name_override //For temporary visible name changes diff --git a/code/modules/mob/living/carbon/human/human_helpers.dm b/code/modules/mob/living/carbon/human/human_helpers.dm index ce5ba1cba23..642f86d9903 100644 --- a/code/modules/mob/living/carbon/human/human_helpers.dm +++ b/code/modules/mob/living/carbon/human/human_helpers.dm @@ -55,7 +55,7 @@ return if_no_face if( head && (head.flags_inv&HIDEFACE) ) return if_no_face //Likewise for hats - var/obj/item/organ/limb/O = get_organ("head") + var/obj/item/bodypart/O = get_bodypart("head") if( !O || (status_flags&DISFIGURED) || (O.brutestate+O.burnstate)>2 || cloneloss>50 || !real_name ) //disfigured. use id-name if possible return if_no_face return real_name diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index 6fb70500d4d..10b12f5425b 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -214,7 +214,7 @@ if(dna.check_mutation(COLDRES)) return 1 //Fully protected from the cold. - if(dna && COLDRES in dna.species.specflags) + if(dna && (RESISTCOLD in dna.species.specflags)) return 1 temperature = max(temperature, 2.7) //There is an occasional bug where the temperature is miscalculated in ares with a small amount of gas on them, so this is necessary to ensure that that bug does not affect this calculation. Space's temperature is 2.7K and most suits that are intended to protect against any cold, protect down to 2.0K. @@ -289,17 +289,18 @@ . = 1 return . /mob/living/carbon/human/proc/handle_embedded_objects() - for(var/obj/item/organ/limb/L in organs) - for(var/obj/item/I in L.embedded_objects) + for(var/X in bodyparts) + var/obj/item/bodypart/BP = X + for(var/obj/item/I in BP.embedded_objects) if(prob(I.embedded_pain_chance)) - L.take_damage(I.w_class*I.embedded_pain_multiplier) - src << "\the [I] embedded in your [L.getDisplayName()] hurts!" + BP.take_damage(I.w_class*I.embedded_pain_multiplier) + src << "\the [I] embedded in your [BP.name] hurts!" if(prob(I.embedded_fall_chance)) - L.take_damage(I.w_class*I.embedded_fall_pain_multiplier) - L.embedded_objects -= I + BP.take_damage(I.w_class*I.embedded_fall_pain_multiplier) + BP.embedded_objects -= I I.loc = get_turf(src) - visible_message("\the [I] falls out of [name]'s [L.getDisplayName()]!","\the [I] falls out of your [L.getDisplayName()]!") + visible_message("\the [I] falls out of [name]'s [BP.name]!","\the [I] falls out of your [BP.name]!") if(!has_embedded_objects()) clear_alert("embeddedobject") diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm index bb5376c35a8..a9bfdce73cb 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -41,7 +41,7 @@ var/say_mod = "says" // affects the speech message var/list/default_features = list() // Default mutant bodyparts for this species. Don't forget to set one for every mutant bodypart you allow this species to have. var/list/mutant_bodyparts = list() // Parts of the body that are diferent enough from the standard human model that they cause clipping with some equipment - var/list/mutant_organs = list(/obj/item/organ/internal/tongue) //Internal organs that are unique to this race. + var/list/mutant_organs = list(/obj/item/organ/tongue) //Internal organs that are unique to this race. var/speedmod = 0 // this affects the race's speed. positive numbers make it move slower, negative numbers make it move faster var/armor = 0 // overall defense for the race... or less defense, if it's negative. var/brutemod = 1 // multiplier for brute damage @@ -83,6 +83,8 @@ var/tox_breath_dam_min = MIN_PLASMA_DAMAGE var/tox_breath_dam_max = MAX_PLASMA_DAMAGE + var/has_dismemberment = 1 //Whether or not this species uses dismemberment for its limbs + /////////// // PROCS // /////////// @@ -125,10 +127,12 @@ var/obj/item/thing = C.get_item_by_slot(slot_id) if(thing) C.unEquip(thing) + if(!has_dismemberment) + C.regenerate_limbs() //if we don't handle dismemberment, we grow our missing limbs back if(exotic_blood) C.reagents.add_reagent(exotic_blood, 80) for(var/path in mutant_organs) - var/obj/item/organ/internal/I = new path() + var/obj/item/organ/I = new path() I.Insert(C) /datum/species/proc/on_species_loss(mob/living/carbon/C) @@ -148,6 +152,8 @@ return "[id]" /datum/species/proc/update_color(mob/living/carbon/human/H, forced_colour) + if(has_dismemberment) //only species without dismemberment still use base icon states. + return H.remove_overlay(SPECIES_LAYER) var/image/standing @@ -185,6 +191,11 @@ /datum/species/proc/handle_hair(mob/living/carbon/human/H, forced_colour) H.remove_overlay(HAIR_LAYER) + + var/obj/item/bodypart/head/HD = H.get_bodypart("head") + if(!HD) //Decapitated + return + if(H.disabilities & HUSK) return var/datum/sprite_accessory/S @@ -204,9 +215,7 @@ if(H.facial_hair_style && (FACEHAIR in specflags) && !facialhair_hidden) S = facial_hair_styles_list[H.facial_hair_style] if(S) - var/image/img_facial_s - - img_facial_s = image("icon" = S.icon, "icon_state" = "[S.icon_state]_s", "layer" = -HAIR_LAYER) + var/image/img_facial_s = image("icon" = S.icon, "icon_state" = "[S.icon_state]_s", "layer" = -HAIR_LAYER) if(!forced_colour) if(hair_color) @@ -233,7 +242,7 @@ if(M.flags_inv & HIDEHAIR) hair_hidden = 1 if(!hair_hidden) - if(!H.getorgan(/obj/item/organ/internal/brain)) //Applies the debrained overlay if there is no brain + if(!H.getorgan(/obj/item/organ/brain)) //Applies the debrained overlay if there is no brain standing += image("icon"='icons/mob/human_face.dmi', "icon_state" = "debrained_s", "layer" = -HAIR_LAYER) else if(H.hair_style && (HAIR in specflags)) @@ -267,16 +276,24 @@ var/list/standing = list() + if(!has_dismemberment) //Legacy support + H.update_base_icon_state() + if(!(H.disabilities & HUSK)) + update_color(H) + + handle_mutant_bodyparts(H) + var/obj/item/bodypart/head/HD = H.get_bodypart("head") + // lipstick - if(H.lip_style && LIPS in specflags) + if(H.lip_style && (LIPS in specflags) && HD) var/image/lips = image("icon"='icons/mob/human_face.dmi', "icon_state"="lips_[H.lip_style]_s", "layer" = -BODY_LAYER) lips.color = H.lip_color standing += lips // eyes - if(EYECOLOR in specflags) + if((EYECOLOR in specflags) && HD) var/image/img_eyes_s = image("icon" = 'icons/mob/human_face.dmi', "icon_state" = "[eyes]_s", "layer" = -BODY_LAYER) img_eyes_s.color = "#" + H.eye_color standing += img_eyes_s @@ -295,7 +312,7 @@ else standing += image("icon"=U2.icon, "icon_state"="[U2.icon_state]_s", "layer"=-BODY_LAYER) - if(H.socks) + if(H.socks && H.get_num_legs() >= 2) var/datum/sprite_accessory/socks/U3 = socks_list[H.socks] if(U3) standing += image("icon"=U3.icon, "icon_state"="[U3.icon_state]_s", "layer"=-BODY_LAYER) @@ -319,6 +336,8 @@ if(!mutant_bodyparts) return + var/obj/item/bodypart/head/HD = H.get_bodypart("head") + if("tail_lizard" in mutant_bodyparts) if(H.wear_suit && (H.wear_suit.flags_inv & HIDEJUMPSUIT)) bodyparts_to_add -= "tail_lizard" @@ -351,19 +370,19 @@ bodyparts_to_add -= "waggingspines" if("snout" in mutant_bodyparts) //Take a closer look at that snout! - if((H.wear_mask && (H.wear_mask.flags_inv & HIDEFACE)) || (H.head && (H.head.flags_inv & HIDEFACE))) + if((H.wear_mask && (H.wear_mask.flags_inv & HIDEFACE)) || (H.head && (H.head.flags_inv & HIDEFACE)) || !HD || HD.status == ORGAN_ROBOTIC) bodyparts_to_add -= "snout" if("frills" in mutant_bodyparts) - if(!H.dna.features["frills"] || H.dna.features["frills"] == "None" || H.head && (H.head.flags_inv & HIDEEARS)) + if(!H.dna.features["frills"] || H.dna.features["frills"] == "None" || H.head && (H.head.flags_inv & HIDEEARS) || !HD || HD.status == ORGAN_ROBOTIC) bodyparts_to_add -= "frills" if("horns" in mutant_bodyparts) - if(!H.dna.features["horns"] || H.dna.features["horns"] == "None" || H.head && (H.head.flags_inv & HIDEHAIR) || (H.wear_mask && (H.wear_mask.flags_inv & HIDEHAIR))) + if(!H.dna.features["horns"] || H.dna.features["horns"] == "None" || H.head && (H.head.flags_inv & HIDEHAIR) || (H.wear_mask && (H.wear_mask.flags_inv & HIDEHAIR)) || !HD || HD.status == ORGAN_ROBOTIC) bodyparts_to_add -= "horns" if("ears" in mutant_bodyparts) - if(!H.dna.features["ears"] || H.dna.features["ears"] == "None" || H.head && (H.head.flags_inv & HIDEHAIR) || (H.wear_mask && (H.wear_mask.flags_inv & HIDEHAIR))) + if(!H.dna.features["ears"] || H.dna.features["ears"] == "None" || H.head && (H.head.flags_inv & HIDEHAIR) || (H.wear_mask && (H.wear_mask.flags_inv & HIDEHAIR)) || !HD || HD.status == ORGAN_ROBOTIC) bodyparts_to_add -= "ears" if(!bodyparts_to_add) @@ -469,20 +488,31 @@ if(!(type in I.species_exception)) return 0 + var/R = H.has_right_hand() + var/L = H.has_left_hand() + var/num_arms = H.get_num_arms() + var/num_legs = H.get_num_legs() + switch(slot) if(slot_l_hand) if(H.l_hand) return 0 + if(!L) + return 0 return 1 if(slot_r_hand) if(H.r_hand) return 0 + if(!R) + return 0 return 1 if(slot_wear_mask) if(H.wear_mask) return 0 if( !(I.slot_flags & SLOT_MASK) ) return 0 + if(!H.get_bodypart("head")) + return 0 return 1 if(slot_back) if(H.back) @@ -501,12 +531,16 @@ return 0 if( !(I.slot_flags & SLOT_GLOVES) ) return 0 + if(num_arms < 2) + return 0 return 1 if(slot_shoes) if(H.shoes) return 0 if( !(I.slot_flags & SLOT_FEET) ) return 0 + if(num_legs < 2) + return 0 return 1 if(slot_belt) if(H.belt) @@ -523,18 +557,24 @@ return 0 if( !(I.slot_flags & SLOT_EYES) ) return 0 + if(!H.get_bodypart("head")) + return 0 return 1 if(slot_head) if(H.head) return 0 if( !(I.slot_flags & SLOT_HEAD) ) return 0 + if(!H.get_bodypart("head")) + return 0 return 1 if(slot_ears) if(H.ears) return 0 if( !(I.slot_flags & SLOT_EARS) ) return 0 + if(!H.get_bodypart("head")) + return 0 return 1 if(slot_w_uniform) if(H.w_uniform) @@ -604,12 +644,16 @@ return 0 if(!istype(I, /obj/item/weapon/restraints/handcuffs)) return 0 + if(num_arms < 2) + return 0 return 1 if(slot_legcuffed) if(H.legcuffed) return 0 if(!istype(I, /obj/item/weapon/restraints/legcuffs)) return 0 + if(num_legs < 2) + return 0 return 1 if(slot_in_backpack) if (H.back && istype(H.back, /obj/item/weapon/storage/backpack)) @@ -712,7 +756,7 @@ if(A.update_remote_sight(H)) //returns 1 if we override all other sight updates. return - for(var/obj/item/organ/internal/cyberimp/eyes/E in H.internal_organs) + for(var/obj/item/organ/cyberimp/eyes/E in H.internal_organs) H.sight |= E.sight_flags if(E.dark_view) H.see_in_dark = E.dark_view @@ -757,7 +801,7 @@ H << "You feel weak." H.emote("collapse") if(prob(15)) - if(!( H.hair_style == "Shaved") || !(H.hair_style == "Bald") || HAIR in specflags) + if(!( H.hair_style == "Shaved") || !(H.hair_style == "Bald") || (HAIR in specflags)) H << "Your hair starts to fall out in clumps..." spawn(50) H.facial_hair_style = "Shaved" @@ -796,7 +840,7 @@ if(istype(J) && J.allow_thrust(0.01, H)) . -= 2 else - var/obj/item/organ/internal/cyberimp/chest/thrusters/T = H.getorganslot("thrusters") + var/obj/item/organ/cyberimp/chest/thrusters/T = H.getorganslot("thrusters") if(istype(T) && T.allow_thrust(0.01, H)) . -= 2 @@ -825,6 +869,12 @@ if(H.bodytemperature < BODYTEMP_COLD_DAMAGE_LIMIT) . += (BODYTEMP_COLD_DAMAGE_LIMIT - H.bodytemperature) / COLD_SLOWDOWN_FACTOR + var/leg_amount = H.get_num_legs() + . += 6 - 3*leg_amount //the fewer the legs, the slower the mob + if(!leg_amount) + . += 6 - 3*H.get_num_arms() //crawling is harder with fewer arms + + . += speedmod ////////////////// @@ -870,13 +920,14 @@ var/damage = rand(M.dna.species.punchdamagelow, M.dna.species.punchdamagehigh) - if(!damage) + var/obj/item/bodypart/affecting = H.get_bodypart(ran_zone(M.zone_selected)) + + if(!damage || !affecting) playsound(H.loc, M.dna.species.miss_sound, 25, 1, -1) H.visible_message("[M] has attempted to [atk_verb] [H]!") return 0 - var/obj/item/organ/limb/affecting = H.get_organ(ran_zone(M.zone_selected)) var/armor_block = H.run_armor_check(affecting, "melee") playsound(H.loc, M.dna.species.attack_sound, 25, 1, -1) @@ -902,7 +953,7 @@ if(H.w_uniform) H.w_uniform.add_fingerprint(M) - var/obj/item/organ/limb/affecting = H.get_organ(ran_zone(M.zone_selected)) + var/obj/item/bodypart/affecting = H.get_bodypart(ran_zone(M.zone_selected)) var/randn = rand(1, 100) if(randn <= 25) playsound(H, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) @@ -951,23 +1002,45 @@ "[M] attemped to disarm [H]!") return -/datum/species/proc/spec_attacked_by(obj/item/I, mob/living/user, def_zone, obj/item/organ/limb/affecting, hit_area, intent, obj/item/organ/limb/target_limb, target_area, mob/living/carbon/human/H) +/datum/species/proc/spec_attacked_by(obj/item/I, mob/living/user, obj/item/bodypart/affecting, intent, target_area, mob/living/carbon/human/H) // Allows you to put in item-specific reactions based on species if(user != H) user.do_attack_animation(H) if(H.check_shields(I.force, "the [I.name]", I, MELEE_ATTACK, I.armour_penetration)) return 0 - H.send_item_attack_message(I, user, hit_area) + var/hit_area + if(!affecting) //Something went wrong. Maybe the limb is missing? + H.visible_message("[user] has attempted to attack [H] with [I]!", \ + "[user] has attempted to attack [H] with [I]!") + playsound(H, 'sound/weapons/punchmiss.ogg', 25, 1, -1) + return 0 - if(!I.force) - return 0 //item force is zero + hit_area = affecting.name + var/def_zone = affecting.body_zone var/armor_block = H.run_armor_check(affecting, "melee", "Your armor has protected your [hit_area].", "Your armor has softened a hit to your [hit_area].",I.armour_penetration) armor_block = min(90,armor_block) //cap damage reduction at 90% var/Iforce = I.force //to avoid runtimes on the forcesay checks at the bottom. Some items might delete themselves if you drop them. (stunning yourself, ninja swords) - apply_damage(I.force, I.damtype, affecting, armor_block, H) + apply_damage(I.force, I.damtype, def_zone, armor_block, H) + + H.send_item_attack_message(I, user, hit_area) + + if(!I.force) + return 0 //item force is zero + + //dismemberment + if(affecting.get_damage() >= affecting.max_damage) + if(I.can_dismember() && prob(I.force*(I.w_class-1))) + if(affecting.dismember()) + I.add_blood(H) + playsound(get_turf(H), pick('sound/misc/desceration-01.ogg', 'sound/misc/desceration-02.ogg', 'sound/misc/desceration-03.ogg'), 80, 1) + affecting.add_blood(H) + var/turf/location = H.loc + if(istype(location)) + location.add_blood(H) + return var/bloody = 0 if(((I.damtype == BRUTE) && I.force && prob(25 + (I.force * 2)))) @@ -1039,12 +1112,13 @@ if(!damage || blocked <= 0) return 0 - var/obj/item/organ/limb/organ = null + var/obj/item/bodypart/organ = null if(islimb(def_zone)) organ = def_zone else - if(!def_zone) def_zone = ran_zone(def_zone) - organ = H.get_organ(check_zone(def_zone)) + if(!def_zone) + def_zone = ran_zone(def_zone) + organ = H.get_bodypart(check_zone(def_zone)) if(!organ) return 0 @@ -1265,7 +1339,7 @@ if(200 to 260) H.apply_damage(COLD_GAS_DAMAGE_LEVEL_1, BURN, "head") - if(!(HEATRES in specflags)) // HEAT DAMAGE + if(!(RESISTHEAT in specflags)) // HEAT DAMAGE switch(breath.temperature) if(360 to 400) H.apply_damage(HEAT_GAS_DAMAGE_LEVEL_1, BURN, "head") @@ -1300,7 +1374,7 @@ H.bodytemperature += min((1-thermal_protection) * ((loc_temp - H.bodytemperature) / BODYTEMP_HEAT_DIVISOR), BODYTEMP_HEATING_MAX) // +/- 50 degrees from 310.15K is the 'safe' zone, where no damage is dealt. - if(H.bodytemperature > BODYTEMP_HEAT_DAMAGE_LIMIT && !(HEATRES in specflags)) + if(H.bodytemperature > BODYTEMP_HEAT_DAMAGE_LIMIT && !(RESISTHEAT in specflags)) //Body temperature is too hot. switch(H.bodytemperature) if(360 to 400) @@ -1339,7 +1413,7 @@ var/adjusted_pressure = H.calculate_affecting_pressure(pressure) //Returns how much pressure actually affects the mob. switch(adjusted_pressure) if(HAZARD_HIGH_PRESSURE to INFINITY) - if(!(HEATRES in specflags)) + if(!(RESISTHEAT in specflags)) H.adjustBruteLoss( min( ( (adjusted_pressure / HAZARD_HIGH_PRESSURE) -1 )*PRESSURE_DAMAGE_COEFFICIENT , MAX_HIGH_PRESSURE_DAMAGE) ) H.throw_alert("pressure", /obj/screen/alert/highpressure, 2) else @@ -1351,7 +1425,7 @@ if(HAZARD_LOW_PRESSURE to WARNING_LOW_PRESSURE) H.throw_alert("pressure", /obj/screen/alert/lowpressure, 1) else - if(H.dna.check_mutation(COLDRES) || (COLDRES in specflags)) + if(H.dna.check_mutation(COLDRES) || (RESISTCOLD in specflags)) H.clear_alert("pressure") else H.adjustBruteLoss( LOW_PRESSURE_DAMAGE ) @@ -1362,11 +1436,11 @@ ////////// /datum/species/proc/handle_fire(mob/living/carbon/human/H) - if((HEATRES in specflags) || (NOFIRE in specflags)) + if((RESISTHEAT in specflags) || (NOFIRE in specflags)) return 1 /datum/species/proc/IgniteMob(mob/living/carbon/human/H) - if((HEATRES in specflags) || (NOFIRE in specflags)) + if((RESISTHEAT in specflags) || (NOFIRE in specflags)) return 1 /datum/species/proc/ExtinguishMob(mob/living/carbon/human/H) diff --git a/code/modules/mob/living/carbon/human/species_types.dm b/code/modules/mob/living/carbon/human/species_types.dm index df97e03d43b..a7beebc5857 100644 --- a/code/modules/mob/living/carbon/human/species_types.dm +++ b/code/modules/mob/living/carbon/human/species_types.dm @@ -56,7 +56,7 @@ default_color = "00FF00" specflags = list(MUTCOLORS,EYECOLOR,LIPS) mutant_bodyparts = list("tail_lizard", "snout", "spines", "horns", "frills", "body_markings") - mutant_organs = list(/obj/item/organ/internal/tongue/lizard) + mutant_organs = list(/obj/item/organ/tongue/lizard) default_features = list("mcolor" = "0F0", "tail" = "Smooth", "snout" = "Round", "horns" = "None", "frills" = "None", "spines" = "None", "body_markings" = "None") attack_verb = "slash" attack_sound = 'sound/weapons/slash.ogg' @@ -182,6 +182,7 @@ specflags = list(MUTCOLORS,EYECOLOR,NOBLOOD,VIRUSIMMUNE) meat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/human/mutant/slime exotic_blood = "slimejelly" + has_dismemberment = 0 /datum/species/jelly/spec_life(mob/living/carbon/human/H) if(H.stat == DEAD) //can't farm slime jelly from a dead slime/jelly person indefinitely @@ -319,7 +320,7 @@ // Animated beings of stone. They have increased defenses, and do not need to breathe. They're also slow as fuuuck. name = "Golem" id = "golem" - specflags = list(NOBREATH,HEATRES,COLDRES,NOGUNS,NOBLOOD,RADIMMUNE,VIRUSIMMUNE,PIERCEIMMUNE) + specflags = list(NOBREATH,RESISTHEAT,RESISTCOLD,NOGUNS,NOBLOOD,RADIMMUNE,VIRUSIMMUNE,PIERCEIMMUNE) speedmod = 2 armor = 55 siemens_coeff = 0 @@ -330,6 +331,7 @@ nojumpsuit = 1 sexes = 0 meat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/human/mutant/golem + has_dismemberment = 0 /datum/species/golem/adamantine name = "Adamantine Golem" @@ -376,7 +378,7 @@ name = "Human?" id = "fly" say_mod = "buzzes" - mutant_organs = list(/obj/item/organ/internal/tongue/fly) + mutant_organs = list(/obj/item/organ/tongue/fly) meat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/human/mutant/fly /datum/species/fly/handle_chemicals(datum/reagent/chem, mob/living/carbon/human/H) @@ -410,7 +412,7 @@ blacklisted = 1 sexes = 0 meat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/human/mutant/skeleton - specflags = list(NOBREATH,HEATRES,COLDRES,NOBLOOD,RADIMMUNE,VIRUSIMMUNE,PIERCEIMMUNE) + specflags = list(NOBREATH,RESISTHEAT,RESISTCOLD,NOBLOOD,RADIMMUNE,VIRUSIMMUNE,PIERCEIMMUNE) var/list/myspan = null /datum/species/skeleton/New() @@ -433,8 +435,8 @@ sexes = 0 blacklisted = 1 meat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/human/mutant/zombie - specflags = list(NOBREATH,HEATRES,COLDRES,NOBLOOD,RADIMMUNE) - mutant_organs = list(/obj/item/organ/internal/tongue/zombie) + specflags = list(NOBREATH,RESISTHEAT,RESISTCOLD,NOBLOOD,RADIMMUNE) + mutant_organs = list(/obj/item/organ/tongue/zombie) /datum/species/cosmetic_zombie name = "Human" @@ -450,7 +452,7 @@ say_mod = "gibbers" sexes = 0 specflags = list(NOBLOOD,NOBREATH,VIRUSIMMUNE) - mutant_organs = list(/obj/item/organ/internal/tongue/abductor) + mutant_organs = list(/obj/item/organ/tongue/abductor) var/scientist = 0 // vars to not pollute spieces list with castes var/agent = 0 var/team = 1 @@ -473,20 +475,6 @@ var/global/image/plasmaman_on_fire = image("icon"='icons/mob/OnFire.dmi', "icon_ burnmod = 2 heatmod = 2 speedmod = 1 - var/skin = 0 - -/datum/species/plasmaman/skin - name = "Skinbone" - skin = 1 - roundstart = 0 - -/datum/species/plasmaman/update_base_icon_state(mob/living/carbon/human/H) - var/base = ..() - if(base == id && !skin) - base = "[base]_m" - else - base = "skinbone_m" - return base /datum/species/plasmaman/spec_life(mob/living/carbon/human/H) var/datum/gas_mixture/environment = H.loc.return_air() @@ -510,6 +498,8 @@ var/global/image/plasmaman_on_fire = image("icon"='icons/mob/OnFire.dmi', "icon_ /datum/species/plasmaman/before_equip_job(datum/job/J, mob/living/carbon/human/H, visualsOnly = FALSE) var/datum/outfit/plasmaman/O = new /datum/outfit/plasmaman H.equipOutfit(O, visualsOnly) + H.internal = H.r_hand + H.update_internals_hud_icon(1) return 0 /datum/species/plasmaman/qualifies_for_rank(rank, list/features) @@ -544,7 +534,7 @@ var/global/list/synth_flesh_disguises = list() var/disguise_fail_health = 75 //When their health gets to this level their synthflesh partially falls off var/image/damaged_synth_flesh = null //an image to display when we're below disguise_fail_health var/datum/species/fake_species = null //a species to do most of our work for us, unless we're damaged - + has_dismemberment = 0 /datum/species/synth/military name = "Military Synth" @@ -663,7 +653,10 @@ var/global/list/synth_flesh_disguises = list() H.updatehealth() if(H.health > disguise_fail_health) if(fake_species) - return fake_species.update_base_icon_state(H) + if(fake_species.has_dismemberment) + return fake_species.handle_body(H) + else + return fake_species.update_base_icon_state(H) else return ..() else @@ -672,7 +665,7 @@ var/global/list/synth_flesh_disguises = list() /datum/species/synth/update_color(mob/living/carbon/human/H, forced_colour) H.updatehealth() if(H.health > disguise_fail_health) - if(fake_species) + if(fake_species && fake_species.has_dismemberment) fake_species.update_color(H, forced_colour) @@ -739,4 +732,4 @@ SYNDICATE BLACK OPS use_skintones = 0 specflags = list(RADIMMUNE,VIRUSIMMUNE,NOBLOOD,PIERCEIMMUNE,EYECOLOR) sexes = 0 - + has_dismemberment = 0 diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index 8a44cd032a1..6cb5cda6feb 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -50,6 +50,7 @@ There are several things that need to be remembered: If you have any questions/constructive-comments/bugs-to-report Please contact me on #coderbus IRC. ~Carnie x //Carn can sometimes be hard to reach now. However IRC is still your best bet for getting help. + */ /mob/living/carbon/human/proc/update_base_icon_state() @@ -65,11 +66,12 @@ Please contact me on #coderbus IRC. ~Carnie x var/image/standing = image("icon"='icons/mob/dam_human.dmi', "icon_state"="blank", "layer"=-DAMAGE_LAYER) overlays_standing[DAMAGE_LAYER] = standing - for(var/obj/item/organ/limb/O in organs) - if(O.brutestate) - standing.overlays += "[O.icon_state]_[O.brutestate]0" //we're adding icon_states of the base image as overlays - if(O.burnstate) - standing.overlays += "[O.icon_state]_0[O.burnstate]" + for(var/X in bodyparts) + var/obj/item/bodypart/BP = X + if(BP.brutestate) + standing.overlays += "[BP.icon_state]_[BP.brutestate]0" //we're adding icon_states of the base image as overlays + if(BP.burnstate) + standing.overlays += "[BP.icon_state]_0[BP.burnstate]" apply_overlay(DAMAGE_LAYER) @@ -78,10 +80,6 @@ Please contact me on #coderbus IRC. ~Carnie x /mob/living/carbon/human/update_hair() dna.species.handle_hair(src) -/mob/living/carbon/human/proc/update_mutcolor() - if(!(disabilities & HUSK)) - dna.species.update_color(src) - //used when putting/removing clothes that hide certain mutant body parts to just update those and not update the whole body. /mob/living/carbon/human/proc/update_mutant_bodyparts() dna.species.handle_mutant_bodyparts(src) @@ -89,39 +87,53 @@ Please contact me on #coderbus IRC. ~Carnie x /mob/living/carbon/human/proc/update_body() remove_overlay(BODY_LAYER) - update_base_icon_state() dna.species.handle_body(src) + update_body_parts() /mob/living/carbon/human/update_fire() ..("Standing") +/mob/living/carbon/human/proc/update_body_parts() + if(!dna.species.has_dismemberment) //Species don't have no dismemberment going for 'em! + remove_overlay(BODYPARTS_LAYER) + return -/mob/living/carbon/human/proc/update_augments() - remove_overlay(AUGMENTS_LAYER) + icon_state = ""//Reset here as apposed to having a null one due to some getFlatIcon calls at roundstart. - var/list/standing = list() - var/g = (gender == FEMALE) ? "f" : "m" + remove_overlay(SPECIES_LAYER)//if we switch from a species w/o dismemberment to one with it, we must clear that layer. + //CHECK FOR UPDATE + var/oldkey = icon_render_key + icon_render_key = generate_icon_render_key() + if(oldkey == icon_render_key) + return - if(getlimb(/obj/item/organ/limb/robot/r_arm)) - standing += image("icon"='icons/mob/augments.dmi', "icon_state"="r_arm_s", "layer"=-AUGMENTS_LAYER) - if(getlimb(/obj/item/organ/limb/robot/l_arm)) - standing += image("icon"='icons/mob/augments.dmi', "icon_state"="l_arm_s", "layer"=-AUGMENTS_LAYER) + remove_overlay(BODYPARTS_LAYER) - if(getlimb(/obj/item/organ/limb/robot/r_leg)) - standing += image("icon"='icons/mob/augments.dmi', "icon_state"="r_leg_s", "layer"=-AUGMENTS_LAYER) - if(getlimb(/obj/item/organ/limb/robot/l_leg)) - standing += image("icon"='icons/mob/augments.dmi', "icon_state"="l_leg_s", "layer"=-AUGMENTS_LAYER) + //LOAD ICONS + if(limb_icon_cache[icon_render_key]) + load_limb_from_cache() + update_damage_overlays() + update_mutant_bodyparts() + update_hair() + return - if(getlimb(/obj/item/organ/limb/robot/chest)) - standing += image("icon"='icons/mob/augments.dmi', "icon_state"="chest_[g]_s", "layer"=-AUGMENTS_LAYER) - if(getlimb(/obj/item/organ/limb/robot/head)) - standing += image("icon"='icons/mob/augments.dmi', "icon_state"="head_s", "layer"=-AUGMENTS_LAYER) + //GENERATE NEW LIMBS + var/list/new_limbs = list() + for(var/X in bodyparts) + var/obj/item/bodypart/BP = X + if(!BP.no_update) + BP.update_limb() + var/image/temp = BP.get_limb_icon() + if(temp) + new_limbs += temp + if(new_limbs.len) + overlays_standing[BODYPARTS_LAYER] = new_limbs + limb_icon_cache[icon_render_key] = new_limbs - if(standing.len) - overlays_standing[AUGMENTS_LAYER] = standing + apply_overlay(BODYPARTS_LAYER) + update_damage_overlays() - apply_overlay(AUGMENTS_LAYER) /* --------------------------------------- */ //For legacy support. @@ -144,10 +156,10 @@ Please contact me on #coderbus IRC. ~Carnie x update_inv_wear_suit() update_inv_pockets() update_transform() - // Mutantrace colors - update_mutcolor() //mutations update_mutations_overlay() + //damage overlays + update_damage_overlays() /* --------------------------------------- */ //vvvvvv UPDATE_INV PROCS vvvvvv @@ -216,6 +228,9 @@ Please contact me on #coderbus IRC. ~Carnie x /mob/living/carbon/human/update_inv_gloves() remove_overlay(GLOVES_LAYER) + if(get_num_arms() <2) + return + if(client && hud_used) var/obj/screen/inventory/inv = hud_used.inv_slots[slot_gloves] inv.update_icon() @@ -245,6 +260,9 @@ Please contact me on #coderbus IRC. ~Carnie x /mob/living/carbon/human/update_inv_glasses() remove_overlay(GLASSES_LAYER) + if(!get_bodypart("head")) //decapitated + return + if(client && hud_used) var/obj/screen/inventory/inv = hud_used.inv_slots[slot_glasses] inv.update_icon() @@ -266,6 +284,9 @@ Please contact me on #coderbus IRC. ~Carnie x /mob/living/carbon/human/update_inv_ears() remove_overlay(EARS_LAYER) + if(!get_bodypart("head")) //decapitated + return + if(client && hud_used) var/obj/screen/inventory/inv = hud_used.inv_slots[slot_ears] inv.update_icon() @@ -285,6 +306,9 @@ Please contact me on #coderbus IRC. ~Carnie x /mob/living/carbon/human/update_inv_shoes() remove_overlay(SHOES_LAYER) + if(get_num_legs() <2) + return + if(client && hud_used) var/obj/screen/inventory/inv = hud_used.inv_slots[slot_shoes] inv.update_icon() @@ -323,6 +347,9 @@ Please contact me on #coderbus IRC. ~Carnie x /mob/living/carbon/human/update_inv_head() + remove_overlay(HEAD_LAYER) + if(!get_bodypart("head")) //Decapitated + return ..() if(client && hud_used) var/obj/screen/inventory/inv = hud_used.inv_slots[slot_head] @@ -402,6 +429,9 @@ Please contact me on #coderbus IRC. ~Carnie x /mob/living/carbon/human/update_inv_wear_mask() + remove_overlay(FACEMASK_LAYER) + if(!get_bodypart("head")) //Decapitated + return ..() if(client && hud_used) var/obj/screen/inventory/inv = hud_used.inv_slots[slot_wear_mask] @@ -523,3 +553,64 @@ generate/load female uniform sprites matching all previously decided variables return standing + + + + + + + + +///////////////////// +// Limb Icon Cache // +///////////////////// +/* + Called from update_body_parts() these procs handle the limb icon cache. + the limb icon cache adds an icon_render_key to a human mob, it represents: + - skin_tone (if applicable) + - gender + - limbs (stores as the limb name and whether it is removed/fine, organic/robotic) + These procs only store limbs as to increase the number of matching icon_render_keys + This cache exists because drawing 6/7 icons for humans constantly is quite a waste + See RemieRichards on irc.rizon.net #coderbus +*/ + +var/global/list/limb_icon_cache = list() + +/mob/living/carbon/human + var/icon_render_key = "" + + +//produces a key based on the human's limbs +/mob/living/carbon/human/proc/generate_icon_render_key() + . = "[dna.species.id]" + + if(dna.check_mutation(HULK)) + . += "-coloured-hulk" + else if(dna.species.use_skintones) + . += "-coloured-[skin_tone]" + else if(dna.features["mcolor"]) + . += "-coloured-[dna.features["mcolor"]]" + else + . += "-not_coloured" + + . += "-[gender]" + + for(var/X in bodyparts) + var/obj/item/bodypart/BP = X + . += "-[BP.body_zone]" + if(BP.status == ORGAN_ORGANIC) + . += "-organic" + else + . += "-robotic" + + if(disabilities & HUSK) + . += "-husk" + + +//change the human's icon to the one matching it's key +/mob/living/carbon/human/proc/load_limb_from_cache() + if(limb_icon_cache[icon_render_key]) + remove_overlay(BODYPARTS_LAYER) + overlays_standing[BODYPARTS_LAYER] = limb_icon_cache[icon_render_key] + apply_overlay(BODYPARTS_LAYER) diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm index 5e7aee2d4c2..77c3a6c6d0d 100644 --- a/code/modules/mob/living/carbon/life.dm +++ b/code/modules/mob/living/carbon/life.dm @@ -14,7 +14,7 @@ if(..()) . = 1 - for(var/obj/item/organ/internal/O in internal_organs) + for(var/obj/item/organ/O in internal_organs) O.on_life() //grab processing diff --git a/code/modules/mob/living/carbon/monkey/monkey.dm b/code/modules/mob/living/carbon/monkey/monkey.dm index 7cae78192ea..e9a142ce5a3 100644 --- a/code/modules/mob/living/carbon/monkey/monkey.dm +++ b/code/modules/mob/living/carbon/monkey/monkey.dm @@ -20,16 +20,24 @@ if(unique_name) //used to exclude pun pun gender = pick(MALE, FEMALE) real_name = name + + //initialize limbs, currently only used to handle cavity implant surgery, no dismemberment. + bodyparts = newlist(/obj/item/bodypart/chest, /obj/item/bodypart/head, /obj/item/bodypart/l_arm, + /obj/item/bodypart/r_arm, /obj/item/bodypart/r_leg, /obj/item/bodypart/l_leg) + for(var/X in bodyparts) + var/obj/item/bodypart/O = X + O.owner = src + if(good_mutations.len) //genetic mutations have been set up. initialize() - internal_organs += new /obj/item/organ/internal/appendix - internal_organs += new /obj/item/organ/internal/lungs - internal_organs += new /obj/item/organ/internal/heart - internal_organs += new /obj/item/organ/internal/brain - internal_organs += new /obj/item/organ/internal/tongue + internal_organs += new /obj/item/organ/appendix + internal_organs += new /obj/item/organ/lungs + internal_organs += new /obj/item/organ/heart + internal_organs += new /obj/item/organ/brain + internal_organs += new /obj/item/organ/tongue - for(var/obj/item/organ/internal/I in internal_organs) + for(var/obj/item/organ/I in internal_organs) I.Insert(src) ..() @@ -38,13 +46,6 @@ create_dna(src) dna.initialize_dna(random_blood_type()) -/mob/living/carbon/monkey/prepare_data_huds() - //Prepare our med HUD... - ..() - //...and display it. - for(var/datum/atom_hud/data/human/medical/hud in huds) - hud.add_to_hud(src) - /mob/living/carbon/monkey/movement_delay() if(reagents) if(reagents.has_reagent("morphine")) @@ -305,10 +306,10 @@ /mob/living/carbon/monkey/fully_heal(admin_revive = 0) if(!getorganslot("lungs")) - var/obj/item/organ/internal/lungs/L = new() + var/obj/item/organ/lungs/L = new() L.Insert(src) if(!getorganslot("tongue")) - var/obj/item/organ/internal/tongue/T = new() + var/obj/item/organ/tongue/T = new() T.Insert(src) ..() diff --git a/code/modules/mob/living/carbon/say.dm b/code/modules/mob/living/carbon/say.dm index 726fbd8d126..9f940c4e5ce 100644 --- a/code/modules/mob/living/carbon/say.dm +++ b/code/modules/mob/living/carbon/say.dm @@ -1,6 +1,6 @@ /mob/living/carbon/treat_message(message) message = ..(message) - var/obj/item/organ/internal/tongue/T = getorganslot("tongue") + var/obj/item/organ/tongue/T = getorganslot("tongue") if(!T) //hoooooouaah! var/regex/tongueless_lower = new("\[gdntke]+", "g") var/regex/tongueless_upper = new("\[GDNTKE]+", "g") diff --git a/code/modules/mob/living/death.dm b/code/modules/mob/living/death.dm index 4f3528aa1ca..e4c1500e632 100644 --- a/code/modules/mob/living/death.dm +++ b/code/modules/mob/living/death.dm @@ -63,3 +63,5 @@ update_damage_hud() update_health_hud() update_canmove() + med_hud_set_health() + med_hud_set_status() diff --git a/code/modules/mob/living/emote.dm b/code/modules/mob/living/emote.dm index 70fdee24d9c..8145741e009 100644 --- a/code/modules/mob/living/emote.dm +++ b/code/modules/mob/living/emote.dm @@ -2,6 +2,8 @@ //Things like airguitar can be done without arms, and the flap thing makes so little sense it's a keeper. //Intended to be called by a higher up emote proc if the requested emote isn't in the custom emotes. + + /mob/living/emote(act, m_type=1, message = null) if(stat) return @@ -13,6 +15,7 @@ param = copytext(act, t1 + 1, length(act) + 1) act = copytext(act, 1, t1) + act = lowertext(act) switch(act)//Hello, how would you like to order? Alphabetically! if ("aflap") if (!src.restrained()) @@ -47,6 +50,10 @@ message = "[src] chokes!" m_type = 2 + if ("cross","crosses") + message = "[src] crosses their arms." + m_type = 2 + if ("chuckle","chuckles") message = "[src] chuckles." m_type = 2 @@ -94,6 +101,10 @@ message = "[src] frowns." m_type = 1 + if ("gag","gags") + message = "[src] gags!" + m_type = 2 + if ("gasp","gasps") message = "[src] gasps!" m_type = 2 @@ -120,10 +131,33 @@ message = "[src] grins." m_type = 1 + if ("groan","groans") + message = "[src] groans!" + m_type = 1 + + + if ("grimace","grimaces") + message = "[src] grimaces." + m_type = 1 + if ("jump","jumps") message = "[src] jumps!" m_type = 1 + if ("kiss","kisses") //S-so forward uwa~ + var/M = null + if (param) + for (var/mob/A in view(1, src)) + if (param == A.name) + M = A + break + if (!M) + param = null + if (param) + message = "[src] blows a kiss to [param]." //I was gonna make this [src] kisses [param] but then I imagined dealing with an ahelp about someone spamming it and following certain players around and I had a miniature stroke. + else + message = "[src] blows a kiss." + if ("laugh","laughs") message = "[src] laughs." m_type = 2 @@ -175,11 +209,18 @@ else pointed(M) m_type = 1 - + if ("pout","pouts") + message = "[src] pouts." + m_type = 2 + if ("scream","screams") message = "[src] screams!" m_type = 2 + if ("scowl","scowls") + message = "[src] scowls." + m_type = 1 + if ("shake","shakes") message = "[src] shakes its head." m_type = 1 @@ -200,6 +241,10 @@ message = "[src] sneezes." m_type = 2 + if ("smug","smugs") + message = "[src] grins smugly." + m_type = 2 + if ("sniff","sniffs") message = "[src] sniffs." m_type = 2 @@ -222,10 +267,29 @@ else message = "[src] stares." + if ("stretch","stretches") + message = "[src] stretches their arms." + m_type = 2 + if ("sulk","sulks") message = "[src] sulks down sadly." m_type = 1 + if ("surrender","surrenders") + message = "[src] puts their hands on their head and falls to the ground, they surrender!" + if(sleeping) + return //Can't surrender while asleep. + Weaken(20) //So you can't resist. + m_type = 1 + + if ("faint","faints") + message = "[src] faints." + if(sleeping) + return //Can't faint while asleep + SetSleeping(10) //Short-short nap + m_type = 1 + + if ("sway","sways") message = "[src] sways around dizzily." m_type = 1 @@ -250,12 +314,16 @@ message = "[src] whimpers." m_type = 2 + if ("wsmile","wsmiles") + message = "[src] smiles weakly." + m_type = 2 + if ("yawn","yawns") message = "[src] yawns." m_type = 2 if ("help") - src << "Help for emotes. You can use these emotes with say \"*emote\":\n\naflap, blush, bow-(none)/mob, burp, choke, chuckle, clap, collapse, cough, dance, deathgasp, drool, flap, frown, gasp, giggle, glare-(none)/mob, grin, jump, laugh, look, me, nod, point-atom, scream, shake, sigh, sit, smile, sneeze, sniff, snore, stare-(none)/mob, sulk, sway, tremble, twitch, twitch_s, wave, whimper, yawn" + src << "Help for emotes. You can use these emotes with say \"*emote\":\n\naflap, blush, bow-(none)/mob, burp, choke, chuckle, clap, collapse, cough, cross, dance, deathgasp, drool, flap, frown, gasp, giggle, glare-(none)/mob, grin, grimace, groan, jump, kiss, laugh, look, me, nod, point-atom, scream, shake, sigh, sit, smile, sneeze, sniff, snore, stare-(none)/mob, stretch, sulk, surrender, sway, tremble, twitch, twitch_s, wave, whimper, wsmile, yawn" else src << "Unusable emote '[act]'. Say *help for a list." diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index e33323c786a..06f6492e9ae 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -23,10 +23,19 @@ Sorry Giacom. Please don't be mad :( if(unique_name) name = "[name] ([rand(1, 1000)])" real_name = name - + var/datum/atom_hud/data/human/medical/advanced/medhud = huds[DATA_HUD_MEDICAL_ADVANCED] + medhud.add_to_hud(src) faction |= "\ref[src]" +/mob/living/prepare_huds() + ..() + prepare_data_huds() + +/mob/living/proc/prepare_data_huds() + med_hud_set_health() + med_hud_set_status() + /mob/living/Destroy() ..() @@ -36,7 +45,7 @@ Sorry Giacom. Please don't be mad :( D.client.images.Remove(I) qdel(I) staticOverlays.len = 0 - + remove_from_all_data_huds() return QDEL_HINT_HARDDEL_NOW @@ -210,7 +219,7 @@ Sorry Giacom. Please don't be mad :( return health = maxHealth - getOxyLoss() - getToxLoss() - getFireLoss() - getBruteLoss() - getCloneLoss() update_stat() - + med_hud_set_health() //This proc is used for mobs which are affected by pressure to calculate the amount of pressure that actually //affects them once clothing is factored in. ~Errorage @@ -426,7 +435,7 @@ Sorry Giacom. Please don't be mad :( var/t = shooter.zone_selected if ((t in list( "eyes", "mouth" ))) t = "head" - var/obj/item/organ/limb/def_zone = ran_zone(t) + var/def_zone = ran_zone(t) return def_zone // heal ONE external organ, organ gets randomly selected from damaged ones. @@ -443,14 +452,14 @@ Sorry Giacom. Please don't be mad :( if(updating_health) updatehealth() -// heal MANY external organs, in random order +// heal MANY bodyparts, in random order /mob/living/proc/heal_overall_damage(brute, burn, updating_health=1) adjustBruteLoss(-brute, updating_health) adjustFireLoss(-burn, updating_health) if(updating_health) updatehealth() -// damage MANY external organs, in random order +// damage MANY bodyparts, in random order /mob/living/proc/take_overall_damage(brute, burn, updating_health=1) adjustBruteLoss(brute, updating_health) adjustFireLoss(burn, updating_health) diff --git a/code/modules/mob/living/living_defines.dm b/code/modules/mob/living/living_defines.dm index 85ab36335ad..2406a5ba0ed 100644 --- a/code/modules/mob/living/living_defines.dm +++ b/code/modules/mob/living/living_defines.dm @@ -3,6 +3,7 @@ languages = HUMAN sight = 0 see_in_dark = 2 + hud_possible = list(HEALTH_HUD,STATUS_HUD,ANTAG_HUD) //Health and life related vars var/maxHealth = 100 //Maximum health that should be possible. diff --git a/code/modules/mob/living/silicon/login.dm b/code/modules/mob/living/silicon/login.dm index fd1e5cf1701..08bfb5e6455 100644 --- a/code/modules/mob/living/silicon/login.dm +++ b/code/modules/mob/living/silicon/login.dm @@ -1,6 +1,6 @@ /mob/living/silicon/Login() if(mind && ticker && ticker.mode) - ticker.mode.remove_cultist(mind, 0) + ticker.mode.remove_cultist(mind, 0, 0) ticker.mode.remove_revolutionary(mind, 0) ticker.mode.remove_gangster(mind, remove_bosses=1) ticker.mode.remove_thrall(mind,0) diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 5128a13958e..2c3db69ef8e 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -116,7 +116,7 @@ //MMI stuff. Held togheter by magic. ~Miauw if(!mmi || !mmi.brainmob) mmi = new (src) - mmi.brain = new /obj/item/organ/internal/brain(mmi) + mmi.brain = new /obj/item/organ/brain(mmi) mmi.brain.name = "[real_name]'s brain" mmi.icon_state = "mmi_full" mmi.name = "Man-Machine Interface: [real_name]" diff --git a/code/modules/mob/living/silicon/robot/robot_modules.dm b/code/modules/mob/living/silicon/robot/robot_modules.dm index ef48c295882..0f4ecdb8946 100644 --- a/code/modules/mob/living/silicon/robot/robot_modules.dm +++ b/code/modules/mob/living/silicon/robot/robot_modules.dm @@ -130,6 +130,7 @@ modules += new /obj/item/weapon/wrench/cyborg(src) modules += new /obj/item/weapon/crowbar/cyborg(src) modules += new /obj/item/device/healthanalyzer(src) + modules += new /obj/item/toy/crayon/spraycan/borg(src) emag = new /obj/item/weapon/melee/energy/sword/cyborg(src) fix_modules() @@ -179,6 +180,7 @@ modules += new /obj/item/device/multitool/cyborg(src) modules += new /obj/item/device/t_scanner(src) modules += new /obj/item/device/analyzer(src) + modules += new /obj/item/areaeditor/blueprints/cyborg(src) add_module(new /obj/item/stack/sheet/metal/cyborg()) add_module(new /obj/item/stack/sheet/glass/cyborg()) @@ -260,6 +262,8 @@ modules += new /obj/item/weapon/reagent_containers/food/drinks/drinkingglass(src) modules += new /obj/item/weapon/reagent_containers/food/condiment/enzyme(src) modules += new /obj/item/weapon/pen(src) + modules += new /obj/item/toy/crayon/spraycan/borg(src) + modules += new /obj/item/weapon/hand_labeler/borg(src) modules += new /obj/item/weapon/razor(src) modules += new /obj/item/device/instrument/violin(src) modules += new /obj/item/device/instrument/guitar(src) diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm index c8dd62d7c63..208bd2da166 100644 --- a/code/modules/mob/living/silicon/silicon.dm +++ b/code/modules/mob/living/silicon/silicon.dm @@ -41,6 +41,12 @@ diag_hud_set_status() diag_hud_set_health() +/mob/living/silicon/med_hud_set_health() + return //we use a different hud + +/mob/living/silicon/med_hud_set_status() + return //we use a different hud + /mob/living/silicon/Destroy() radio = null aicamera = null diff --git a/code/modules/mob/living/simple_animal/bot/bot.dm b/code/modules/mob/living/simple_animal/bot/bot.dm index 43bb2e55a25..a21e2bd2bf5 100644 --- a/code/modules/mob/living/simple_animal/bot/bot.dm +++ b/code/modules/mob/living/simple_animal/bot/bot.dm @@ -188,6 +188,12 @@ ..() diag_hud_set_bothealth() +/mob/living/simple_animal/bot/med_hud_set_health() + return //we use a different hud + +/mob/living/simple_animal/bot/med_hud_set_status() + return //we use a different hud + /mob/living/simple_animal/bot/handle_automated_action() //Master process which handles code common across most bots. set background = BACKGROUND_ENABLED diag_hud_set_botmode() diff --git a/code/modules/mob/living/simple_animal/bot/cleanbot.dm b/code/modules/mob/living/simple_animal/bot/cleanbot.dm index f7efbc7c198..5c00a4fc3bf 100644 --- a/code/modules/mob/living/simple_animal/bot/cleanbot.dm +++ b/code/modules/mob/living/simple_animal/bot/cleanbot.dm @@ -174,7 +174,7 @@ /mob/living/simple_animal/bot/cleanbot/proc/clean(obj/effect/decal/cleanable/target) anchored = 1 icon_state = "cleanbot-c" - visible_message("[src] begins to clean up [target]") + visible_message("[src] begins to clean up [target].") mode = BOT_CLEANING spawn(50) if(mode == BOT_CLEANING) diff --git a/code/modules/mob/living/simple_animal/friendly/cat.dm b/code/modules/mob/living/simple_animal/friendly/cat.dm index 82b7cfae730..0aef48fdc9f 100644 --- a/code/modules/mob/living/simple_animal/friendly/cat.dm +++ b/code/modules/mob/living/simple_animal/friendly/cat.dm @@ -20,7 +20,7 @@ minbodytemp = 200 maxbodytemp = 400 unsuitable_atmos_damage = 1 - species = /mob/living/simple_animal/pet/cat + animal_species = /mob/living/simple_animal/pet/cat childtype = list(/mob/living/simple_animal/pet/cat/kitten) butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat/slab = 2) response_help = "pets" diff --git a/code/modules/mob/living/simple_animal/friendly/dog.dm b/code/modules/mob/living/simple_animal/friendly/dog.dm index bd928eb762c..b0df6fbc666 100644 --- a/code/modules/mob/living/simple_animal/friendly/dog.dm +++ b/code/modules/mob/living/simple_animal/friendly/dog.dm @@ -24,7 +24,7 @@ gender = MALE butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat/slab/corgi = 3, /obj/item/stack/sheet/animalhide/corgi = 1) childtype = list(/mob/living/simple_animal/pet/dog/corgi/puppy = 95, /mob/living/simple_animal/pet/dog/corgi/puppy/void = 5) - species = /mob/living/simple_animal/pet/dog + animal_species = /mob/living/simple_animal/pet/dog var/shaved = 0 var/obj/item/inventory_head var/obj/item/inventory_back @@ -164,7 +164,7 @@ usr << "\The [item_to_add] is stuck to your hand, you cannot put it on [src]'s back!" return - if(istype(item_to_add,/obj/item/weapon/c4)) // last thing he ever wears, I guess + if(istype(item_to_add,/obj/item/weapon/grenade/plastic)) // last thing he ever wears, I guess item_to_add.afterattack(src,usr,1) return @@ -200,7 +200,7 @@ /mob/living/simple_animal/pet/dog/corgi/proc/place_on_head(obj/item/item_to_add, mob/user) - if(istype(item_to_add,/obj/item/weapon/c4)) // last thing he ever wears, I guess + if(istype(item_to_add,/obj/item/weapon/grenade/plastic)) // last thing he ever wears, I guess item_to_add.afterattack(src,user,1) return diff --git a/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm b/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm index 4d6632dec56..bb635bb1425 100644 --- a/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm +++ b/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm @@ -42,6 +42,7 @@ has_unlimited_silicon_privilege = 1 damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 0, CLONE = 0, STAMINA = 0, OXY = 0) staticOverlays = list() + hud_possible = list(DIAG_STAT_HUD, DIAG_HUD, ANTAG_HUD) var/staticChoice = "static" var/list/staticChoices = list("static", "blank", "letter", "animal") var/picked = FALSE //Have we picked our visual appearence (+ colour if applicable) @@ -85,6 +86,22 @@ var/datum/action/generic/drone/select_filter/SF = new(src) SF.Grant(src) + var/datum/atom_hud/data/diagnostic/diag_hud = huds[DATA_HUD_DIAGNOSTIC] + diag_hud.add_to_hud(src) + + +/mob/living/simple_animal/drone/med_hud_set_health() + var/image/holder = hud_list[DIAG_HUD] + holder.icon_state = "huddiag[RoundDiagBar(health/maxHealth)]" + +/mob/living/simple_animal/drone/med_hud_set_status() + var/image/holder = hud_list[DIAG_STAT_HUD] + if(stat == DEAD) + holder.icon_state = "huddead2" + else if(incapacitated()) + holder.icon_state = "hudoffline" + else + holder.icon_state = "hudstat" /mob/living/simple_animal/drone/Destroy() diff --git a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm index 8578e0cc078..66a10c95760 100644 --- a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm +++ b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm @@ -25,7 +25,7 @@ melee_damage_upper = 2 environment_smash = 0 stop_automated_movement_when_pulled = 1 - var/obj/udder/udder = null + var/obj/item/udder/udder = null /mob/living/simple_animal/hostile/retaliate/goat/New() udder = new() @@ -98,7 +98,7 @@ attacktext = "kicks" attack_sound = 'sound/weapons/punch1.ogg' health = 50 - var/obj/udder/udder = null + var/obj/item/udder/udder = null gold_core_spawnable = 2 /mob/living/simple_animal/cow/New() @@ -274,28 +274,30 @@ var/global/chicken_count = 0 else SSobj.processing.Remove(src) -/obj/udder -/obj/udder/New() +/obj/item/udder + name = "udder" + +/obj/item/udder/New() reagents = new(50) reagents.my_atom = src reagents.add_reagent("milk", 20) -/obj/udder/proc/generateMilk() +/obj/item/udder/proc/generateMilk() if(prob(5)) reagents.add_reagent("milk", rand(5, 10)) -/obj/udder/proc/milkAnimal(obj/O, mob/user) +/obj/item/udder/proc/milkAnimal(obj/O, mob/user) var/obj/item/weapon/reagent_containers/glass/G = O if(G.reagents.total_volume >= G.volume) user << "[O] is full." return - var/transfered = reagents.trans_id_to(G, "milk", rand(5,10)) + var/transfered = reagents.trans_to(O, rand(5,10)) if(transfered) user.visible_message("[user] milks [src] using \the [O].", "You milk [src] using \the [O].") else user << "The udder is dry. Wait a bit longer..." -/obj/udder/Destroy() +/obj/item/udder/Destroy() qdel(reagents) - return ..() + return ..() \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/guardian/guardian.dm b/code/modules/mob/living/simple_animal/guardian/guardian.dm index 377b89d6e7c..546e4b3a4e2 100644 --- a/code/modules/mob/living/simple_animal/guardian/guardian.dm +++ b/code/modules/mob/living/simple_animal/guardian/guardian.dm @@ -48,6 +48,19 @@ var/global/list/parasites = list() //all currently existing/living guardians ..() +/mob/living/simple_animal/hostile/guardian/med_hud_set_health() + if(summoner) + var/image/holder = hud_list[HEALTH_HUD] + holder.icon_state = "hud[RoundHealth(summoner)]" + +/mob/living/simple_animal/hostile/guardian/med_hud_set_status() + if(summoner) + var/image/holder = hud_list[STATUS_HUD] + if(summoner.stat == DEAD) + holder.icon_state = "huddead" + else + holder.icon_state = "hudhealthy" + /mob/living/simple_animal/hostile/guardian/Destroy() parasites -= src return ..() @@ -103,8 +116,9 @@ var/global/list/parasites = list() //all currently existing/living guardians /mob/living/simple_animal/hostile/guardian/Life() //Dies if the summoner dies ..() - update_health_hud() //we need to update our health display to match our summoner and we can't practically give the summoner a hook to do it - + update_health_hud() //we need to update all of our health displays to match our summoner and we can't practically give the summoner a hook to do it + med_hud_set_health() + med_hud_set_status() if(summoner) if(summoner.stat == DEAD) src << "Your summoner has died!" diff --git a/code/modules/mob/living/simple_animal/guardian/guardiannaming.dm b/code/modules/mob/living/simple_animal/guardian/guardiannaming.dm index db04e530481..662a3853878 100644 --- a/code/modules/mob/living/simple_animal/guardian/guardiannaming.dm +++ b/code/modules/mob/living/simple_animal/guardian/guardiannaming.dm @@ -17,6 +17,30 @@ /datum/guardianname/carp/New() prefixname = pick(carp_names) +/datum/guardianname/carp/sand + suffixcolour = "Sand" + colour = "#C2B280" + +/datum/guardianname/carp/seashell + suffixcolour = "Seashell" + colour = "#FFF5EE" + +/datum/guardianname/carp/coral + suffixcolour = "Coral" + colour = "#FF7F50" + +/datum/guardianname/carp/salmon + suffixcolour = "Salmon" + colour = "#FA8072" + +/datum/guardianname/carp/sunset + suffixcolour = "Sunset" + colour = "#FAD6A5" + +/datum/guardianname/carp/riptide + suffixcolour = "Riptide" + colour = "#89D9C8" + /datum/guardianname/carp/seagreen suffixcolour = "Sea Green" colour = "#2E8B57" diff --git a/code/modules/mob/living/simple_animal/guardian/types/support.dm b/code/modules/mob/living/simple_animal/guardian/types/support.dm index 59fa99f35b3..e3bc381f209 100644 --- a/code/modules/mob/living/simple_animal/guardian/types/support.dm +++ b/code/modules/mob/living/simple_animal/guardian/types/support.dm @@ -38,6 +38,10 @@ var/obj/effect/overlay/temp/heal/H = PoolOrNew(/obj/effect/overlay/temp/heal, get_turf(C)) if(namedatum) H.color = namedatum.colour + if(C == summoner) + update_health_hud() + med_hud_set_health() + med_hud_set_status() /mob/living/simple_animal/hostile/guardian/healer/ToggleMode() if(src.loc == summoner) diff --git a/code/modules/mob/living/simple_animal/hostile/giant_spider.dm b/code/modules/mob/living/simple_animal/hostile/giant_spider.dm index 01d04dc084f..7c33ecbe6c4 100644 --- a/code/modules/mob/living/simple_animal/hostile/giant_spider.dm +++ b/code/modules/mob/living/simple_animal/hostile/giant_spider.dm @@ -49,7 +49,7 @@ see_invisible = SEE_INVISIBLE_MINIMUM see_in_dark = 4 var/playable_spider = FALSE - + /mob/living/simple_animal/hostile/poison/giant_spider/Topic(href, href_list) if(href_list["activate"]) var/mob/dead/observer/ghost = usr @@ -57,18 +57,20 @@ humanize_spider(ghost) /mob/living/simple_animal/hostile/poison/giant_spider/attack_ghost(mob/user) - humanize_spider(user) + if(!humanize_spider(user)) + return ..() /mob/living/simple_animal/hostile/poison/giant_spider/proc/humanize_spider(mob/user) if(key || !playable_spider)//Someone is in it or the fun police are shutting it down - return + return 0 var/spider_ask = alert("Become a spider?", "Are you australian?", "Yes", "No") if(spider_ask == "No" || !src || qdeleted(src)) - return + return 1 if(key) user << "Someone else already took this spider." - return + return 1 key = user.key + return 1 //nursemaids - these create webs and eggs /mob/living/simple_animal/hostile/poison/giant_spider/nurse diff --git a/code/modules/mob/living/simple_animal/hostile/headcrab.dm b/code/modules/mob/living/simple_animal/hostile/headcrab.dm index d1a829a5483..60e9d09b387 100644 --- a/code/modules/mob/living/simple_animal/hostile/headcrab.dm +++ b/code/modules/mob/living/simple_animal/hostile/headcrab.dm @@ -23,13 +23,13 @@ gold_core_spawnable = 1 //are you sure about this?? /mob/living/simple_animal/hostile/headcrab/proc/Infect(mob/living/carbon/victim) - var/obj/item/organ/internal/body_egg/changeling_egg/egg = new(victim) + var/obj/item/organ/body_egg/changeling_egg/egg = new(victim) egg.Insert(victim) if(origin) egg.origin = origin else if(mind) // Let's make this a feature egg.origin = mind - for(var/obj/item/organ/internal/I in src) + for(var/obj/item/organ/I in src) I.loc = egg visible_message("[src] plants something in [victim]'s flesh!", \ "We inject our egg into [victim]'s body!") @@ -56,14 +56,14 @@ -/obj/item/organ/internal/body_egg/changeling_egg +/obj/item/organ/body_egg/changeling_egg name = "changeling egg" desc = "Twitching and disgusting." origin_tech = "biotech=7" // You need to be really lucky to obtain it. var/datum/mind/origin var/time -/obj/item/organ/internal/body_egg/changeling_egg/egg_process() +/obj/item/organ/body_egg/changeling_egg/egg_process() // Changeling eggs grow in dead people time++ if(time >= EGG_INCUBATION_TIME) @@ -71,11 +71,11 @@ Remove(owner) qdel(src) -/obj/item/organ/internal/body_egg/changeling_egg/proc/Pop() +/obj/item/organ/body_egg/changeling_egg/proc/Pop() var/mob/living/carbon/monkey/M = new(owner) owner.stomach_contents += M - for(var/obj/item/organ/internal/I in src) + for(var/obj/item/organ/I in src) I.Insert(M, 1) if(origin && origin.current && (origin.current.stat == DEAD)) diff --git a/code/modules/mob/living/simple_animal/hostile/mecha_pilot.dm b/code/modules/mob/living/simple_animal/hostile/mecha_pilot.dm index 0afa18e866b..63d3bd82565 100644 --- a/code/modules/mob/living/simple_animal/hostile/mecha_pilot.dm +++ b/code/modules/mob/living/simple_animal/hostile/mecha_pilot.dm @@ -43,7 +43,20 @@ ..() wanted_objects = subtypesof(/obj/mecha/combat) +/mob/living/simple_animal/hostile/syndicate/mecha_pilot/nanotrasen //nanotrasen are syndies! no it's just a weird path. + name = "Nanotrasen Mecha Pilot" + desc = "Death to the Syndicate. This variant comes in MECHA DEATH flavour." + icon_living = "nanotrasen" + icon_state = "nanotrasen" + faction = list("nanotrasen") + spawn_mecha_type = /obj/mecha/combat/marauder/loaded +/mob/living/simple_animal/hostile/syndicate/mecha_pilot/no_mech/nanotrasen + name = "Nanotrasen Mecha Pilot" + desc = "Death to the Syndicate. This variant comes in MECHA DEATH flavour." + icon_living = "nanotrasen" + icon_state = "nanotrasen" + faction = list("nanotrasen") /mob/living/simple_animal/hostile/syndicate/mecha_pilot/New() @@ -99,6 +112,7 @@ ranged = 0 minimum_distance = 1 + walk(M,0)//end any lingering movement loops, to prevent the haunted mecha bug //Checks if a mecha is valid for theft /mob/living/simple_animal/hostile/syndicate/mecha_pilot/proc/is_valid_mecha(obj/mecha/M) @@ -253,6 +267,10 @@ else //we're not in a mecha, so we check if we can steal it instead. if(is_valid_mecha(M)) return 1 + else if (M.occupant && CanAttack(M.occupant)) + return 1 + else + return 0 . = ..() diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/dragon.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/dragon.dm index 0fe95918f9f..0267d112d90 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/dragon.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/dragon.dm @@ -24,7 +24,7 @@ aggro_vision_range = 18 idle_vision_range = 5 loot = list(/obj/structure/closet/crate/necropolis/dragon) - butcher_results = list(/obj/item/weapon/ore/diamond = 5, /obj/item/stack/sheet/sinew = 5, /obj/item/stack/sheet/animalhide/goliath_hide = 8, /obj/item/stack/sheet/bone = 30) + butcher_results = list(/obj/item/weapon/ore/diamond = 5, /obj/item/stack/sheet/sinew = 5, /obj/item/stack/sheet/animalhide/ashdrake = 10, /obj/item/stack/sheet/bone = 30) var/anger_modifier = 0 var/obj/item/device/gps/internal var/swooping = 0 @@ -73,7 +73,7 @@ var/obj/effect/overlay/temp/fireball/F = new(src.loc) animate(F, pixel_z = 0, time = 12) sleep(12) - explosion(T, 0, 0, 1, 0, 1, 0) + explosion(T, 0, 0, 1, 0, 0, 0, 1) qdel(F) qdel(src) @@ -87,7 +87,7 @@ else fire_rain() - else if(prob(10+anger_modifier) && !client) + else if(prob(10+anger_modifier) && !client && !swooping) if(health > maxHealth/2) swoop_attack() else @@ -121,6 +121,10 @@ PoolOrNew(/obj/effect/hotspot,J) J.hotspot_expose(700,50,1) + for(var/mob/living/L in J) + if(L != src) + L.adjustFireLoss(20) + L << "You're hit by the drake's fire breath!" /mob/living/simple_animal/hostile/megafauna/dragon/proc/swoop_attack(fire_rain = 0) if(stat) @@ -150,6 +154,8 @@ sleep(10) playsound(src, 'sound/effects/meteorimpact.ogg', 200, 1) for(var/mob/living/L in range(1,tturf)) + if(L == src) + continue if(L.stat) visible_message("[src] slams down on [L], crushing them!") L.gib() @@ -190,7 +196,9 @@ /obj/item/weapon/melee/ghost_sword/attack_self(mob/user) if(summon_cooldown > world.time) + user << "You just recently called out for aid. You don't want to annoy the spirits." return + user << "You call out for aid, attempting to summon spirits to your side." notify_ghosts("[user] is raising their [src], calling for your help!", source = user) summon_cooldown = world.time + 600 @@ -290,6 +298,7 @@ w_class = 4 force = 25 damtype = BURN + burn_state = LAVA_PROOF hitsound = 'sound/weapons/sear.ogg' var/lava_cooldown = 0 @@ -320,4 +329,4 @@ if(3) new /obj/item/weapon/dragons_blood(src) if(4) - new /obj/item/weapon/lava_staff(src) \ No newline at end of file + new /obj/item/weapon/lava_staff(src) diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs.dm index 7adf03d0eaf..d66f5fe2aae 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs.dm @@ -49,7 +49,7 @@ /mob/living/simple_animal/hostile/asteroid/basilisk name = "basilisk" desc = "A territorial beast, covered in a thick shell that absorbs energy. Its stare causes victims to freeze from the inside." - icon = 'icons/mob/animal.dmi' + icon = 'icons/mob/lavaland/lavaland_monsters.dmi' icon_state = "Basilisk" icon_living = "Basilisk" icon_aggro = "Basilisk_alert" @@ -91,10 +91,7 @@ /mob/living/simple_animal/hostile/asteroid/basilisk/GiveTarget(new_target) if(..()) //we have a target if(isliving(target)) - var/mob/living/L = target - if(L.bodytemperature > 200) - L.bodytemperature = 200 - visible_message("The [src.name]'s stare chills [L.name] to the bone!") + OpenFire(target) /mob/living/simple_animal/hostile/asteroid/basilisk/ex_act(severity, target) switch(severity) @@ -108,7 +105,7 @@ /mob/living/simple_animal/hostile/asteroid/goldgrub name = "goldgrub" desc = "A worm that grows fat from eating everything in its sight. Seems to enjoy precious metals and other shiny things, hence the name." - icon = 'icons/mob/animal.dmi' + icon = 'icons/mob/lavaland/lavaland_monsters.dmi' icon_state = "Goldgrub" icon_living = "Goldgrub" icon_aggro = "Goldgrub_alert" @@ -186,7 +183,7 @@ /mob/living/simple_animal/hostile/asteroid/hivelord name = "hivelord" desc = "A truly alien creature, it is a mass of unknown organic material, constantly fluctuating. When attacking, pieces of it split off and attack in tandem with the original." - icon = 'icons/mob/animal.dmi' + icon = 'icons/mob/lavaland/lavaland_monsters.dmi' icon_state = "Hivelord" icon_living = "Hivelord" icon_aggro = "Hivelord_alert" @@ -214,7 +211,7 @@ retreat_distance = 3 minimum_distance = 3 pass_flags = PASSTABLE - loot = list(/obj/item/organ/internal/hivelord_core) + loot = list(/obj/item/organ/hivelord_core) var/brood_type = /mob/living/simple_animal/hostile/asteroid/hivelordbrood /mob/living/simple_animal/hostile/asteroid/hivelord/OpenFire(the_target) @@ -233,28 +230,45 @@ mouse_opacity = 1 ..(gibbed) -/obj/item/organ/internal/hivelord_core +/obj/item/organ/hivelord_core name = "hivelord remains" desc = "All that remains of a hivelord, it seems to be what allows it to break pieces of itself off without being hurt... its healing properties will soon become inert if not used quickly." icon_state = "roro core 2" flags = NOBLUDGEON slot = "hivecore" force = 0 + actions_types = list(/datum/action/item_action/organ_action/use) var/inert = 0 var/preserved = 0 + var/list/spawned_brood = list() -/obj/item/organ/internal/hivelord_core/New() +/obj/item/organ/hivelord_core/New() ..() spawn(2400) if(!owner && !preserved) inert = 1 desc = "The remains of a hivelord that have become useless, having been left alone too long after being harvested." - feedback_add_details("hivelord_core", "[src.type]|inert") else preserved = 1 - feedback_add_details("hivelord_core", "[src.type]|implanted") -/obj/item/organ/internal/hivelord_core/on_life() +/obj/item/organ/hivelord_core/ui_action_click() + var/spawn_amount = 1 + if(!inert) + spawn_amount++ + + for(var/a in spawned_brood) + if(!istype(a, /mob/living/simple_animal/hostile/asteroid/hivelordbrood) || qdeleted(a)) + spawned_brood -= a + continue + spawn_amount -= spawned_brood.len + + for(var/i = 1 to spawn_amount) + var/mob/living/simple_animal/hostile/asteroid/hivelordbrood/blood/B = new (owner.loc) + B.link_host(owner) + spawned_brood |= B + + +/obj/item/organ/hivelord_core/on_life() ..() if(owner) owner.adjustBruteLoss(-1) @@ -267,7 +281,7 @@ if(B && blood_volume < 560 && blood_volume) B.volume += 2 // Fast blood regen -/obj/item/organ/internal/hivelord_core/afterattack(atom/target, mob/user, proximity_flag) +/obj/item/organ/hivelord_core/afterattack(atom/target, mob/user, proximity_flag) if(proximity_flag && ishuman(target)) var/mob/living/carbon/human/H = target if(inert) @@ -278,22 +292,20 @@ user << "[src] are useless on the dead." return if(H != user) - feedback_add_details("hivelord_core","[src.type]|used|other") H.visible_message("[user] forces [H] to apply [src]... they quickly regenerate all injuries!") else user << "You start to smear [src] on yourself. It feels and smells disgusting, but you feel amazingly refreshed in mere moments." - feedback_add_details("hivelord_core","[src.type]|used|self") H.revive(full_heal = 1) qdel(src) ..() -/obj/item/organ/internal/hivelord_core/prepare_eat() +/obj/item/organ/hivelord_core/prepare_eat() return null /mob/living/simple_animal/hostile/asteroid/hivelordbrood name = "hivelord brood" desc = "A fragment of the original Hivelord, rallying behind its original. One isn't much of a threat, but..." - icon = 'icons/mob/animal.dmi' + icon = 'icons/mob/lavaland/lavaland_monsters.dmi' icon_state = "Hivelordbrood" icon_living = "Hivelordbrood" icon_aggro = "Hivelordbrood" @@ -306,6 +318,7 @@ speed = 3 maxHealth = 1 health = 1 + flying = 1 harm_intent_damage = 5 melee_damage_lower = 2 melee_damage_upper = 2 @@ -320,12 +333,94 @@ /mob/living/simple_animal/hostile/asteroid/hivelordbrood/New() ..() spawn(100) - qdel(src) + death() + +/mob/living/simple_animal/hostile/asteroid/hivelordbrood/blood + name = "blood brood" + desc = "A living string of blood and alien materials." + icon_state = "bloodbrood" + icon_living = "bloodbrood" + icon_aggro = "bloodbrood" + attacktext = "pierces" + color = "#C80000" + +/mob/living/simple_animal/hostile/asteroid/hivelordbrood/blood/death() + if(loc) // Splash the turf we are on with blood + reagents.reaction(get_turf(src)) + ..() + +/mob/living/simple_animal/hostile/asteroid/hivelordbrood/blood/New() + create_reagents(30) + ..() + +/mob/living/simple_animal/hostile/asteroid/hivelordbrood/blood/AttackingTarget() + ..() + if(iscarbon(target)) + transfer_reagents(target, 1) + + +/mob/living/simple_animal/hostile/asteroid/hivelordbrood/blood/attack_hand(mob/living/carbon/human/M) + if("\ref[M]" in faction) + reabsorb_host(M) + else + return ..() + +/mob/living/simple_animal/hostile/asteroid/hivelordbrood/blood/attack_paw(mob/living/carbon/monkey/M) + if("\ref[M]" in faction) + reabsorb_host(M) + else + return ..() + +/mob/living/simple_animal/hostile/asteroid/hivelordbrood/blood/attack_alien(mob/living/carbon/alien/humanoid/M) + if("\ref[M]" in faction) + reabsorb_host(M) + else + return ..() + + +/mob/living/simple_animal/hostile/asteroid/hivelordbrood/blood/proc/reabsorb_host(mob/living/carbon/C) + C.visible_message("[src] is reabsorbed by [C]'s body.", \ + "[src] is reabsorbed by your body.") + transfer_reagents(C) + death() + +/mob/living/simple_animal/hostile/asteroid/hivelordbrood/blood/proc/transfer_reagents(mob/living/carbon/C, var/volume = 30) + if(!reagents.total_volume) + return + + volume = min(volume, reagents.total_volume) + + var/fraction = min(volume/reagents.total_volume, 1) + reagents.reaction(C, INJECT, fraction) + + var/datum/reagent/blood/B + for(var/datum/reagent/blood/d in reagents.reagent_list) + B = d + break + if(B) + C.inject_blood(src, min(B.volume, volume)) + + reagents.trans_to(C, volume) + +/mob/living/simple_animal/hostile/asteroid/hivelordbrood/blood/proc/link_host(mob/living/carbon/C) + faction = list("\ref[src]", "\ref[C]") // Hostile to everyone except the host. + var/datum/reagent/B = C.take_blood(src, 30) + if(!B) + if(ishuman(C)) + var/mob/living/carbon/human/H = C + if(H.dna.species.exotic_blood && H.reagents.total_volume) + H.reagents.trans_to(src, 10) + + else + reagents.reagent_list += B + reagents.update_total() + + color = mix_color_from_reagents(reagents.reagent_list) /mob/living/simple_animal/hostile/asteroid/goliath name = "goliath" desc = "A massive beast that uses long tentacles to ensare its prey, threatening them is not advised under any conditions." - icon = 'icons/mob/animal.dmi' + icon = 'icons/mob/lavaland/lavaland_monsters.dmi' icon_state = "Goliath" icon_living = "Goliath" icon_aggro = "Goliath_alert" @@ -402,7 +497,7 @@ /obj/effect/goliath_tentacle/ name = "Goliath tentacle" - icon = 'icons/mob/animal.dmi' + icon = 'icons/mob/lavaland/lavaland_monsters.dmi' icon_state = "Goliath_tentacle" var/latched = 0 anchored = 1 @@ -493,7 +588,7 @@ /mob/living/simple_animal/hostile/asteroid/fugu name = "wumborian fugu" desc = "The wumborian fugu rapidly increases its body mass in order to ward off its prey. Great care should be taken to avoid it while it's in this state as it is nearly invincible, but it cannot maintain its form forever." - icon = 'icons/mob/animal.dmi' + icon = 'icons/mob/lavaland/lavaland_monsters.dmi' icon_state = "Fugu" icon_living = "Fugu" icon_aggro = "Fugu" @@ -677,7 +772,7 @@ speak_emote = list("echoes") attack_sound = 'sound/weapons/pierce.ogg' throw_message = "bounces harmlessly off of" - loot = list(/obj/item/organ/internal/hivelord_core/legion) + loot = list(/obj/item/organ/hivelord_core/legion) brood_type = /mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion del_on_death = 1 stat_attack = 1 @@ -717,7 +812,6 @@ del_on_death = 1 stat_attack = 1 robust_searching = 1 - layer = 6.1 /mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion/Life() if(isturf(src.loc)) @@ -732,14 +826,135 @@ qdel(src) ..() -/obj/item/organ/internal/hivelord_core/legion +/obj/item/organ/hivelord_core/legion name = "legion's heart" desc = "A demonic, still beating heart... its healing properties will soon become inert if not used quickly." icon = 'icons/obj/surgery.dmi' icon_state = "demon_heart" -//Nests +/obj/item/weapon/legion_skull + name = "legion's head" + desc = "The once living, now empty eyes of the former human's skull cut deep into your soul." + icon = 'icons/obj/mining.dmi' + icon_state = "skull" + +//Gutlunches + +/mob/living/simple_animal/hostile/asteroid/gutlunch + name = "gutlunch" + desc = "A scavenger that eats raw meat, often found alongside ash walkers. Produces a thick, nutritious milk." + icon = 'icons/mob/lavaland/lavaland_monsters.dmi' + icon_state = "gutlunch" + icon_living = "gutlunch" + icon_dead = "gutlunch" + speak_emote = list("warbles", "quavers") + emote_hear = list("trills.") + emote_see = list("sniffs.", "burps.") + density = 0 + speak_chance = 1 + turns_per_move = 8 + environment_smash = 0 + move_to_delay = 15 + response_help = "pets" + response_disarm = "gently pushes aside" + response_harm = "squishes" + friendly = "pinches" + a_intent = "help" + ventcrawler = 2 + gold_core_spawnable = 2 + stat_attack = 1 + gender = NEUTER + stop_automated_movement = FALSE + stop_automated_movement_when_pulled = TRUE + stat_exclusive = TRUE + robust_searching = TRUE + search_objects = TRUE + del_on_death = TRUE + loot = list(/obj/effect/decal/cleanable/blood/gibs) + + animal_species = /mob/living/simple_animal/hostile/asteroid/gutlunch + childtype = list(/mob/living/simple_animal/hostile/asteroid/gutlunch/gubbuck = 45, /mob/living/simple_animal/hostile/asteroid/gutlunch/guthen = 55) + + wanted_objects = list(/obj/effect/decal/cleanable/xenoblood/xgibs, /obj/effect/decal/cleanable/blood/gibs/) + var/obj/item/udder/gutlunch/udder = null + + +/mob/living/simple_animal/hostile/asteroid/gutlunch/New() + udder = new() + deathmessage = "[src] is pulped into bugmash." + ..() + +/mob/living/simple_animal/hostile/asteroid/gutlunch/Destroy() + qdel(udder) + udder = null + return ..() + +/mob/living/simple_animal/hostile/asteroid/gutlunch/regenerate_icons() + overlays.Cut() + if(udder.reagents.total_volume == udder.reagents.maximum_volume) + overlays += "gl_full" + ..() + +/mob/living/simple_animal/hostile/asteroid/gutlunch/attackby(obj/item/O, mob/user, params) + if(stat == CONSCIOUS && istype(O, /obj/item/weapon/reagent_containers/glass)) + udder.milkAnimal(O, user) + regenerate_icons() + else + ..() + +/mob/living/simple_animal/hostile/asteroid/gutlunch/AttackingTarget() + if(is_type_in_list(target,wanted_objects)) //we eats + udder.generateMilk() + regenerate_icons() + visible_message("[src] slurps up [target].") + qdel(target) + ..() + + +/obj/item/udder/gutlunch + name = "nutrient sac" + +/obj/item/udder/gutlunch/New() + reagents = new(50) + reagents.my_atom = src + +/obj/item/udder/gutlunch/generateMilk() + if(prob(60)) + reagents.add_reagent("cream", rand(2, 5)) + if(prob(45)) + reagents.add_reagent("salglu_solution", rand(2,5)) + + +//Male gutlunch. They're smaller and more colorful! +/mob/living/simple_animal/hostile/asteroid/gutlunch/gubbuck + name = "gubbuck" + gender = MALE + +/mob/living/simple_animal/hostile/asteroid/gutlunch/gubbuck/New() + ..() + color = pick("#E39FBB", "#D97D64", "#CF8C4A") + resize = 0.85 + update_transform() + + +//Lady gutlunch. They make the babby. +/mob/living/simple_animal/hostile/asteroid/gutlunch/guthen + name = "guthen" + gender = FEMALE + +/mob/living/simple_animal/hostile/asteroid/gutlunch/guthen/Life() + ..() + if(udder.reagents.total_volume == udder.reagents.maximum_volume) //Only breed when we're full. + make_babies() + +/mob/living/simple_animal/hostile/asteroid/gutlunch/guthen/make_babies() + if(..()) + udder.reagents.clear_reagents() + regenerate_icons() + + +//Nests /mob/living/simple_animal/hostile/spawner/lavaland name = "necropolis tendril" desc = "A vile tendril of corruption, originating deep underground. Terrible monsters are pouring out of it." diff --git a/code/modules/mob/living/simple_animal/hostile/syndicate.dm b/code/modules/mob/living/simple_animal/hostile/syndicate.dm index 2ee585ae7cb..a71f5fe68e9 100644 --- a/code/modules/mob/living/simple_animal/hostile/syndicate.dm +++ b/code/modules/mob/living/simple_animal/hostile/syndicate.dm @@ -168,4 +168,4 @@ /mob/living/simple_animal/hostile/viscerator/New() ..() - deathmessage = "[src] is smashed into pieces!" + deathmessage = "[src] is smashed into pieces!" diff --git a/code/modules/mob/living/simple_animal/hostile/zombie.dm b/code/modules/mob/living/simple_animal/hostile/zombie.dm index dd2e54c8bfd..8d96e162f1e 100644 --- a/code/modules/mob/living/simple_animal/hostile/zombie.dm +++ b/code/modules/mob/living/simple_animal/hostile/zombie.dm @@ -55,11 +55,13 @@ if(istype(target, /obj/machinery/door/airlock)) if(!removingairlock) - src << "You start tearing apart the airlock..." - playsound(src.loc, 'sound/hallucinations/growl3.ogg', 50, 1) var/obj/machinery/door/airlock/A = target removingairlock = 1 - if(do_after(src, 200, 0, A, 1)) + src << "You start tearing apart the airlock..." + playsound(src.loc, 'sound/machines/airlock_alien_prying.ogg', 100, 1) + spawn(20) + playsound(src.loc, 'sound/hallucinations/growl3.ogg', 50, 1) + if(do_after(src, 160, 0, A, 1)) playsound(src.loc, 'sound/hallucinations/far_noise.ogg', 50, 1) var/obj/structure/door_assembly/door = new A.doortype(get_turf(A)) door.density = 0 diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index 81ee2da1dce..fe8d46b2137 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -56,7 +56,7 @@ //Hot simple_animal baby making vars var/list/childtype = null var/scan_ready = 1 - var/species //Sorry, no spider+corgi buttbabies. + var/animal_species //Sorry, no spider+corgi buttbabies. //simple_animal access var/obj/item/weapon/card/id/access_card = null //innate access uses an internal ID card @@ -111,6 +111,7 @@ death() else stat = CONSCIOUS + med_hud_set_status() /mob/living/simple_animal/handle_status_effects() @@ -461,8 +462,8 @@ ..() /mob/living/simple_animal/proc/make_babies() // <3 <3 <3 - if(gender != FEMALE || stat || !scan_ready || !childtype || !species || ticker.current_state != GAME_STATE_PLAYING) - return + if(gender != FEMALE || stat || !scan_ready || !childtype || !animal_species || ticker.current_state != GAME_STATE_PLAYING) + return 0 scan_ready = 0 spawn(400) scan_ready = 1 @@ -474,7 +475,7 @@ continue else if(istype(M, childtype)) //Check for children FIRST. children++ - else if(istype(M, species)) + else if(istype(M, animal_species)) if(M.ckey) continue else if(!istype(M, childtype) && M.gender == MALE) //Better safe than sorry ;_; @@ -485,6 +486,8 @@ if(alone && partner && children < 3) var/childspawn = pickweight(childtype) new childspawn(loc) + return 1 + return 0 /mob/living/simple_animal/stripPanelUnequip(obj/item/what, mob/who, where, child_override) if(!child_override) diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index f2bcb507b76..870064d2447 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -233,7 +233,7 @@ var/next_mob_id = 0 return 0 -//This is a SAFE proc. Use this instead of equip_to_splot()! +//This is a SAFE proc. Use this instead of equip_to_slot()! //set qdel_on_fail to have it delete W if it fails to equip //set disable_warning to disable the 'you are unable to equip that' warning. //unset redraw_mob to prevent the mob from being redrawn at the end. @@ -326,7 +326,7 @@ var/next_mob_id = 0 if (!tile) return 0 - PoolOrNew(/obj/effect/overlay/temp/point, list(tile,invisibility)) + PoolOrNew(/obj/effect/overlay/temp/point, list(A,invisibility)) return 1 @@ -676,21 +676,23 @@ var/next_mob_id = 0 /mob/proc/update_canmove() var/ko = weakened || paralysis || stat || (status_flags & FAKEDEATH) var/buckle_lying = !(buckled && !buckled.buckle_lying) + var/has_legs = get_num_legs() + var/has_arms = get_num_arms() if(ko || resting || stunned) drop_r_hand() drop_l_hand() unset_machine() if(pulling) stop_pulling() - else + else if(has_legs) lying = 0 - canmove = 1 + if(buckled) lying = 90*buckle_lying else - if((ko || resting) && !lying) + if((ko || resting || !has_legs) && !lying) fall(ko) - canmove = !(ko || resting || stunned || buckled) + canmove = !(ko || resting || stunned || buckled || (!has_legs && !has_arms)) density = !lying if(lying) if(layer == initial(layer)) //to avoid special cases like hiding larvas. @@ -932,4 +934,4 @@ var/next_mob_id = 0 updatehealth() if("resize") update_transform() - + ..() diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index c8215595f2b..fb1553ba799 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -416,7 +416,7 @@ It's fairly easy to fix if dealing with single letters but not so much with comp A.overlays += alert_overlay /proc/item_heal_robotic(mob/living/carbon/human/H, mob/user, brute, burn) - var/obj/item/organ/limb/affecting = H.get_organ(check_zone(user.zone_selected)) + var/obj/item/bodypart/affecting = H.get_bodypart(check_zone(user.zone_selected)) var/dam //changes repair text based on how much brute/burn was supplied @@ -425,15 +425,15 @@ It's fairly easy to fix if dealing with single letters but not so much with comp else dam = 0 - if(affecting.status == ORGAN_ROBOTIC) - if(brute > 0 && affecting.brute_dam > 0 || burn > 0 && affecting.burn_dam > 0) + if(affecting && affecting.status == ORGAN_ROBOTIC) + if((brute > 0 && affecting.brute_dam > 0) || (burn > 0 && affecting.burn_dam > 0)) affecting.heal_damage(brute,burn,1) H.update_damage_overlays(0) H.updatehealth() - user.visible_message("[user] has fixed some of the [dam ? "dents on" : "burnt wires in"] [H]'s [affecting.getDisplayName()].", "You fix some of the [dam ? "dents on" : "burnt wires in"] [H]'s [affecting.getDisplayName()].") + user.visible_message("[user] has fixed some of the [dam ? "dents on" : "burnt wires in"] [H]'s [affecting].", "You fix some of the [dam ? "dents on" : "burnt wires in"] [H]'s [affecting].") return else - user << "[H]'s [affecting.getDisplayName()] is already in good condition!" + user << "[H]'s [affecting] is already in good condition!" return else return diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm index 3f47e465f66..fca202896d1 100644 --- a/code/modules/mob/transform_procs.dm +++ b/code/modules/mob/transform_procs.dm @@ -12,7 +12,7 @@ implants += W if (tr_flags & TR_KEEPORGANS) - for(var/obj/item/organ/internal/I in internal_organs) + for(var/obj/item/organ/I in internal_organs) int_organs += I I.Remove(src, 1) @@ -80,10 +80,10 @@ //re-add organs to new mob if(tr_flags & TR_KEEPORGANS) - for(var/obj/item/organ/internal/I in O.internal_organs) + for(var/obj/item/organ/I in O.internal_organs) qdel(I) - for(var/obj/item/organ/internal/I in int_organs) + for(var/obj/item/organ/I in int_organs) I.Insert(O, 1) //transfer mind and delete old mob @@ -119,7 +119,7 @@ implants += W if (tr_flags & TR_KEEPORGANS) - for(var/obj/item/organ/internal/I in internal_organs) + for(var/obj/item/organ/I in internal_organs) int_organs += I I.Remove(src, 1) @@ -198,10 +198,10 @@ O.sec_hud_set_implants() if(tr_flags & TR_KEEPORGANS) - for(var/obj/item/organ/internal/I in O.internal_organs) + for(var/obj/item/organ/I in O.internal_organs) qdel(I) - for(var/obj/item/organ/internal/I in int_organs) + for(var/obj/item/organ/I in int_organs) I.Insert(O, 1) if(mind) @@ -230,7 +230,7 @@ /mob/living/carbon/human/AIize() if (notransform) return - for(var/t in organs) + for(var/t in bodyparts) qdel(t) return ..() @@ -315,7 +315,7 @@ canmove = 0 icon = null invisibility = INVISIBILITY_MAXIMUM - for(var/t in organs) + for(var/t in bodyparts) qdel(t) var/mob/living/silicon/robot/R = new /mob/living/silicon/robot(loc) @@ -366,7 +366,7 @@ canmove = 0 icon = null invisibility = INVISIBILITY_MAXIMUM - for(var/t in organs) + for(var/t in bodyparts) qdel(t) var/alien_caste = pick("Hunter","Sentinel","Drone") @@ -396,7 +396,7 @@ canmove = 0 icon = null invisibility = INVISIBILITY_MAXIMUM - for(var/t in organs) + for(var/t in bodyparts) qdel(t) var/mob/living/simple_animal/slime/new_slime @@ -455,7 +455,7 @@ canmove = 0 icon = null invisibility = INVISIBILITY_MAXIMUM - for(var/t in organs) //this really should not be necessary + for(var/t in bodyparts) //this really should not be necessary qdel(t) var/mob/living/simple_animal/pet/dog/corgi/new_corgi = new /mob/living/simple_animal/pet/dog/corgi (loc) @@ -486,7 +486,7 @@ icon = null invisibility = INVISIBILITY_MAXIMUM - for(var/t in organs) + for(var/t in bodyparts) qdel(t) var/mob/new_mob = new mobpath(src.loc) diff --git a/code/modules/ninja/ninja_event.dm b/code/modules/ninja/ninja_event.dm index 26e3f2f5302..903a523d884 100644 --- a/code/modules/ninja/ninja_event.dm +++ b/code/modules/ninja/ninja_event.dm @@ -206,7 +206,7 @@ Contents: equip_to_slot_or_del(new /obj/item/clothing/glasses/night(src), slot_glasses) equip_to_slot_or_del(EK, slot_belt) equip_to_slot_or_del(new /obj/item/device/flashlight(src), slot_r_store) - equip_to_slot_or_del(new /obj/item/weapon/c4(src), slot_l_store) + equip_to_slot_or_del(new /obj/item/weapon/grenade/plastic/x4(src), slot_l_store) equip_to_slot_or_del(new /obj/item/weapon/tank/internals/emergency_oxygen(src), slot_s_store) equip_to_slot_or_del(new /obj/item/weapon/tank/jetpack/carbondioxide(src), slot_back) diff --git a/code/modules/paperwork/handlabeler.dm b/code/modules/paperwork/handlabeler.dm index d679df9e53a..963e094e845 100644 --- a/code/modules/paperwork/handlabeler.dm +++ b/code/modules/paperwork/handlabeler.dm @@ -1,5 +1,6 @@ /obj/item/weapon/hand_labeler name = "hand labeler" + desc = "A combined label printer and applicator in a portable device, designed to be easy to operate and use." icon = 'icons/obj/bureaucracy.dmi' icon_state = "labeler0" item_state = "flight" @@ -7,6 +8,33 @@ var/labels_left = 30 var/mode = 0 +/obj/item/weapon/hand_labeler/suicide_act(mob/user) + user.visible_message("[user] is pointing \the [src] \ + at \himself. They're going to label themselves as a suicide!") + labels_left = max(labels_left - 1, 0) + + var/old_real_name = user.real_name + user.real_name += " (suicide)" + // no conflicts with their identification card + for(var/atom/A in user.GetAllContents()) + if(istype(A, /obj/item/weapon/card/id)) + var/obj/item/weapon/card/id/their_card = A + + // only renames their card, as opposed to tagging everyone's + if(their_card.registered_name != old_real_name) + continue + + their_card.registered_name = user.real_name + their_card.update_label() + + // NOT EVEN DEATH WILL TAKE AWAY THE STAIN + user.mind.name += " (suicide)" + + mode = 1 + icon_state = "labeler[mode]" + label = "suicide" + + return OXYLOSS /obj/item/weapon/hand_labeler/afterattack(atom/A, mob/user,proximity) if(!proximity) return @@ -63,10 +91,32 @@ labels_left = initial(labels_left) return +/obj/item/weapon/hand_labeler/borg + name = "cyborg-hand labeler" + +/obj/item/weapon/hand_labeler/borg/afterattack(atom/A, mob/user, proximity) + ..(A, user, proximity) + if(!isrobot(user)) + return + + var/mob/living/silicon/robot/borgy = user + + var/starting_labels = initial(labels_left) + var/diff = starting_labels - labels_left + if(diff) + labels_left = starting_labels + // 50 per label. Magical cyborg paper doesn't come cheap. + var/cost = diff * 50 + + // If the cyborg manages to use a module without a cell, they get the paper + // for free. + if(borgy.cell) + borgy.cell.use(cost) + /obj/item/hand_labeler_refill name = "hand labeler paper roll" icon = 'icons/obj/bureaucracy.dmi' desc = "A roll of paper. Use it on a hand labeler to refill it." icon_state = "labeler_refill" item_state = "electropack" - w_class = 1 \ No newline at end of file + w_class = 1 diff --git a/code/modules/paperwork/paperplane.dm b/code/modules/paperwork/paperplane.dm index bbde5e50c49..95d67cbdbc2 100644 --- a/code/modules/paperwork/paperplane.dm +++ b/code/modules/paperwork/paperplane.dm @@ -95,7 +95,7 @@ if(..() || !ishuman(hit_atom))//if the plane is caught or it hits a nonhuman return var/mob/living/carbon/human/H = hit_atom - if(prob(15)) + if(prob(2)) if((H.head && H.head.flags_cover & HEADCOVERSEYES) || (H.wear_mask && H.wear_mask.flags_cover & MASKCOVERSEYES) || (H.glasses && H.glasses.flags_cover & GLASSESCOVERSEYES)) return visible_message("\The [src] hits [H] in the eye!") diff --git a/code/modules/power/cable.dm b/code/modules/power/cable.dm index 38d05de6955..341f7cf7e51 100644 --- a/code/modules/power/cable.dm +++ b/code/modules/power/cable.dm @@ -512,9 +512,9 @@ var/global/list/datum/stack_recipe/cable_coil_recipes = list ( \ if(!istype(H)) return ..() - var/obj/item/organ/limb/affecting = H.get_organ(check_zone(user.zone_selected)) - if(affecting.status == ORGAN_ROBOTIC) - user.visible_message("[user] starts to fix some of the wires in [H]'s [affecting.getDisplayName()].", "You start fixing some of the wires in [H]'s [affecting.getDisplayName()].") + var/obj/item/bodypart/affecting = H.get_bodypart(check_zone(user.zone_selected)) + if(affecting && affecting.status == ORGAN_ROBOTIC) + user.visible_message("[user] starts to fix some of the wires in [H]'s [affecting.name].", "You start fixing some of the wires in [H]'s [affecting.name].") if(!do_mob(user, H, 50)) return item_heal_robotic(H, user, 0, 5) diff --git a/code/modules/power/cell.dm b/code/modules/power/cell.dm index d5d7b12abd0..f1b3d4ccbbc 100644 --- a/code/modules/power/cell.dm +++ b/code/modules/power/cell.dm @@ -37,6 +37,7 @@ SSobj.processing |= src else SSobj.processing -= src + ..() /obj/item/weapon/stock_parts/cell/process() if(self_recharge) diff --git a/code/modules/power/lighting.dm b/code/modules/power/lighting.dm index 47b0d481de9..654614f7574 100644 --- a/code/modules/power/lighting.dm +++ b/code/modules/power/lighting.dm @@ -435,8 +435,8 @@ else user << "You try to remove the light [fitting], but you burn your hand on it!" - var/obj/item/organ/limb/affecting = H.get_organ("[user.hand ? "l" : "r" ]_arm") - if(affecting.take_damage( 0, 5 )) // 5 burn damage + var/obj/item/bodypart/affecting = H.get_bodypart("[user.hand ? "l" : "r" ]_arm") + if(affecting && affecting.take_damage( 0, 5 )) // 5 burn damage H.update_damage_overlays(0) H.updatehealth() return // if burned, don't remove the light diff --git a/code/modules/procedural mapping/mapGenerators/lava_river.dm b/code/modules/procedural mapping/mapGenerators/lava_river.dm index 90f9a6c0949..336a7786acb 100644 --- a/code/modules/procedural mapping/mapGenerators/lava_river.dm +++ b/code/modules/procedural mapping/mapGenerators/lava_river.dm @@ -1,9 +1,17 @@ /datum/mapGenerator/lavaland var/start_z = 5 + var/min_x = 0 + var/min_y = 0 + var/max_x = 0 + var/max_y = 0 modules = list(/datum/mapGeneratorModule/river) /datum/mapGenerator/lavaland/defineRegion(turf/Start, turf/End, replace = 0) start_z = Start.z + min_x = min(Start.x,End.x) + min_y = min(Start.y,End.y) + max_x = max(Start.x,End.x) + max_y = max(Start.y,End.y) ..() /datum/mapGeneratorModule/river @@ -12,7 +20,8 @@ var/start_z = 5 /datum/mapGeneratorModule/river/generate() - if(istype(mother, /datum/mapGenerator/lavaland)) - var/datum/mapGenerator/lavaland/L = mother - start_z = L.start_z - spawn_rivers(start_z, river_nodes, river_type) + var/datum/mapGenerator/lavaland/L = mother + if(!istype(L)) + return + start_z = L.start_z + spawn_rivers(start_z, river_nodes, river_type, min_x = L.min_x, min_y = L.min_y, max_x = L.max_x, max_y = L.max_y) diff --git a/code/modules/projectiles/guns/energy.dm b/code/modules/projectiles/guns/energy.dm index b2766731b3b..8f79ac1c510 100644 --- a/code/modules/projectiles/guns/energy.dm +++ b/code/modules/projectiles/guns/energy.dm @@ -163,3 +163,4 @@ SSobj.processing |= src else SSobj.processing -= src + ..() \ No newline at end of file diff --git a/code/modules/projectiles/guns/energy/stun.dm b/code/modules/projectiles/guns/energy/stun.dm index 8342edc0ce2..ddd2bab6064 100644 --- a/code/modules/projectiles/guns/energy/stun.dm +++ b/code/modules/projectiles/guns/energy/stun.dm @@ -21,10 +21,10 @@ fire_sound = 'sound/weapons/gunshot.ogg' e_cost = 200 select_name = "stun" - projectile_type = /obj/item/projectile/shock_revolver + projectile_type = /obj/item/projectile/energy/shock_revolver -/obj/item/projectile/shock_revolver +/obj/item/projectile/energy/shock_revolver name = "shock bolt" icon_state = "purple_laser" var/chain @@ -35,7 +35,7 @@ spawn(1) P.chain = P.Beam(user,icon_state="purple_lightning",icon = 'icons/effects/effects.dmi',time=1000, maxdistance = 30) -/obj/item/projectile/shock_revolver/on_hit(atom/target) +/obj/item/projectile/energy/shock_revolver/on_hit(atom/target) . = ..() if(isliving(target)) tesla_zap(src, 3, 10000) diff --git a/code/modules/projectiles/guns/projectile/revolver.dm b/code/modules/projectiles/guns/projectile/revolver.dm index 68aeeebcd52..e064f90c85d 100644 --- a/code/modules/projectiles/guns/projectile/revolver.dm +++ b/code/modules/projectiles/guns/projectile/revolver.dm @@ -248,12 +248,12 @@ var/obj/item/ammo_casing/AC = chambered if(AC.fire(user, user)) playsound(user, fire_sound, 50, 1) - var/obj/item/organ/limb/affecting = H.get_organ(check_zone(user.zone_selected)) - var/limb_name = affecting.getDisplayName() - if(affecting.name == "head" || affecting.name == "eyes" || affecting.name == "mouth") + var/zone = check_zone(user.zone_selected) + var/obj/item/bodypart/affecting = H.get_bodypart(zone) + if(zone == "head" || zone == "eyes" || zone == "mouth") shoot_self(user, affecting) else - user.visible_message("[user.name] cowardly fires [src] at \his [limb_name]!", "You cowardly fire [src] at your [limb_name]!", "You hear a gunshot!") + user.visible_message("[user.name] cowardly fires [src] at \his [affecting.name]!", "You cowardly fire [src] at your [affecting.name]!", "You hear a gunshot!") return user.visible_message("*click*") diff --git a/code/modules/projectiles/projectile/magic.dm b/code/modules/projectiles/projectile/magic.dm index 8d883cafefc..a7499d447a3 100644 --- a/code/modules/projectiles/projectile/magic.dm +++ b/code/modules/projectiles/projectile/magic.dm @@ -265,7 +265,7 @@ H.real_name = H.dna.species.random_name(H.gender,1) H.update_body() H.update_hair() - H.update_mutcolor() + H.update_body_parts() H.dna.update_dna_identity() else return diff --git a/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm b/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm index 7537b9a67ec..46759d13382 100644 --- a/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm @@ -709,7 +709,8 @@ All effects don't start immediately, but rather get worse over time; the rate is step_towards(O, get_turf(M)) return ..() -/datum/reagent/consumable/ethanol/hearty_punch //Another reference. Heals those in critical condition extremely quickly. If you die with it in your system, it will be removed and you will live! +// Another reference. Heals those in critical condition extremely quickly. +/datum/reagent/consumable/ethanol/hearty_punch name = "Hearty Punch" id = "hearty_punch" description = "Brave bull/syndicate bomb/absinthe mixture resulting in an energizing beverage. Mild alcohol content." diff --git a/code/modules/reagents/chemistry/reagents/food_reagents.dm b/code/modules/reagents/chemistry/reagents/food_reagents.dm index 878e2c2ad0a..bca21857b2d 100644 --- a/code/modules/reagents/chemistry/reagents/food_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/food_reagents.dm @@ -119,7 +119,7 @@ /datum/reagent/consumable/frostoil name = "Frost Oil" id = "frostoil" - description = "A special oil that noticably chills the body. Extraced from Icepeppers." + description = "A special oil that noticably chills the body. Extracted from Icepeppers and slimes." color = "#8BA6E9" // rgb: 139, 166, 233 /datum/reagent/consumable/frostoil/on_mob_life(mob/living/M) @@ -152,8 +152,11 @@ if(reac_volume >= 5) for(var/mob/living/simple_animal/slime/M in T) M.adjustToxLoss(rand(15,30)) - //if(istype(T)) - // T.atmos_spawn_air(SPAWN_COLD) + if(reac_volume >= 1) // Make Freezy Foam and anti-fire grenades! + if(istype(T, /turf/open)) + var/turf/open/OT = T + OT.MakeSlippery(TURF_WET_WATER) // Is less effective in high pressure/high heat capacity environments. More effective in low pressure. + OT.air.temperature -= MOLES_CELLSTANDARD*100*reac_volume/OT.air.heat_capacity() // reduces environment temperature by 5K per unit. /datum/reagent/consumable/condensedcapsaicin name = "Condensed Capsaicin" diff --git a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm index 6b821adc2f7..a12a1d56bfe 100644 --- a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm @@ -406,7 +406,7 @@ /datum/reagent/medicine/pen_acid name = "Pentetic Acid" id = "pen_acid" - description = "Reduces massive amounts of radiation and toxin damage while purging other chemicals from the body. Has a chance of dealing brute damage." + description = "Reduces massive amounts of radiation and toxin damage while purging other chemicals from the body." reagent_state = LIQUID color = "#C8A5DC" metabolization_rate = 0.5 * REAGENTS_METABOLISM @@ -1057,4 +1057,4 @@ datum/reagent/medicine/syndicate_nanites/on_mob_life(mob/living/M) M.status_flags |= GOTTAGOREALLYFAST M.adjustToxLoss(2, 0) . = 1 - ..() \ No newline at end of file + ..() diff --git a/code/modules/reagents/chemistry/reagents/other_reagents.dm b/code/modules/reagents/chemistry/reagents/other_reagents.dm index dd753c9c057..f0020af71d8 100644 --- a/code/modules/reagents/chemistry/reagents/other_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm @@ -188,7 +188,7 @@ M.confused = 1 M.confused += 3 if(iscultist(M) || (is_handofgod_cultist(M) && !is_handofgod_prophet(M))) - ticker.mode.remove_cultist(M.mind) + ticker.mode.remove_cultist(M.mind, 1, 1) ticker.mode.remove_hog_follower(M.mind) holder.remove_reagent(src.id, src.volume) // maybe this is a little too perfect and a max() cap on the statuses would be better?? M.jitteriness = 0 @@ -254,7 +254,7 @@ /datum/reagent/lube/reaction_turf(turf/open/T, reac_volume) if (!istype(T)) return if(reac_volume >= 1) - T.MakeSlippery(2) + T.MakeSlippery(TURF_WET_LUBE) /datum/reagent/spraytan name = "Spray Tan" diff --git a/code/modules/reagents/reagent_containers/spray.dm b/code/modules/reagents/reagent_containers/spray.dm index 4a9eb41cbc2..f999590d933 100644 --- a/code/modules/reagents/reagent_containers/spray.dm +++ b/code/modules/reagents/reagent_containers/spray.dm @@ -136,6 +136,13 @@ desc = "BLAM!-brand non-foaming space cleaner!" list_reagents = list("cleaner" = 250) +/obj/item/weapon/reagent_containers/spray/spraytan + name = "spray tan" + volume = 50 + desc = "Gyaro brand spray tan. Do not spray near eyes or other orifices." + list_reagents = list("spraytan" = 50) + + //pepperspray /obj/item/weapon/reagent_containers/spray/pepper name = "pepperspray" diff --git a/code/modules/reagents/reagent_containers/syringes.dm b/code/modules/reagents/reagent_containers/syringes.dm index e2626f13977..e65c3fac38e 100644 --- a/code/modules/reagents/reagent_containers/syringes.dm +++ b/code/modules/reagents/reagent_containers/syringes.dm @@ -66,7 +66,7 @@ if(ismob(target)) //Blood! if(ishuman(target)) var/mob/living/carbon/human/H = target - if(NOBLOOD in H.dna.species.specflags && !H.dna.species.exotic_blood) + if((NOBLOOD in H.dna.species.specflags) && !H.dna.species.exotic_blood) user << "You are unable to locate any blood!" return if(reagents.has_reagent("blood")) diff --git a/code/modules/research/designs/mecha_designs.dm b/code/modules/research/designs/mecha_designs.dm index 5ddcd742dc8..a2028a40d54 100644 --- a/code/modules/research/designs/mecha_designs.dm +++ b/code/modules/research/designs/mecha_designs.dm @@ -3,7 +3,7 @@ /////////////////////////////////// /datum/design/ripley_main - name = "Exosuit Module (APLU \"Ripley\" Central Control module)" + name = "APLU \"Ripley\" Central Control module" desc = "Allows for the construction of a \"Ripley\" Central Control module." id = "ripley_main" req_tech = list("programming" = 3) @@ -13,7 +13,7 @@ category = list("Exosuit Modules") /datum/design/ripley_peri - name = "Exosuit Module (APLU \"Ripley\" Peripherals Control module)" + name = "APLU \"Ripley\" Peripherals Control module" desc = "Allows for the construction of a \"Ripley\" Peripheral Control module." id = "ripley_peri" req_tech = list("programming" = 3) @@ -23,7 +23,7 @@ category = list("Exosuit Modules") /datum/design/odysseus_main - name = "Exosuit Module (\"Odysseus\" Central Control module)" + name = "\"Odysseus\" Central Control module" desc = "Allows for the construction of a \"Odysseus\" Central Control module." id = "odysseus_main" req_tech = list("programming" = 3,"biotech" = 2) @@ -33,7 +33,7 @@ category = list("Exosuit Modules") /datum/design/odysseus_peri - name = "Exosuit Module (\"Odysseus\" Peripherals Control module)" + name = "\"Odysseus\" Peripherals Control module" desc = "Allows for the construction of a \"Odysseus\" Peripheral Control module." id = "odysseus_peri" req_tech = list("programming" = 3,"biotech" = 2) @@ -43,7 +43,7 @@ category = list("Exosuit Modules") /datum/design/gygax_main - name = "Exosuit Module (\"Gygax\" Central Control module)" + name = "\"Gygax\" Central Control module" desc = "Allows for the construction of a \"Gygax\" Central Control module." id = "gygax_main" req_tech = list("programming" = 4) @@ -53,7 +53,7 @@ category = list("Exosuit Modules") /datum/design/gygax_peri - name = "Exosuit Module (\"Gygax\" Peripherals Control module)" + name = "\"Gygax\" Peripherals Control module" desc = "Allows for the construction of a \"Gygax\" Peripheral Control module." id = "gygax_peri" req_tech = list("programming" = 4) @@ -63,7 +63,7 @@ category = list("Exosuit Modules") /datum/design/gygax_targ - name = "Exosuit Module (\"Gygax\" Weapons & Targeting Control module)" + name = "\"Gygax\" Weapons & Targeting Control module" desc = "Allows for the construction of a \"Gygax\" Weapons & Targeting Control module." id = "gygax_targ" req_tech = list("programming" = 4, "combat" = 2) @@ -73,7 +73,7 @@ category = list("Exosuit Modules") /datum/design/durand_main - name = "Exosuit Module (\"Durand\" Central Control module)" + name = "\"Durand\" Central Control module" desc = "Allows for the construction of a \"Durand\" Central Control module." id = "durand_main" req_tech = list("programming" = 4) @@ -83,7 +83,7 @@ category = list("Exosuit Modules") /datum/design/durand_peri - name = "Exosuit Module (\"Durand\" Peripherals Control module)" + name = "\"Durand\" Peripherals Control module" desc = "Allows for the construction of a \"Durand\" Peripheral Control module." id = "durand_peri" req_tech = list("programming" = 4) @@ -93,7 +93,7 @@ category = list("Exosuit Modules") /datum/design/durand_targ - name = "Exosuit Module (\"Durand\" Weapons & Targeting Control module)" + name = "\"Durand\" Weapons & Targeting Control module" desc = "Allows for the construction of a \"Durand\" Weapons & Targeting Control module." id = "durand_targ" req_tech = list("programming" = 4, "combat" = 2) @@ -103,7 +103,7 @@ category = list("Exosuit Modules") /datum/design/honker_main - name = "Exosuit Module (\"H.O.N.K\" Central Control module)" + name = "\"H.O.N.K\" Central Control module" desc = "Allows for the construction of a \"H.O.N.K\" Central Control module." id = "honker_main" req_tech = list("programming" = 3) @@ -113,7 +113,7 @@ category = list("Exosuit Modules") /datum/design/honker_peri - name = "Exosuit Module (\"H.O.N.K\" Peripherals Control module)" + name = "\"H.O.N.K\" Peripherals Control module" desc = "Allows for the construction of a \"H.O.N.K\" Peripheral Control module." id = "honker_peri" req_tech = list("programming" = 3) @@ -123,7 +123,7 @@ category = list("Exosuit Modules") /datum/design/honker_targ - name = "Exosuit Module (\"H.O.N.K\" Weapons & Targeting Control module)" + name = "\"H.O.N.K\" Weapons & Targeting Control module" desc = "Allows for the construction of a \"H.O.N.K\" Weapons & Targeting Control module." id = "honker_targ" req_tech = list("programming" = 3) @@ -133,7 +133,7 @@ category = list("Exosuit Modules") /datum/design/phazon_main - name = "Exosuit Module (\"Phazon\" Central Control module)" + name = "\"Phazon\" Central Control module" desc = "Allows for the construction of a \"Phazon\" Central Control module." id = "phazon_main" req_tech = list("programming" = 5, "materials" = 7, "powerstorage" = 6) @@ -143,7 +143,7 @@ category = list("Exosuit Modules") /datum/design/phazon_peri - name = "Exosuit Module (\"Phazon\" Peripherals Control module)" + name = "\"Phazon\" Peripherals Control module" desc = "Allows for the construction of a \"Phazon\" Peripheral Control module." id = "phazon_peri" req_tech = list("programming" = 5, "bluespace" = 6) @@ -153,7 +153,7 @@ category = list("Exosuit Modules") /datum/design/phazon_targ - name = "Exosuit Module (\"Phazon\" Weapons & Targeting Control module)" + name = "\"Phazon\" Weapons & Targeting Control module" desc = "Allows for the construction of a \"Phazon\" Weapons & Targeting Control module." id = "phazon_targ" req_tech = list("programming" = 5, "magnets" = 6) diff --git a/code/modules/research/designs/medical_designs.dm b/code/modules/research/designs/medical_designs.dm index 9ba09d72318..d7e9ef3882f 100644 --- a/code/modules/research/designs/medical_designs.dm +++ b/code/modules/research/designs/medical_designs.dm @@ -118,7 +118,7 @@ build_type = PROTOLATHE | MECHFAB construction_time = 40 materials = list(MAT_METAL = 200, MAT_GLASS = 400) - build_path = /obj/item/organ/internal/cyberimp/eyes/shield + build_path = /obj/item/organ/cyberimp/eyes/shield category = list("Misc", "Medical Designs") /datum/design/cyberimp_breather @@ -129,7 +129,7 @@ build_type = PROTOLATHE | MECHFAB construction_time = 35 materials = list(MAT_METAL = 200, MAT_GLASS = 250) - build_path = /obj/item/organ/internal/cyberimp/mouth/breathing_tube + build_path = /obj/item/organ/cyberimp/mouth/breathing_tube category = list("Misc", "Medical Designs") /datum/design/cyberimp_medical_hud @@ -140,7 +140,7 @@ build_type = PROTOLATHE | MECHFAB construction_time = 50 materials = list(MAT_METAL = 200, MAT_GLASS = 200, MAT_SILVER = 500, MAT_GOLD = 500) - build_path = /obj/item/organ/internal/cyberimp/eyes/hud/medical + build_path = /obj/item/organ/cyberimp/eyes/hud/medical category = list("Misc", "Medical Designs") /datum/design/cyberimp_security_hud @@ -151,7 +151,7 @@ build_type = PROTOLATHE | MECHFAB construction_time = 50 materials = list(MAT_METAL = 200, MAT_GLASS = 200, MAT_SILVER = 750, MAT_GOLD = 750) - build_path = /obj/item/organ/internal/cyberimp/eyes/hud/security + build_path = /obj/item/organ/cyberimp/eyes/hud/security category = list("Misc", "Medical Designs") /datum/design/cyberimp_xray @@ -162,7 +162,7 @@ build_type = PROTOLATHE | MECHFAB construction_time = 60 materials = list(MAT_METAL = 200, MAT_GLASS = 200, MAT_SILVER = 600, MAT_GOLD = 600, MAT_PLASMA = 1000, MAT_URANIUM = 1000, MAT_DIAMOND = 2000) - build_path = /obj/item/organ/internal/cyberimp/eyes/xray + build_path = /obj/item/organ/cyberimp/eyes/xray category = list("Misc", "Medical Designs") /datum/design/cyberimp_thermals @@ -173,7 +173,7 @@ build_type = PROTOLATHE | MECHFAB construction_time = 60 materials = list(MAT_METAL = 200, MAT_GLASS = 200, MAT_SILVER = 600, MAT_GOLD = 600, MAT_PLASMA = 1000, MAT_DIAMOND = 2000) - build_path = /obj/item/organ/internal/cyberimp/eyes/thermals + build_path = /obj/item/organ/cyberimp/eyes/thermals category = list("Misc", "Medical Designs") /datum/design/cyberimp_antidrop @@ -184,7 +184,7 @@ build_type = PROTOLATHE | MECHFAB construction_time = 60 materials = list(MAT_METAL = 200, MAT_GLASS = 200, MAT_SILVER = 400, MAT_GOLD = 400) - build_path = /obj/item/organ/internal/cyberimp/brain/anti_drop + build_path = /obj/item/organ/cyberimp/brain/anti_drop category = list("Misc", "Medical Designs") /datum/design/cyberimp_antistun @@ -195,7 +195,7 @@ build_type = PROTOLATHE | MECHFAB construction_time = 60 materials = list(MAT_METAL = 200, MAT_GLASS = 200, MAT_SILVER = 500, MAT_GOLD = 1000) - build_path = /obj/item/organ/internal/cyberimp/brain/anti_stun + build_path = /obj/item/organ/cyberimp/brain/anti_stun category = list("Misc", "Medical Designs") /datum/design/cyberimp_nutriment @@ -206,7 +206,7 @@ build_type = PROTOLATHE | MECHFAB construction_time = 40 materials = list(MAT_METAL = 200, MAT_GLASS = 200, MAT_GOLD = 500, MAT_URANIUM = 500) - build_path = /obj/item/organ/internal/cyberimp/chest/nutriment + build_path = /obj/item/organ/cyberimp/chest/nutriment category = list("Misc", "Medical Designs") /datum/design/cyberimp_nutriment_plus @@ -217,7 +217,7 @@ build_type = PROTOLATHE | MECHFAB construction_time = 50 materials = list(MAT_METAL = 200, MAT_GLASS = 200, MAT_GOLD = 500, MAT_URANIUM = 750) - build_path = /obj/item/organ/internal/cyberimp/chest/nutriment/plus + build_path = /obj/item/organ/cyberimp/chest/nutriment/plus category = list("Misc", "Medical Designs") /datum/design/cyberimp_reviver @@ -228,7 +228,7 @@ build_type = PROTOLATHE | MECHFAB construction_time = 60 materials = list(MAT_METAL = 200, MAT_GLASS = 200, MAT_GOLD = 500, MAT_URANIUM = 1000, MAT_DIAMOND = 2000) - build_path = /obj/item/organ/internal/cyberimp/chest/reviver + build_path = /obj/item/organ/cyberimp/chest/reviver category = list("Misc", "Medical Designs") /datum/design/cyberimp_thrusters @@ -239,7 +239,7 @@ build_type = PROTOLATHE | MECHFAB construction_time = 80 materials = list(MAT_METAL = 4000, MAT_GLASS = 2000, MAT_SILVER = 1000, MAT_DIAMOND = 1000) - build_path = /obj/item/organ/internal/cyberimp/chest/thrusters + build_path = /obj/item/organ/cyberimp/chest/thrusters category = list("Misc", "Medical Designs") diff --git a/code/modules/ruins/lavaland_ruin_code.dm b/code/modules/ruins/lavaland_ruin_code.dm index 576cf63d6ba..935d38df73c 100644 --- a/code/modules/ruins/lavaland_ruin_code.dm +++ b/code/modules/ruins/lavaland_ruin_code.dm @@ -208,6 +208,8 @@ meat_counter += 20 else meat_counter ++ + for(var/obj/item/W in H) + H.unEquip(W) H.gib() /mob/living/simple_animal/hostile/spawner/ash_walker/spawn_mob() diff --git a/code/modules/shuttle/supply.dm b/code/modules/shuttle/supply.dm index 4a440f22c75..da204476df6 100644 --- a/code/modules/shuttle/supply.dm +++ b/code/modules/shuttle/supply.dm @@ -1,7 +1,7 @@ /obj/docking_port/mobile/supply name = "supply shuttle" id = "supply" - callTime = 1200 + callTime = 600 dir = 8 travelDir = 90 diff --git a/code/modules/spells/spell_types/lichdom.dm b/code/modules/spells/spell_types/lichdom.dm index 5c2b5ebe555..c7efcd76349 100644 --- a/code/modules/spells/spell_types/lichdom.dm +++ b/code/modules/spells/spell_types/lichdom.dm @@ -87,7 +87,7 @@ var/mob/living/carbon/C = old_body for(var/obj/item/W in C) C.unEquip(W) - for(var/obj/item/organ/internal/I in C.internal_organs) + for(var/obj/item/organ/I in C.internal_organs) I.Remove(C) I.forceMove(body_turf) var/wheres_wizdo = dir2text(get_dir(body_turf, item_turf)) diff --git a/code/modules/spells/spell_types/summonitem.dm b/code/modules/spells/spell_types/summonitem.dm index 985a6448297..e4b02f8b08b 100644 --- a/code/modules/spells/spell_types/summonitem.dm +++ b/code/modules/spells/spell_types/summonitem.dm @@ -55,7 +55,7 @@ if(!item_to_retrive.loc) if(isorgan(item_to_retrive)) // Organs are usually stored in nullspace - var/obj/item/organ/internal/organ = item_to_retrive + var/obj/item/organ/organ = item_to_retrive if(organ.owner) // If this code ever runs I will be happy add_logs(L, organ.owner, "magically removed [organ.name] from", addition="INTENT: [uppertext(L.a_intent)]") diff --git a/code/modules/stock_market/events.dm b/code/modules/stock_market/events.dm index 61b1ba86e34..1e34fddf03d 100644 --- a/code/modules/stock_market/events.dm +++ b/code/modules/stock_market/events.dm @@ -129,7 +129,7 @@ A.subtitle = "Investors panic, bailout pending" if (prob(15)) A.opinion = rand(-1, 1) - var/article = "Another one might bite the dust: [company.current_trend > 0 ? "despite their positive trend" : "in line with their failing model"], [company.name] is files for bankruptcy citing [pick(bankrupt_reason)]. The president of %country% has been asked to bail the company out, " + var/article = "Another one might bite the dust: [company.current_trend > 0 ? "despite their positive trend" : "in line with their failing model"], [company.name] files for bankruptcy citing [pick(bankrupt_reason)]. The president of %country% has been asked to bail the company out, " if (!A.opinion) article += "but no answer has been given by the government to date. Our tip to stay safe is: %sell%" else if (A.opinion > 0) diff --git a/code/modules/surgery/amputation.dm b/code/modules/surgery/amputation.dm new file mode 100644 index 00000000000..1e13586eea8 --- /dev/null +++ b/code/modules/surgery/amputation.dm @@ -0,0 +1,22 @@ + +/datum/surgery/amputation + name = "amputation" + steps = list(/datum/surgery_step/incise, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/retract_skin, /datum/surgery_step/saw, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/sever_limb) + species = list(/mob/living/carbon/human) + possible_locs = list("r_arm", "l_arm", "l_leg", "r_leg", "head") + +/datum/surgery_step/sever_limb + name = "sever limb" + implements = list(/obj/item/weapon/scalpel = 100, /obj/item/weapon/circular_saw = 100, /obj/item/weapon/melee/energy/sword/cyborg/saw = 100, /obj/item/weapon/melee/arm_blade = 80, /obj/item/weapon/twohanded/required/chainsaw = 80, /obj/item/weapon/mounted_chainsaw = 80, /obj/item/weapon/twohanded/fireaxe = 50, /obj/item/weapon/hatchet = 40, /obj/item/weapon/kitchen/knife/butcher = 25) + time = 64 + +/datum/surgery_step/sever_limb/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) + user.visible_message("[user] begins to sever [target]'s [parse_zone(target_zone)]!", "You begin to sever [target]'s [parse_zone(target_zone)]...") + +/datum/surgery_step/sever_limb/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) + var/mob/living/carbon/human/L = target + user.visible_message("[user] severs [L]'s [parse_zone(target_zone)]!", "You sever [L]'s [parse_zone(target_zone)].") + var/obj/item/bodypart/BP = L.get_bodypart(target_zone) + if(BP) + BP.drop_limb() + return 1 \ No newline at end of file diff --git a/code/modules/surgery/bodyparts/bodyparts.dm b/code/modules/surgery/bodyparts/bodyparts.dm new file mode 100644 index 00000000000..0313dfa5325 --- /dev/null +++ b/code/modules/surgery/bodyparts/bodyparts.dm @@ -0,0 +1,336 @@ + +/obj/item/bodypart + name = "limb" + desc = "why is it detached..." + force = 3 + throwforce = 3 + var/mob/living/carbon/human/owner = null + var/status = ORGAN_ORGANIC + var/body_zone //"chest", "l_arm", etc , used for def_zone + var/body_part = null //bitflag used to check which clothes cover this bodypart + var/brutestate = 0 + var/burnstate = 0 + var/brute_dam = 0 + var/burn_dam = 0 + var/max_damage = 0 + var/list/embedded_objects = list() + + //Coloring and proper item icon update + var/skin_tone = "" + var/body_gender = "" + var/species_id = "" + var/should_draw_gender = FALSE + var/should_draw_greyscale = FALSE + var/species_color = "" + var/mutation_color = "" + var/no_update = 0 + + var/px_x = 0 + var/px_y = 0 + + var/state_flags + +/obj/item/bodypart/examine(mob/user) + ..() + if(brute_dam > 0) + user << "This limb has [brute_dam > 30 ? "severe" : "minor"] bruising." + if(burn_dam > 0) + user << "This limb has [burn_dam > 30 ? "severe" : "minor"] burns." + + +/obj/item/bodypart/Destroy() + if(owner) + owner.bodyparts -= src + owner = null + return ..() + +/obj/item/bodypart/attackby(obj/item/W, mob/user, params) + if(W.sharpness) + add_fingerprint(user) + if(!contents.len) + user << "There is nothing left inside [src]!" + return + playsound(loc, 'sound/weapons/slice.ogg', 50, 1, -1) + user.visible_message("[user] begins to cut through the bone in [src].",\ + "You begin to cut through the bone in [src]...") + if(do_after(user, 54, target = src)) + drop_organs(user) + else + return ..() + +/obj/item/bodypart/throw_impact(atom/hit_atom) + ..() + playsound(get_turf(src), 'sound/misc/splort.ogg', 50, 1, -1) + +/obj/item/bodypart/proc/drop_organs(mob/user) + var/turf/T = get_turf(src) + playsound(T, 'sound/misc/splort.ogg', 50, 1, -1) + for(var/obj/item/I in src) + I.loc = T + +//Applies brute and burn damage to the organ. Returns 1 if the damage-icon states changed at all. +//Damage will not exceed max_damage using this proc +//Cannot apply negative damage +/obj/item/bodypart/proc/take_damage(brute, burn) + if(owner && (owner.status_flags & GODMODE)) + return 0 //godmode + brute = max(brute,0) + burn = max(burn,0) + + + if(status == ORGAN_ROBOTIC) //This makes robolimbs not damageable by chems and makes it stronger + brute = max(0, brute - 5) + burn = max(0, burn - 4) + + var/can_inflict = max_damage - (brute_dam + burn_dam) + if(!can_inflict) + return 0 + + if((brute + burn) < can_inflict) + brute_dam += brute + burn_dam += burn + else + if(brute > 0) + if(burn > 0) + brute = round( (brute/(brute+burn)) * can_inflict, 1 ) + burn = can_inflict - brute //gets whatever damage is left over + brute_dam += brute + burn_dam += burn + else + brute_dam += can_inflict + else + if(burn > 0) + burn_dam += can_inflict + else + return 0 + if(owner) + owner.updatehealth() + return update_bodypart_damage_state() + + +//Heals brute and burn damage for the organ. Returns 1 if the damage-icon states changed at all. +//Damage cannot go below zero. +//Cannot remove negative damage (i.e. apply damage) +/obj/item/bodypart/proc/heal_damage(brute, burn, robotic) + + if(robotic && status != ORGAN_ROBOTIC) // This makes organic limbs not heal when the proc is in Robotic mode. + brute = max(0, brute - 3) + burn = max(0, burn - 3) + + if(!robotic && status == ORGAN_ROBOTIC) // This makes robolimbs not healable by chems. + brute = max(0, brute - 3) + burn = max(0, burn - 3) + + brute_dam = max(brute_dam - brute, 0) + burn_dam = max(burn_dam - burn, 0) + if(owner) + owner.updatehealth() + return update_bodypart_damage_state() + + +//Returns total damage...kinda pointless really +/obj/item/bodypart/proc/get_damage() + return brute_dam + burn_dam + + +//Updates an organ's brute/burn states for use by update_damage_overlays() +//Returns 1 if we need to update overlays. 0 otherwise. +/obj/item/bodypart/proc/update_bodypart_damage_state() + if(status == ORGAN_ORGANIC) //Robotic limbs show no damage - RR + var/tbrute = round( (brute_dam/max_damage)*3, 1 ) + var/tburn = round( (burn_dam/max_damage)*3, 1 ) + if((tbrute != brutestate) || (tburn != burnstate)) + brutestate = tbrute + burnstate = tburn + return 1 + return 0 + + + +//Change organ status +/obj/item/bodypart/proc/change_bodypart_status(new_limb_status, heal_limb) + status = new_limb_status + if(heal_limb) + burn_dam = 0 + brute_dam = 0 + brutestate = 0 + burnstate = 0 + if(owner) + owner.updatehealth() + owner.update_body() //if our head becomes robotic, we remove the lizard horns and human hair. + owner.update_hair() + owner.update_damage_overlays() + +//we inform the bodypart of the changes that happened to the owner, or give it the informations from a source mob. +/obj/item/bodypart/proc/update_limb(dropping_limb, mob/living/carbon/human/source) + var/mob/living/carbon/human/H + if(source) + H = source + else + H = owner + if(!istype(H)) + return + + should_draw_greyscale = FALSE + + var/datum/species/S = H.dna.species + species_id = S.id + + if(S.use_skintones) + skin_tone = H.skin_tone + should_draw_greyscale = TRUE + else + skin_tone = "" + + body_gender = H.gender + should_draw_gender = S.sexes + + if(MUTCOLORS in S.specflags) + species_color = H.dna.features["mcolor"] + should_draw_greyscale = TRUE + else + species_color = "" + + if(H.disabilities & HUSK) + species_id = "husk" + should_draw_gender = FALSE + should_draw_greyscale = FALSE + + if(!dropping_limb && H.dna.check_mutation(HULK)) + mutation_color = "00aa00" + else + mutation_color = "" + + if(dropping_limb) + no_update = 1 //when attached, the limb won't be affected by the appearance changes of its mob owner. + +//to update the bodypart's icon when not attached to a mob +/obj/item/bodypart/proc/update_icon_dropped() + overlays.Cut() + var/image/I = get_limb_icon(1) + if(I) + I.pixel_x = px_x + I.pixel_y = px_y + overlays += I + +//Gives you a proper icon appearance for the dismembered limb +/obj/item/bodypart/proc/get_limb_icon(dropped) + var/image/I + + var/icon_gender = (body_gender == FEMALE) ? "f" : "m" //gender of the icon, if applicable + + if((body_zone != "head" && body_zone != "chest")) + should_draw_gender = FALSE + + var/image_dir + if(dropped) + image_dir = SOUTH + if(status == ORGAN_ORGANIC) + if(should_draw_greyscale) + if(should_draw_gender) + I = image("icon"='icons/mob/human_parts_greyscale.dmi', "icon_state"="[species_id]_[body_zone]_[icon_gender]_s", "layer"=-BODYPARTS_LAYER, "dir"=image_dir) + else + I = image("icon"='icons/mob/human_parts_greyscale.dmi', "icon_state"="[species_id]_[body_zone]_s", "layer"=-BODYPARTS_LAYER, "dir"=image_dir) + else + if(should_draw_gender) + I = image("icon"='icons/mob/human_parts.dmi', "icon_state"="[species_id]_[body_zone]_[icon_gender]_s", "layer"=-BODYPARTS_LAYER, "dir"=image_dir) + else + I = image("icon"='icons/mob/human_parts.dmi', "icon_state"="[species_id]_[body_zone]_s", "layer"=-BODYPARTS_LAYER, "dir"=image_dir) + else + if(should_draw_gender) + I = image("icon"='icons/mob/augments.dmi', "icon_state"="[body_zone]_[icon_gender]_s", "layer"=-BODYPARTS_LAYER, "dir"=image_dir) + else + I = image("icon"='icons/mob/augments.dmi', "icon_state"="[body_zone]_s", "layer"=-BODYPARTS_LAYER, "dir"=image_dir) + return I + + + if(!should_draw_greyscale) + return I + + //Greyscale Colouring + var/draw_color + + if(skin_tone) //Limb has skin color variable defined, use it + draw_color = skintone2hex(skin_tone) + if(species_color) + draw_color = species_color + if(mutation_color) + draw_color = mutation_color + + if(draw_color) + I.color = "#[draw_color]" + //End Greyscale Colouring + + return I + + + +/obj/item/bodypart/chest + name = "chest" + desc = "It's impolite to stare at a person's chest." + icon_state = "chest" + max_damage = 200 + body_zone = "chest" + body_part = CHEST + px_x = 0 + px_y = 0 + var/obj/item/cavity_item + +/obj/item/bodypart/chest/Destroy() + if(cavity_item) + qdel(cavity_item) + return ..() + +/obj/item/bodypart/l_arm + name = "left arm" + icon_state = "l_arm" + max_damage = 75 + body_zone ="l_arm" + body_part = ARM_LEFT + px_x = -6 + px_y = 0 + +/obj/item/bodypart/r_arm + name = "right arm" + icon_state = "r_arm" + max_damage = 75 + body_zone = "r_arm" + body_part = ARM_RIGHT + px_x = 6 + px_y = 0 + +/obj/item/bodypart/l_leg + name = "left leg" + icon_state = "l_leg" + max_damage = 75 + body_zone = "l_leg" + body_part = LEG_LEFT + px_x = -2 + px_y = 12 + +/obj/item/bodypart/r_leg + name = "right leg" + icon_state = "r_leg" + max_damage = 75 + body_zone = "r_leg" + body_part = LEG_RIGHT + px_x = 2 + px_y = 12 + + +///////////////////////////////////////////////////////////////////////// + +/obj/item/severedtail + name = "tail" + desc = "A severed tail." + icon = 'icons/obj/surgery.dmi' + icon_state = "severedtail" + color = "#161" + var/markings = "Smooth" + + + + + + + diff --git a/code/modules/surgery/bodyparts/dismemberment.dm b/code/modules/surgery/bodyparts/dismemberment.dm new file mode 100644 index 00000000000..5f037989886 --- /dev/null +++ b/code/modules/surgery/bodyparts/dismemberment.dm @@ -0,0 +1,311 @@ + + +//Dismember a limb +/obj/item/bodypart/proc/dismember() + var/mob/living/carbon/human/H = owner + if(!istype(H) || !H.dna.species.has_dismemberment) // species don't allow dismemberment + return 0 + + var/obj/item/bodypart/affecting = H.get_bodypart("chest") + affecting.take_damage(Clamp(brute_dam/2, 15, 50), Clamp(burn_dam/2, 0, 50)) //Damage the chest based on limb's existing damage + H.visible_message("[H]'s [src.name] has been violently dismembered!") + H.emote("scream") + drop_limb() + + var/direction = pick(cardinal) + var/t_range = rand(2,max(throw_range/2, 2)) + var/turf/target_turf = get_turf(src) + for(var/i in 1 to t_range-1) + var/turf/new_turf = get_step(target_turf, direction) + target_turf = new_turf + if(new_turf.density) + break + throw_at_fast(target_turf, throw_range, throw_speed) + return 1 + + +/obj/item/bodypart/chest/dismember() + var/mob/living/carbon/human/H = owner + if(!istype(H) || !H.dna.species.has_dismemberment) //human's species don't allow dismemberment + return 0 + + var/organ_spilled = 0 + var/turf/T = get_turf(H) + T.add_blood(H) + playsound(get_turf(owner), 'sound/misc/splort.ogg', 80, 1) + for(var/X in owner.internal_organs) + var/obj/item/organ/O = X + if(O.zone != "chest") + continue + O.Remove(owner) + O.loc = T + organ_spilled = 1 + if(cavity_item) + cavity_item.loc = T + cavity_item = null + organ_spilled = 1 + + if(organ_spilled) + owner.visible_message("[owner]'s internal organs spill out onto the floor!") + return 1 + + + +//limb removal. The "special" argument is used for swapping a limb with a new one without the effects of losing a limb kicking in. +/obj/item/bodypart/proc/drop_limb(special) + if(!ishuman(owner)) + return + var/turf/T = get_turf(owner) + var/mob/living/carbon/human/H = owner + if(!no_update) + update_limb(1) + H.bodyparts -= src + owner = null + + for(var/X in H.surgeries) //if we had an ongoing surgery on that limb, we stop it. + var/datum/surgery/S = X + if(S.organ == src) + H.surgeries -= S + qdel(S) + break + + for(var/obj/item/I in embedded_objects) + embedded_objects -= I + I.loc = src + if(!H.has_embedded_objects()) + H.clear_alert("embeddedobject") + + if(!special) + for(var/X in H.dna.mutations) //some mutations require having specific limbs to be kept. + var/datum/mutation/human/MT = X + if(MT.limb_req && MT.limb_req == body_zone) + MT.force_lose(H) + + for(var/X in H.internal_organs) //internal organs inside the dismembered limb are dropped. + var/obj/item/organ/O = X + var/org_zone = check_zone(O.zone) + if(org_zone != body_zone) + continue + O.transfer_to_limb(src, H) + + update_icon_dropped() + src.loc = T + H.update_health_hud() //update the healthdoll + H.update_body() + H.update_hair() + H.update_canmove() + + +//when a limb is dropped, the internal organs are removed from the mob and put into the limb +/obj/item/organ/proc/transfer_to_limb(obj/item/bodypart/LB, mob/living/carbon/human/H) + Remove(H) + loc = LB + +/obj/item/organ/brain/transfer_to_limb(obj/item/bodypart/head/LB, mob/living/carbon/human/H) + if(H.mind && H.mind.changeling) + LB.brain = new //changeling doesn't lose its real brain organ, we drop a decoy. + LB.brain.loc = LB + else //if not a changeling, we put the brain organ inside the dropped head + Remove(H) //and put the player in control of the brainmob + loc = LB + LB.brain = src + LB.brainmob = brainmob + brainmob = null + LB.brainmob.loc = LB + LB.brainmob.container = LB + LB.brainmob.stat = DEAD + + +/obj/item/bodypart/chest/drop_limb(special) + return + +/obj/item/bodypart/r_arm/drop_limb(special) + var/mob/living/carbon/human/H = owner + ..() + if(istype(H) && !special) + if(H.handcuffed) + H.handcuffed.loc = H.loc + H.handcuffed.dropped(H) + H.handcuffed = null + H.update_handcuffed() + if(H.hud_used) + var/obj/screen/inventory/R = H.hud_used.inv_slots[slot_r_hand] + if(R) + R.update_icon() + if(H.r_hand) + H.unEquip(H.r_hand, 1) + if(H.gloves) + H.unEquip(H.gloves, 1) + H.update_inv_gloves() //to remove the bloody hands overlay + + +/obj/item/bodypart/l_arm/drop_limb(special) + var/mob/living/carbon/human/H = owner + ..() + if(istype(H) && !special) + if(H.handcuffed) + H.handcuffed.loc = H.loc + H.handcuffed.dropped(H) + H.handcuffed = null + H.update_handcuffed() + if(H.hud_used) + var/obj/screen/inventory/L = H.hud_used.inv_slots[slot_l_hand] + if(L) + L.update_icon() + if(H.l_hand) + H.unEquip(H.l_hand, 1) + if(H.gloves) + H.unEquip(H.gloves, 1) + H.update_inv_gloves() //to remove the bloody hands overlay + + +/obj/item/bodypart/r_leg/drop_limb(special) + if(owner && !special) + owner.Weaken(2) + if(owner.legcuffed) + owner.legcuffed.loc = owner.loc + owner.legcuffed.dropped(owner) + owner.legcuffed = null + owner.update_inv_legcuffed() + if(ishuman(owner)) + var/mob/living/carbon/human/H = owner + if(H.shoes) + H.unEquip(H.shoes, 1) + ..() + +/obj/item/bodypart/l_leg/drop_limb(special) //copypasta + if(owner && !special) + owner.Weaken(2) + if(owner.legcuffed) + owner.legcuffed.loc = owner.loc + owner.legcuffed.dropped(owner) + owner.legcuffed = null + owner.update_inv_legcuffed() + if(ishuman(owner)) + var/mob/living/carbon/human/H = owner + if(H.shoes) + H.unEquip(H.shoes, 1) + ..() + +/obj/item/bodypart/head/drop_limb(special) + var/mob/living/carbon/human/H = owner + if(istype(H)) + if(!special) + //Drop all worn head items + for(var/X in list(H.glasses, H.ears, H.wear_mask, H.head)) + var/obj/item/I = X + H.unEquip(I, 1) + name = "[H]'s head" + ..() + + + + + + +//Attach a limb to a human and drop any existing limb of that type. +/obj/item/bodypart/proc/replace_limb(mob/living/carbon/human/H, special) + if(!istype(H)) + return + var/obj/item/bodypart/O = locate(src.type) in H.bodyparts + + if(O) + O.drop_limb(1) + attach_limb(H, special) + +/obj/item/bodypart/head/replace_limb(mob/living/carbon/human/H, special) + if(!istype(H)) + return + var/obj/item/bodypart/head/O = locate(src.type) in H.bodyparts + if(O) + if(!special) + return + else + O.drop_limb(1) + attach_limb(H, special) + +/obj/item/bodypart/proc/attach_limb(mob/living/carbon/human/H, special) + loc = null + owner = H + H.bodyparts += src + + if(special) //non conventional limb attachment + for(var/X in H.surgeries) //if we had an ongoing surgery to attach a new limb, we stop it. + var/datum/surgery/S = X + var/surgery_zone = check_zone(S.location) + if(surgery_zone == body_zone) + H.surgeries -= S + qdel(S) + break + + update_bodypart_damage_state() + H.updatehealth() + H.update_body() + H.update_hair() + H.update_damage_overlays() + H.update_canmove() + + +/obj/item/bodypart/r_arm/attach_limb(mob/living/carbon/human/H, special) + ..() + if(H.hud_used) + var/obj/screen/inventory/R = H.hud_used.inv_slots[slot_r_hand] + if(R) + R.update_icon() + +/obj/item/bodypart/l_arm/attach_limb(mob/living/carbon/human/H, special) + ..() + if(H.hud_used) + var/obj/screen/inventory/L = H.hud_used.inv_slots[slot_l_hand] + if(L) + L.update_icon() + +/obj/item/bodypart/head/attach_limb(mob/living/carbon/human/H, special) + //Transfer some head appearance vars over + if(brain) + brainmob.container = null //Reset brainmob head var. + brainmob.loc = brain //Throw mob into brain. + brain.brainmob = brainmob //Set the brain to use the brainmob + brainmob = null //Set head brainmob var to null + brain.Insert(H) //Now insert the brain proper + brain = null //No more brain in the head + + H.hair_color = hair_color + H.hair_style = hair_style + H.facial_hair_color = facial_hair_color + H.facial_hair_style = facial_hair_style + H.eye_color = eye_color + H.lip_style = lip_style + H.lip_color = lip_color + if(real_name) + H.real_name = real_name + real_name = "" + name = initial(name) + ..() + + +//Regenerates all limbs. Returns amount of limbs regenerated +/mob/living/proc/regenerate_limbs(noheal) + return 0 + +/mob/living/carbon/human/regenerate_limbs(noheal) + var/list/limb_list = list("head", "chest", "r_arm", "l_arm", "r_leg", "l_leg") + for(var/Z in limb_list) + . += regenerate_limb(Z, noheal) + +/mob/living/proc/regenerate_limb(limb_zone, noheal) + return + +/mob/living/carbon/human/regenerate_limb(limb_zone, noheal) + var/obj/item/bodypart/L + if(get_bodypart(limb_zone)) + return 0 + L = newBodyPart(limb_zone, 0, 0, src) + if(L) + if(!noheal) + L.brute_dam = 0 + L.burn_dam = 0 + L.burn_state = 0 + + L.attach_limb(src, 1) + return 1 diff --git a/code/modules/surgery/bodyparts/head.dm b/code/modules/surgery/bodyparts/head.dm new file mode 100644 index 00000000000..1feb60587e4 --- /dev/null +++ b/code/modules/surgery/bodyparts/head.dm @@ -0,0 +1,163 @@ + + +/obj/item/bodypart/head + name = "head" + desc = "Didn't make sense not to live for fun, your brain gets smart but your head gets dumb." + icon_state = "head" + max_damage = 200 + body_zone = "head" + body_part = HEAD + layer = 4.1 //so it isn't hidden behind some objects when on the floor + w_class = 4 //Quite a hefty load + slowdown = 1 //Balancing measure + throw_range = 2 //No head bowling + px_x = 0 + px_y = -8 + + var/mob/living/carbon/brain/brainmob = null //The current occupant. + var/obj/item/organ/brain/brain = null //The brain organ + + //Limb appearance info: + var/real_name = "" //Replacement name + //Hair colour and style + var/hair_color = "000" + var/hair_style = "Bald" + var/hair_alpha = 255 + //Facial hair colour and style + var/facial_hair_color = "000" + var/facial_hair_style = "Shaved" + //Eye Colouring + var/eyes = "eyes" + var/eye_color = "" + var/lip_style = null + var/lip_color = "white" + +/obj/item/bodypart/head/drop_organs(mob/user) + var/turf/T = get_turf(src) + playsound(T, 'sound/misc/splort.ogg', 50, 1, -1) + for(var/obj/item/I in src) + if(I == brain) + user.visible_message("[user] saws [src] open and pulls out a brain!", "You saw [src] open and pull out a brain.") + if(brainmob) + brainmob.container = null + brainmob.loc = brain + brain.brainmob = brainmob + brainmob = null + brain.loc = T + brain = null + update_icon_dropped() + else + I.loc = T + +/obj/item/bodypart/head/update_limb(dropping_limb, mob/living/carbon/human/source) + var/mob/living/carbon/human/H + if(source) + H = source + else + H = owner + if(!istype(H)) + return + var/datum/species/S = H.dna.species + //First of all, name. + real_name = H.real_name + + //Facial hair + if(H.facial_hair_style && (FACEHAIR in S.specflags)) + facial_hair_style = H.facial_hair_style + if(S.hair_color) + if(S.hair_color == "mutcolor") + facial_hair_color = H.dna.features["mcolor"] + else + facial_hair_color = S.hair_color + else + facial_hair_color = H.facial_hair_color + hair_alpha = S.hair_alpha + else + facial_hair_style = "Shaved" + facial_hair_color = "000" + hair_alpha = 255 + //Hair + if(H.hair_style && (HAIR in S.specflags)) + hair_style = H.hair_style + if(S.hair_color) + if(S.hair_color == "mutcolor") + hair_color = H.dna.features["mcolor"] + else + hair_color = S.hair_color + else + hair_color = H.hair_color + hair_alpha = S.hair_alpha + else + hair_style = "Bald" + hair_color = "000" + hair_alpha = initial(hair_alpha) + // lipstick + if(H.lip_style && (LIPS in S.specflags)) + lip_style = H.lip_style + lip_color = H.lip_color + else + lip_style = null + lip_color = "white" + // eyes + if(EYECOLOR in S.specflags) + eyes = S.eyes + eye_color = H.eye_color + else + eyes = "eyes" + eye_color = "" + ..() + +/obj/item/bodypart/head/update_icon_dropped() + var/list/standing = get_limb_icon(1) + if(!standing) + return + for(var/image/I in standing) + I.pixel_x = px_x + I.pixel_y = px_y + overlays += standing + +/obj/item/bodypart/head/get_limb_icon(dropped) + overlays.Cut() + var/image/I = ..() + var/list/standing = list() + standing += I + if(dropped) //certain overlays only appear when the limb is being detached from its owner. + var/datum/sprite_accessory/S + + if(status != ORGAN_ROBOTIC) //having a robotic head hides certain features. + //facial hair + if(facial_hair_style) + S = facial_hair_styles_list[facial_hair_style] + if(S) + var/image/img_facial_s = image("icon" = S.icon, "icon_state" = "[S.icon_state]_s", "layer" = -HAIR_LAYER, "dir"=SOUTH) + img_facial_s.color = "#" + facial_hair_color + img_facial_s.alpha = hair_alpha + standing += img_facial_s + + //Applies the debrained overlay if there is no brain + if(!brain) + standing += image("icon"='icons/mob/human_face.dmi', "icon_state" = "debrained_s", "layer" = -HAIR_LAYER, "dir"=SOUTH) + else + if(hair_style) + S = hair_styles_list[hair_style] + if(S) + var/image/img_hair_s = image("icon" = S.icon, "icon_state" = "[S.icon_state]_s", "layer" = -HAIR_LAYER, "dir"=SOUTH) + img_hair_s.color = "#" + hair_color + img_hair_s.alpha = hair_alpha + standing += img_hair_s + + + // lipstick + if(lip_style) + var/image/lips = image("icon"='icons/mob/human_face.dmi', "icon_state"="lips_[lip_style]_s", "layer" = -BODY_LAYER, "dir"=SOUTH) + lips.color = lip_color + standing += lips + + // eyes + if(eye_color) + var/image/img_eyes_s = image("icon" = 'icons/mob/human_face.dmi', "icon_state" = "[eyes]_s", "layer" = -BODY_LAYER, "dir"=SOUTH) + img_eyes_s.color = "#" + eye_color + standing += img_eyes_s + + if(standing.len) + return standing diff --git a/code/modules/surgery/bodyparts/helpers.dm b/code/modules/surgery/bodyparts/helpers.dm new file mode 100644 index 00000000000..1dd5b807a62 --- /dev/null +++ b/code/modules/surgery/bodyparts/helpers.dm @@ -0,0 +1,156 @@ + +/mob/living/proc/get_bodypart(zone) + return + +/mob/living/carbon/get_bodypart(zone) + if(!zone) + zone = "chest" + for(var/X in bodyparts) + var/obj/item/bodypart/L = X + if(L.body_zone == zone) + return L + +//Mob has their active hand +/mob/proc/has_active_hand() + return 1 + +/mob/living/carbon/human/has_active_hand() + var/obj/item/bodypart/L + if(hand) + L = get_bodypart("l_arm") + else + L = get_bodypart("r_arm") + if(!L) + return 0 + return 1 + +/mob/living/carbon/proc/has_left_hand() + return 1 + +/mob/living/carbon/human/has_left_hand() + var/obj/item/bodypart/L + L = get_bodypart("l_arm") + if(!L) + return 0 + return 1 + +/mob/living/carbon/proc/has_right_hand() + return 1 + +/mob/living/carbon/human/has_right_hand() + var/obj/item/bodypart/L + L = get_bodypart("r_arm") + if(!L) + return 0 + return 1 + + +//Limb numbers +/mob/proc/get_num_arms() + return 2 +/mob/proc/get_num_legs() + return 2 + +/mob/living/carbon/human/get_num_arms() + . = 0 + for(var/X in bodyparts) + var/obj/item/bodypart/affecting = X + if(affecting.body_part == ARM_RIGHT) + .++ + if(affecting.body_part == ARM_LEFT) + .++ + +/mob/living/carbon/human/get_num_legs() + . = 0 + for(var/X in bodyparts) + var/obj/item/bodypart/affecting = X + if(affecting.body_part == LEG_RIGHT) + .++ + if(affecting.body_part == LEG_LEFT) + .++ + +/mob/living/proc/get_missing_limbs() + return + +/mob/living/carbon/human/get_missing_limbs() + var/list/full = list("head", "chest", "r_arm", "l_arm", "r_leg", "l_leg") + for(var/zone in full) + if(get_bodypart(zone)) + full -= zone + return full + + +//Remove all embedded objects from all limbs on the human mob +/mob/living/carbon/human/proc/remove_all_embedded_objects() + var/turf/T = get_turf(src) + + for(var/X in bodyparts) + var/obj/item/bodypart/L = X + for(var/obj/item/I in L.embedded_objects) + L.embedded_objects -= I + I.loc = T + + clear_alert("embeddedobject") + +/mob/living/carbon/human/proc/has_embedded_objects() + . = 0 + for(var/X in bodyparts) + var/obj/item/bodypart/L = X + for(var/obj/item/I in L.embedded_objects) + return 1 + + +//Helper for quickly creating a new limb - used by augment code in species.dm spec_attacked_by +/proc/newBodyPart(zone, robotic, fixed_icon, mob/living/carbon/human/source) + var/obj/item/bodypart/L + switch(zone) + if("l_arm") + L = new /obj/item/bodypart/l_arm() + if("r_arm") + L = new /obj/item/bodypart/r_arm() + if("head") + L = new /obj/item/bodypart/head() + if("l_leg") + L = new /obj/item/bodypart/l_leg() + if("r_leg") + L = new /obj/item/bodypart/r_leg() + if("chest") + L = new /obj/item/bodypart/chest() + if(L) + if(source) + L.update_limb(fixed_icon, source) + else if(fixed_icon) + L.no_update = 1//when attached, the limb won't be affected by the appearance changes of its mob owner. + if(robotic) + L.change_bodypart_status(ORGAN_ROBOTIC) + + . = L + + +/proc/skintone2hex(skin_tone) + . = 0 + switch(skin_tone) + if("caucasian1") + . = "ffe0d1" + if("caucasian2") + . = "fcccb3" + if("caucasian3") + . = "e8b59b" + if("latino") + . = "d9ae96" + if("mediterranean") + . = "c79b8b" + if("asian1") + . = "ffdeb3" + if("asian2") + . = "e3ba84" + if("arab") + . = "c4915e" + if("indian") + . = "b87840" + if("african1") + . = "754523" + if("african2") + . = "471c18" + if("albino") + . = "fff4e6" \ No newline at end of file diff --git a/code/modules/surgery/cavity_implant.dm b/code/modules/surgery/cavity_implant.dm index c56b673a067..0db9fca7892 100644 --- a/code/modules/surgery/cavity_implant.dm +++ b/code/modules/surgery/cavity_implant.dm @@ -13,17 +13,16 @@ time = 32 var/obj/item/IC = null -/datum/surgery_step/handle_cavity/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) - for(var/obj/item/I in target.internal_organs) - if(!istype(I, /obj/item/organ)) - IC = I - break +/datum/surgery_step/handle_cavity/preop(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool, datum/surgery/surgery) + var/obj/item/bodypart/chest/CH = target.get_bodypart("chest") + IC = CH.cavity_item if(tool) user.visible_message("[user] begins to insert [tool] into [target]'s [target_zone].", "You begin to insert [tool] into [target]'s [target_zone]...") else user.visible_message("[user] checks for items in [target]'s [target_zone].", "You check for items in [target]'s [target_zone]...") -/datum/surgery_step/handle_cavity/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) +/datum/surgery_step/handle_cavity/success(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool, datum/surgery/surgery) + var/obj/item/bodypart/chest/CH = target.get_bodypart("chest") if(tool) if(IC || tool.w_class > 3 || (NODROP in tool.flags) || istype(tool, /obj/item/organ)) user << "You can't seem to fit [tool] in [target]'s [target_zone]!" @@ -31,14 +30,14 @@ else user.visible_message("[user] stuffs [tool] into [target]'s [target_zone]!", "You stuff [tool] into [target]'s [target_zone].") user.drop_item() - target.internal_organs += tool - tool.loc = target + CH.cavity_item = tool + tool.loc = null return 1 else if(IC) user.visible_message("[user] pulls [IC] out of [target]'s [target_zone]!", "You pull [IC] out of [target]'s [target_zone].") user.put_in_hands(IC) - target.internal_organs -= IC + CH.cavity_item = null return 1 else user << "You don't find anything in [target]'s [target_zone]." diff --git a/code/modules/surgery/dethralling.dm b/code/modules/surgery/dethralling.dm index 947dabed56f..74a8d54a7b4 100644 --- a/code/modules/surgery/dethralling.dm +++ b/code/modules/surgery/dethralling.dm @@ -37,5 +37,5 @@ user.visible_message("[user] shines light onto the tumor in [target]'s head!", "You cleanse the contamination from [target]'s brain!") ticker.mode.remove_thrall(target.mind, 0) target.visible_message("A strange black mass falls from [target]'s head!") - new /obj/item/organ/internal/shadowtumor(get_turf(target)) + new /obj/item/organ/shadowtumor(get_turf(target)) return 1 diff --git a/code/modules/surgery/eye_surgery.dm b/code/modules/surgery/eye_surgery.dm index c15995cae04..5e1ef149876 100644 --- a/code/modules/surgery/eye_surgery.dm +++ b/code/modules/surgery/eye_surgery.dm @@ -24,7 +24,7 @@ return 1 /datum/surgery_step/fix_eyes/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) - if(target.getorgan(/obj/item/organ/internal/brain)) + if(target.getorgan(/obj/item/organ/brain)) user.visible_message("[user] accidentally stabs [target] right in the brain!", "You accidentally stab [target] right in the brain!") target.adjustBrainLoss(100) else diff --git a/code/modules/surgery/helpers.dm b/code/modules/surgery/helpers.dm index a04132d1a94..59259bda02f 100644 --- a/code/modules/surgery/helpers.dm +++ b/code/modules/surgery/helpers.dm @@ -1,12 +1,12 @@ /proc/attempt_initiate_surgery(obj/item/I, mob/living/M, mob/user) if(istype(M)) var/mob/living/carbon/human/H - var/obj/item/organ/limb/affecting + var/obj/item/bodypart/affecting var/selected_zone = user.zone_selected if(istype(M, /mob/living/carbon/human)) H = M - affecting = H.get_organ(check_zone(selected_zone)) + affecting = H.get_bodypart(check_zone(selected_zone)) if(M.lying || isslime(M)) //if they're prone or a slime var/datum/surgery/current_surgery @@ -22,11 +22,15 @@ for(var/datum/surgery/S in all_surgeries) if(!S.possible_locs.Find(selected_zone)) continue - if(affecting && S.requires_organic_bodypart && affecting.status == ORGAN_ROBOTIC) + if(affecting) + if(!S.requires_bodypart) + continue + if(S.requires_organic_bodypart && affecting.status == ORGAN_ROBOTIC) + continue + else if(H && S.requires_bodypart) //human with no limb in surgery zone when we need a limb continue if(!S.can_start(user, M)) continue - for(var/path in S.species) if(istype(M, path)) available_surgeries[S.name] = S @@ -35,9 +39,28 @@ var/P = input("Begin which procedure?", "Surgery", null, null) as null|anything in available_surgeries if(P && user && user.Adjacent(M) && (I in user)) var/datum/surgery/S = available_surgeries[P] + + for(var/datum/surgery/other in M.surgeries) + if(other.location == S.location) + return //during the input() another surgery was started at the same location. + var/datum/surgery/procedure = new S.type if(procedure) procedure.location = selected_zone + + //we check that the surgery is still doable after the input() wait. + if(H) + affecting = H.get_bodypart(check_zone(selected_zone)) + if(affecting) + if(!procedure.requires_bodypart) + return + if(procedure.requires_organic_bodypart && affecting.status == ORGAN_ROBOTIC) + return + else if(H && procedure.requires_bodypart) + return + if(!procedure.can_start(user, M)) + return + if(procedure.ignore_clothes || get_location_accessible(M, selected_zone)) M.surgeries += procedure procedure.organ = affecting diff --git a/code/modules/surgery/limb augmentation.dm b/code/modules/surgery/limb augmentation.dm index e719e926bba..34a8c44a285 100644 --- a/code/modules/surgery/limb augmentation.dm +++ b/code/modules/surgery/limb augmentation.dm @@ -18,7 +18,7 @@ name = "replace limb" implements = list(/obj/item/robot_parts = 100) time = 32 - var/obj/item/organ/limb/L = null // L because "limb" + var/obj/item/bodypart/L = null // L because "limb" @@ -47,25 +47,10 @@ if(ishuman(target)) var/mob/living/carbon/human/H = target user.visible_message("[user] successfully augments [target]'s [parse_zone(target_zone)]!", "You successfully augment [target]'s [parse_zone(target_zone)].") - L.loc = get_turf(target) - H.organs -= L - switch(target_zone) - if("r_leg") - H.organs += new /obj/item/organ/limb/robot/r_leg(src) - if("l_leg") - H.organs += new /obj/item/organ/limb/robot/l_leg(src) - if("r_arm") - H.organs += new /obj/item/organ/limb/robot/r_arm(src) - if("l_arm") - H.organs += new /obj/item/organ/limb/robot/l_arm(src) - if("head") - H.organs += new /obj/item/organ/limb/robot/head(src) - if("chest") - H.organs += new /obj/item/organ/limb/robot/chest(src) + L.change_bodypart_status(ORGAN_ROBOTIC, 1) user.drop_item() qdel(tool) H.update_damage_overlays(0) - H.update_augments() //Gives them the Cyber limb overlay H.updatehealth() add_logs(user, target, "augmented", addition="by giving him new [parse_zone(target_zone)] INTENT: [uppertext(user.a_intent)]") else @@ -73,6 +58,13 @@ return 1 + + + + + + + /datum/surgery/chainsaw name = "chainsaw augmentation" steps = list(/datum/surgery_step/incise, /datum/surgery_step/retract_skin, /datum/surgery_step/saw, /datum/surgery_step/clamp_bleeders, @@ -129,7 +121,6 @@ /datum/surgery_step/chainsaw_removal/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) var/list/hands = get_both_hands(target) for(var/obj/item/weapon/mounted_chainsaw/V in hands) - qdel(V) - new /obj/item/weapon/twohanded/required/chainsaw(get_turf(target)) + target.unEquip(V, 1) user.visible_message("[user] carefully saws [target]'s arm free of the chainsaw.", "You remove the chainsaw.") return 1 diff --git a/code/modules/surgery/organ_manipulation.dm b/code/modules/surgery/organ_manipulation.dm index b0cc38c8dc8..8e8eccc4c8a 100644 --- a/code/modules/surgery/organ_manipulation.dm +++ b/code/modules/surgery/organ_manipulation.dm @@ -23,11 +23,11 @@ /datum/surgery_step/manipulate_organs time = 64 name = "manipulate organs" - implements = list(/obj/item/organ/internal = 100, /obj/item/weapon/reagent_containers/food/snacks/organ = 0) + implements = list(/obj/item/organ = 100, /obj/item/weapon/reagent_containers/food/snacks/organ = 0) var/implements_extract = list(/obj/item/weapon/hemostat = 100, /obj/item/weapon/crowbar = 55) var/implements_mend = list(/obj/item/weapon/cautery = 100, /obj/item/weapon/weldingtool = 70, /obj/item/weapon/lighter = 45, /obj/item/weapon/match = 20) var/current_type - var/obj/item/organ/internal/I = null + var/obj/item/organ/I = null /datum/surgery_step/manipulate_organs/New() ..() @@ -71,7 +71,7 @@ user << "There is no removeable organs in [target]'s [parse_zone(target_zone)]!" return -1 else - for(var/obj/item/organ/internal/O in organs) + for(var/obj/item/organ/O in organs) O.on_find(user) organs -= O organs[O.name] = O diff --git a/code/modules/surgery/organs/augments_arms.dm b/code/modules/surgery/organs/augments_arms.dm index cb8929237ce..8bcdd00522e 100644 --- a/code/modules/surgery/organs/augments_arms.dm +++ b/code/modules/surgery/organs/augments_arms.dm @@ -1,4 +1,4 @@ -/obj/item/organ/internal/cyberimp/arm +/obj/item/organ/cyberimp/arm name = "arm-mounted implant" desc = "You shouldn't see this! Adminhelp and report this as an issue on github!" zone = "r_arm" @@ -14,7 +14,7 @@ var/obj/item/holder = null // You can use this var for item path, it would be converted into an item on New() -/obj/item/organ/internal/cyberimp/arm/New() +/obj/item/organ/cyberimp/arm/New() ..() if(ispath(holder)) holder = new holder(src) @@ -23,17 +23,17 @@ slot = zone + "_device" items_list = contents.Copy() -/obj/item/organ/internal/cyberimp/arm/update_icon() +/obj/item/organ/cyberimp/arm/update_icon() if(zone == "r_arm") transform = null else // Mirroring the icon transform = matrix(-1, 0, 0, 0, 1, 0) -/obj/item/organ/internal/cyberimp/arm/examine(mob/user) +/obj/item/organ/cyberimp/arm/examine(mob/user) ..() user << "[src] is assembled in the [zone == "r_arm" ? "right" : "left"] arm configuration. You can use a screwdriver to reassemble it." -/obj/item/organ/internal/cyberimp/arm/attackby(obj/item/weapon/W, mob/user, params) +/obj/item/organ/cyberimp/arm/attackby(obj/item/weapon/W, mob/user, params) ..() if(istype(W, /obj/item/weapon/screwdriver)) if(zone == "r_arm") @@ -46,21 +46,21 @@ else if(istype(W, /obj/item/weapon/card/emag)) emag_act() -/obj/item/organ/internal/cyberimp/arm/Remove(mob/living/carbon/M, special = 0) +/obj/item/organ/cyberimp/arm/Remove(mob/living/carbon/M, special = 0) Retract() ..() -/obj/item/organ/internal/cyberimp/arm/emag_act() +/obj/item/organ/cyberimp/arm/emag_act() return 0 -/obj/item/organ/internal/cyberimp/arm/gun/emp_act(severity) +/obj/item/organ/cyberimp/arm/gun/emp_act(severity) if(prob(15/severity)) owner << "[src] is hit by EMP!" // give the owner an idea about why his implant is glitching Retract() ..() -/obj/item/organ/internal/cyberimp/arm/proc/Retract() +/obj/item/organ/cyberimp/arm/proc/Retract() if(!holder || (holder in src)) return @@ -73,7 +73,7 @@ holder = null playsound(get_turf(owner), 'sound/mecha/mechmove03.ogg', 50, 1) -/obj/item/organ/internal/cyberimp/arm/proc/Extend(var/obj/item/item) +/obj/item/organ/cyberimp/arm/proc/Extend(var/obj/item/item) if(!(item in src)) return @@ -108,7 +108,7 @@ "You hear a short mechanical noise.") playsound(get_turf(owner), 'sound/mecha/mechmove03.ogg', 50, 1) -/obj/item/organ/internal/cyberimp/arm/ui_action_click() +/obj/item/organ/cyberimp/arm/ui_action_click() if(crit_fail || (!holder && !contents.len)) owner << "The implant doesn't respond. It seems to be broken..." return @@ -131,7 +131,7 @@ Retract() -/obj/item/organ/internal/cyberimp/arm/gun/emp_act(severity) +/obj/item/organ/cyberimp/arm/gun/emp_act(severity) if(prob(30/severity) && owner && !crit_fail) Retract() owner.visible_message("A loud bang comes from [owner]\'s [zone == "r_arm" ? "right" : "left"] arm!") @@ -145,36 +145,36 @@ ..() -/obj/item/organ/internal/cyberimp/arm/gun/laser +/obj/item/organ/cyberimp/arm/gun/laser name = "arm-mounted laser implant" desc = "A variant of the arm cannon implant that fires lethal laser beams. The cannon emerges from the subject's arm and remains inside when not in use." icon_state = "arm_laser" origin_tech = "materials=5;combat=5;biotech=4;powerstorage=4;syndicate=5"//this is kinda nutty and i might lower it holder = /obj/item/weapon/gun/energy/laser/mounted -/obj/item/organ/internal/cyberimp/arm/gun/laser/l/zone = "l_arm" +/obj/item/organ/cyberimp/arm/gun/laser/l/zone = "l_arm" -/obj/item/organ/internal/cyberimp/arm/gun/taser +/obj/item/organ/cyberimp/arm/gun/taser name = "arm-mounted taser implant" desc = "A variant of the arm cannon implant that fires electrodes and disabler shots. The cannon emerges from the subject's arm and remains inside when not in use." icon_state = "arm_taser" origin_tech = "materials=5;combat=5;biotech=4;powerstorage=4" holder = /obj/item/weapon/gun/energy/gun/advtaser/mounted -/obj/item/organ/internal/cyberimp/arm/gun/taser/l/zone = "l_arm" +/obj/item/organ/cyberimp/arm/gun/taser/l/zone = "l_arm" -/obj/item/organ/internal/cyberimp/arm/toolset +/obj/item/organ/cyberimp/arm/toolset name = "integrated toolset implant" desc = "A stripped-down version of engineering cyborg toolset, designed to be installed on subject's arm. Contains all neccessary tools." origin_tech = "materials=5;engineering=5;biotech=4;powerstorage=3" contents = newlist(/obj/item/weapon/screwdriver/cyborg, /obj/item/weapon/wrench/cyborg, /obj/item/weapon/weldingtool/largetank/cyborg, /obj/item/weapon/crowbar/cyborg, /obj/item/weapon/wirecutters/cyborg, /obj/item/device/multitool/cyborg) -/obj/item/organ/internal/cyberimp/arm/toolset/l/zone = "l_arm" +/obj/item/organ/cyberimp/arm/toolset/l/zone = "l_arm" -/obj/item/organ/internal/cyberimp/arm/toolset/emag_act() +/obj/item/organ/cyberimp/arm/toolset/emag_act() if(!(locate(/obj/item/weapon/kitchen/knife/combat/cyborg) in items_list)) usr << "You unlock [src]'s integrated knife!" items_list += new /obj/item/weapon/kitchen/knife/combat/cyborg(src) diff --git a/code/modules/surgery/organs/augments_chest.dm b/code/modules/surgery/organs/augments_chest.dm index 486f5f4536b..74e50bc12fd 100644 --- a/code/modules/surgery/organs/augments_chest.dm +++ b/code/modules/surgery/organs/augments_chest.dm @@ -1,11 +1,11 @@ -/obj/item/organ/internal/cyberimp/chest +/obj/item/organ/cyberimp/chest name = "cybernetic torso implant" desc = "implants for the organs in your torso" icon_state = "chest_implant" implant_overlay = "chest_implant_overlay" zone = "chest" -/obj/item/organ/internal/cyberimp/chest/nutriment +/obj/item/organ/cyberimp/chest/nutriment name = "Nutriment pump implant" desc = "This implant with synthesize and pump into your bloodstream a small amount of nutriment when you are starving." icon_state = "chest_implant" @@ -16,7 +16,7 @@ slot = "stomach" origin_tech = "materials=5;programming=3;biotech=4" -/obj/item/organ/internal/cyberimp/chest/nutriment/on_life() +/obj/item/organ/cyberimp/chest/nutriment/on_life() if(synthesizing) return @@ -27,14 +27,14 @@ spawn(50) synthesizing = 0 -/obj/item/organ/internal/cyberimp/chest/nutriment/emp_act(severity) +/obj/item/organ/cyberimp/chest/nutriment/emp_act(severity) if(!owner) return owner.reagents.add_reagent("????",poison_amount / severity) //food poisoning owner << "You feel like your insides are burning." -/obj/item/organ/internal/cyberimp/chest/nutriment/plus +/obj/item/organ/cyberimp/chest/nutriment/plus name = "Nutriment pump implant PLUS" desc = "This implant will synthesize and pump into your bloodstream a small amount of nutriment when you are hungry." icon_state = "chest_implant" @@ -45,7 +45,7 @@ -/obj/item/organ/internal/cyberimp/chest/reviver +/obj/item/organ/cyberimp/chest/reviver name = "Reviver implant" desc = "This implant will attempt to revive you if you lose consciousness. For the faint of heart!" icon_state = "chest_implant" @@ -56,7 +56,7 @@ var/reviving = 0 var/cooldown = 0 -/obj/item/organ/internal/cyberimp/chest/reviver/on_life() +/obj/item/organ/cyberimp/chest/reviver/on_life() if(reviving) if(owner.stat == UNCONSCIOUS) spawn(30) @@ -87,7 +87,7 @@ revive_cost = 0 reviving = 1 -/obj/item/organ/internal/cyberimp/chest/reviver/emp_act(severity) +/obj/item/organ/cyberimp/chest/reviver/emp_act(severity) if(!owner) return @@ -108,7 +108,7 @@ -/obj/item/organ/internal/cyberimp/chest/thrusters +/obj/item/organ/cyberimp/chest/thrusters name = "implantable thrusters set" desc = "An implantable set of thruster ports. They use the gas from environment or subject's internals for propulsion in zero-gravity areas. \ Unlike regular jetpack, this device has no stablilzation system." @@ -122,21 +122,21 @@ var/on = 0 var/datum/effect_system/trail_follow/ion/ion_trail -/obj/item/organ/internal/cyberimp/chest/thrusters/Insert(mob/living/carbon/M, special = 0) +/obj/item/organ/cyberimp/chest/thrusters/Insert(mob/living/carbon/M, special = 0) ..() if(!ion_trail) ion_trail = new ion_trail.set_up(M) -/obj/item/organ/internal/cyberimp/chest/thrusters/Remove(mob/living/carbon/M, special = 0) +/obj/item/organ/cyberimp/chest/thrusters/Remove(mob/living/carbon/M, special = 0) if(on) toggle(silent=1) ..() -/obj/item/organ/internal/cyberimp/chest/thrusters/ui_action_click() +/obj/item/organ/cyberimp/chest/thrusters/ui_action_click() toggle() -/obj/item/organ/internal/cyberimp/chest/thrusters/proc/toggle(silent=0) +/obj/item/organ/cyberimp/chest/thrusters/proc/toggle(silent=0) if(!on) if(crit_fail) if(!silent) @@ -154,7 +154,7 @@ on = 0 update_icon() -/obj/item/organ/internal/cyberimp/chest/thrusters/update_icon() +/obj/item/organ/cyberimp/chest/thrusters/update_icon() if(on) icon_state = "imp_jetpack-on" else @@ -163,7 +163,7 @@ var/datum/action/A = X A.UpdateButtonIcon() -/obj/item/organ/internal/cyberimp/chest/thrusters/proc/allow_thrust(num) +/obj/item/organ/cyberimp/chest/thrusters/proc/allow_thrust(num) if(!on || !owner) return 0 diff --git a/code/modules/surgery/organs/augments_external.dm b/code/modules/surgery/organs/augments_external.dm deleted file mode 100644 index d3acb5135d9..00000000000 --- a/code/modules/surgery/organs/augments_external.dm +++ /dev/null @@ -1,51 +0,0 @@ -/////AUGMENTATION\\\\\ -//See code/modules/surgery/organs/organ.dm for the parent "limb" - - -/obj/item/organ/limb/robot - name = "cyberlimb" - desc = "You should never be seeing this!" - status = ORGAN_ROBOTIC - -/obj/item/organ/limb/robot/chest - name = "chest" - desc = "A Robotic chest" - icon_state = "chest" - max_damage = 200 - body_part = CHEST - -/obj/item/organ/limb/robot/head - name = "head" - desc = "A Robotic head" - icon_state = "head" - max_damage = 200 - body_part = HEAD - -/obj/item/organ/limb/robot/l_arm - name = "l_arm" - desc = "A Robotic arm" - icon_state = "l_arm" - max_damage = 75 - body_part = ARM_LEFT - -/obj/item/organ/limb/robot/l_leg - name = "l_leg" - desc = "A Robotic leg" - icon_state = "l_leg" - max_damage = 75 - body_part = LEG_LEFT - -/obj/item/organ/limb/robot/r_arm - name = "r_arm" - desc = "A Robotic arm" - icon_state = "r_arm" - max_damage = 75 - body_part = ARM_RIGHT - -/obj/item/organ/limb/robot/r_leg - name = "r_leg" - desc = "A Robotic leg" - icon_state = "r_leg" - max_damage = 75 - body_part = LEG_RIGHT - diff --git a/code/modules/surgery/organs/augments_eyes.dm b/code/modules/surgery/organs/augments_eyes.dm index 1693d217906..e7432e89fa6 100644 --- a/code/modules/surgery/organs/augments_eyes.dm +++ b/code/modules/surgery/organs/augments_eyes.dm @@ -1,4 +1,4 @@ -/obj/item/organ/internal/cyberimp/eyes +/obj/item/organ/cyberimp/eyes name = "cybernetic eyes" desc = "artificial photoreceptors with specialized functionality" icon_state = "eye_implant" @@ -16,7 +16,7 @@ var/aug_message = "Your vision is augmented!" -/obj/item/organ/internal/cyberimp/eyes/Insert(var/mob/living/carbon/M, var/special = 0) +/obj/item/organ/cyberimp/eyes/Insert(var/mob/living/carbon/M, var/special = 0) ..() if(istype(owner, /mob/living/carbon/human) && eye_color) var/mob/living/carbon/human/HMN = owner @@ -28,7 +28,7 @@ owner.update_sight() -/obj/item/organ/internal/cyberimp/eyes/Remove(var/mob/living/carbon/M, var/special = 0) +/obj/item/organ/cyberimp/eyes/Remove(var/mob/living/carbon/M, var/special = 0) M.sight ^= sight_flags if(istype(M,/mob/living/carbon/human) && eye_color) var/mob/living/carbon/human/HMN = owner @@ -36,7 +36,7 @@ HMN.regenerate_icons() ..() -/obj/item/organ/internal/cyberimp/eyes/emp_act(severity) +/obj/item/organ/cyberimp/eyes/emp_act(severity) if(!owner) return if(severity > 1) @@ -45,7 +45,7 @@ owner << "Static obfuscates your vision!" owner.flash_eyes(visual = 1) -/obj/item/organ/internal/cyberimp/eyes/xray +/obj/item/organ/cyberimp/eyes/xray name = "X-ray implant" desc = "These cybernetic eye implants will give you X-ray vision. Blinking is futile." eye_color = "000" @@ -54,7 +54,7 @@ dark_view = 8 sight_flags = SEE_MOBS | SEE_OBJS | SEE_TURFS -/obj/item/organ/internal/cyberimp/eyes/thermals +/obj/item/organ/cyberimp/eyes/thermals name = "Thermals implant" desc = "These cybernetic eye implants will give you Thermal vision. Vertical slit pupil included." eye_color = "FC0" @@ -68,27 +68,27 @@ // HUD implants -/obj/item/organ/internal/cyberimp/eyes/hud +/obj/item/organ/cyberimp/eyes/hud name = "HUD implant" desc = "These cybernetic eyes will display a HUD over everything you see. Maybe." slot = "eye_hud" var/HUD_type = 0 -/obj/item/organ/internal/cyberimp/eyes/hud/Insert(var/mob/living/carbon/M, var/special = 0) +/obj/item/organ/cyberimp/eyes/hud/Insert(var/mob/living/carbon/M, var/special = 0) ..() if(HUD_type) var/datum/atom_hud/H = huds[HUD_type] H.add_hud_to(M) M.permanent_huds |= H -/obj/item/organ/internal/cyberimp/eyes/hud/Remove(var/mob/living/carbon/M, var/special = 0) +/obj/item/organ/cyberimp/eyes/hud/Remove(var/mob/living/carbon/M, var/special = 0) if(HUD_type) var/datum/atom_hud/H = huds[HUD_type] M.permanent_huds ^= H H.remove_hud_from(M) ..() -/obj/item/organ/internal/cyberimp/eyes/hud/medical +/obj/item/organ/cyberimp/eyes/hud/medical name = "Medical HUD implant" desc = "These cybernetic eye implants will display a medical HUD over everything you see." eye_color = "0ff" @@ -97,7 +97,7 @@ aug_message = "You suddenly see health bars floating above people's heads..." HUD_type = DATA_HUD_MEDICAL_ADVANCED -/obj/item/organ/internal/cyberimp/eyes/hud/security +/obj/item/organ/cyberimp/eyes/hud/security name = "Security HUD implant" desc = "These cybernetic eye implants will display a security HUD over everything you see." eye_color = "d00" @@ -108,7 +108,7 @@ // Welding shield implant -/obj/item/organ/internal/cyberimp/eyes/shield +/obj/item/organ/cyberimp/eyes/shield name = "welding shield implant" desc = "These reactive micro-shields will protect you from welders and flashes without obscuring your vision." slot = "eye_shield" @@ -118,5 +118,5 @@ aug_message = null eye_color = null -/obj/item/organ/internal/cyberimp/eyes/shield/emp_act(severity) +/obj/item/organ/cyberimp/eyes/shield/emp_act(severity) return \ No newline at end of file diff --git a/code/modules/surgery/organs/augments_internal.dm b/code/modules/surgery/organs/augments_internal.dm index 3c92f71dd14..3dc5e743049 100644 --- a/code/modules/surgery/organs/augments_internal.dm +++ b/code/modules/surgery/organs/augments_internal.dm @@ -1,13 +1,13 @@ #define STUN_SET_AMOUNT 2 -/obj/item/organ/internal/cyberimp +/obj/item/organ/cyberimp name = "cybernetic implant" desc = "a state-of-the-art implant that improves a baseline's functionality" status = ORGAN_ROBOTIC var/implant_color = "#FFFFFF" var/implant_overlay -/obj/item/organ/internal/cyberimp/New(var/mob/M = null) +/obj/item/organ/cyberimp/New(var/mob/M = null) if(iscarbon(M)) src.Insert(M) if(implant_overlay) @@ -20,7 +20,7 @@ //[[[[BRAIN]]]] -/obj/item/organ/internal/cyberimp/brain +/obj/item/organ/cyberimp/brain name = "cybernetic brain implant" desc = "injectors of extra sub-routines for the brain" icon_state = "brain_implant" @@ -28,7 +28,7 @@ zone = "head" w_class = 1 -/obj/item/organ/internal/cyberimp/brain/emp_act(severity) +/obj/item/organ/cyberimp/brain/emp_act(severity) if(!owner) return var/stun_amount = 5 + (severity-1 ? 0 : 5) @@ -37,7 +37,7 @@ return stun_amount -/obj/item/organ/internal/cyberimp/brain/anti_drop +/obj/item/organ/cyberimp/brain/anti_drop name = "anti-drop implant" desc = "This cybernetic brain implant will allow you to force your hand muscles to contract, preventing item dropping. Twitch ear to toggle." var/active = 0 @@ -50,7 +50,7 @@ origin_tech = "materials=5;programming=4;biotech=4" actions_types = list(/datum/action/item_action/organ_action/toggle) -/obj/item/organ/internal/cyberimp/brain/anti_drop/ui_action_click() +/obj/item/organ/cyberimp/brain/anti_drop/ui_action_click() active = !active if(active) l_hand_obj = owner.l_hand @@ -89,7 +89,7 @@ l_hand_obj = null r_hand_obj = null -/obj/item/organ/internal/cyberimp/brain/anti_drop/emp_act(severity) +/obj/item/organ/cyberimp/brain/anti_drop/emp_act(severity) if(!owner) return var/range = severity ? 10 : 5 @@ -108,26 +108,26 @@ R_item.throw_at(A, range, 2) owner << "Your right arm spasms and throws the [R_item.name]!" -/obj/item/organ/internal/cyberimp/brain/anti_drop/proc/release_items() +/obj/item/organ/cyberimp/brain/anti_drop/proc/release_items() if(!l_hand_ignore && l_hand_obj in owner.contents) l_hand_obj.flags ^= NODROP if(!r_hand_ignore && r_hand_obj in owner.contents) r_hand_obj.flags ^= NODROP -/obj/item/organ/internal/cyberimp/brain/anti_drop/Remove(var/mob/living/carbon/M, special = 0) +/obj/item/organ/cyberimp/brain/anti_drop/Remove(var/mob/living/carbon/M, special = 0) if(active) ui_action_click() ..() -/obj/item/organ/internal/cyberimp/brain/anti_stun +/obj/item/organ/cyberimp/brain/anti_stun name = "CNS Rebooter implant" desc = "This implant will automatically give you back control over your central nervous system, reducing downtime when stunned." implant_color = "#FFFF00" slot = "brain_antistun" origin_tech = "materials=6;programming=4;biotech=5" -/obj/item/organ/internal/cyberimp/brain/anti_stun/on_life() +/obj/item/organ/cyberimp/brain/anti_stun/on_life() ..() if(crit_fail) return @@ -137,7 +137,7 @@ if(owner.weakened > STUN_SET_AMOUNT) owner.weakened = STUN_SET_AMOUNT -/obj/item/organ/internal/cyberimp/brain/anti_stun/emp_act(severity) +/obj/item/organ/cyberimp/brain/anti_stun/emp_act(severity) if(crit_fail) return crit_fail = 1 @@ -146,10 +146,10 @@ //[[[[MOUTH]]]] -/obj/item/organ/internal/cyberimp/mouth +/obj/item/organ/cyberimp/mouth zone = "mouth" -/obj/item/organ/internal/cyberimp/mouth/breathing_tube +/obj/item/organ/cyberimp/mouth/breathing_tube name = "breathing tube implant" desc = "This simple implant adds an internals connector to your back, allowing you to use internals without a mask and protecting you from being choked." icon_state = "implant_mask" @@ -157,7 +157,7 @@ w_class = 1 origin_tech = "materials=2;biotech=3" -/obj/item/organ/internal/cyberimp/mouth/breathing_tube/emp_act(severity) +/obj/item/organ/cyberimp/mouth/breathing_tube/emp_act(severity) if(prob(60/severity)) owner << "Your breathing tube suddenly closes!" owner.losebreath += 2 @@ -179,8 +179,8 @@ /obj/item/weapon/storage/box/cyber_implants/bundle name = "boxed cybernetic implants" - var/list/boxed = list(/obj/item/organ/internal/cyberimp/eyes/xray,/obj/item/organ/internal/cyberimp/eyes/thermals, - /obj/item/organ/internal/cyberimp/brain/anti_stun, /obj/item/organ/internal/cyberimp/chest/reviver) + var/list/boxed = list(/obj/item/organ/cyberimp/eyes/xray,/obj/item/organ/cyberimp/eyes/thermals, + /obj/item/organ/cyberimp/brain/anti_stun, /obj/item/organ/cyberimp/chest/reviver) var/amount = 5 /obj/item/weapon/storage/box/cyber_implants/bundle/New() diff --git a/code/modules/surgery/organs/autoimplanter.dm b/code/modules/surgery/organs/autoimplanter.dm index 5ec3b224683..e7878676624 100644 --- a/code/modules/surgery/organs/autoimplanter.dm +++ b/code/modules/surgery/organs/autoimplanter.dm @@ -4,7 +4,7 @@ icon_state = "autoimplanter" item_state = "walkietalkie"//left as this so as to intentionally not have inhands w_class = 2 - var/obj/item/organ/internal/cyberimp/storedorgan + var/obj/item/organ/cyberimp/storedorgan /obj/item/device/autoimplanter/attack_self(mob/user)//when the object it used... if(!storedorgan) @@ -16,7 +16,7 @@ storedorgan = null /obj/item/device/autoimplanter/attackby(obj/item/I, mob/user, params) - if(istype(I, /obj/item/organ/internal/cyberimp)) + if(istype(I, /obj/item/organ/cyberimp)) if(storedorgan) user << "[src] already has an implant stored." return diff --git a/code/modules/surgery/organs/helpers.dm b/code/modules/surgery/organs/helpers.dm index b25f792f336..f1ee5ec13f6 100644 --- a/code/modules/surgery/organs/helpers.dm +++ b/code/modules/surgery/organs/helpers.dm @@ -20,7 +20,7 @@ mob/living/carbon/getorganszone(zone, var/subzones = 0) if(zone == "chest") returnorg = getorganszone("groin") - for(var/obj/item/organ/internal/O in internal_organs) + for(var/obj/item/organ/O in internal_organs) if(zone == O.zone) returnorg += O return returnorg @@ -28,11 +28,6 @@ mob/living/carbon/getorganszone(zone, var/subzones = 0) mob/living/carbon/getorganslot(slot) return internal_organs_slot[slot] -mob/proc/getlimb() - return - -mob/living/carbon/human/getlimb(typepath) - return (locate(typepath) in organs) proc/isorgan(atom/A) - return istype(A, /obj/item/organ/internal) \ No newline at end of file + return istype(A, /obj/item/organ) \ No newline at end of file diff --git a/code/modules/surgery/organs/organ_external.dm b/code/modules/surgery/organs/organ_external.dm deleted file mode 100644 index 18cd9377ecf..00000000000 --- a/code/modules/surgery/organs/organ_external.dm +++ /dev/null @@ -1,189 +0,0 @@ -/obj/item/organ - name = "organ" - icon = 'icons/obj/surgery.dmi' - var/mob/living/carbon/owner = null - var/status = ORGAN_ORGANIC - - -//Old Datum Limbs: -// code/modules/unused/limbs.dm - - -/obj/item/organ/limb - name = "limb" - var/body_part = null - var/brutestate = 0 - var/burnstate = 0 - var/brute_dam = 0 - var/burn_dam = 0 - var/max_damage = 0 - var/list/embedded_objects = list() - - - -/obj/item/organ/limb/chest - name = "chest" - desc = "why is it detached..." - icon_state = "chest" - max_damage = 200 - body_part = CHEST - - -/obj/item/organ/limb/head - name = "head" - desc = "what a way to get a head in life..." - icon_state = "head" - max_damage = 200 - body_part = HEAD - - -/obj/item/organ/limb/l_arm - name = "l_arm" - desc = "why is it detached..." - icon_state = "l_arm" - max_damage = 75 - body_part = ARM_LEFT - - -/obj/item/organ/limb/l_leg - name = "l_leg" - desc = "why is it detached..." - icon_state = "l_leg" - max_damage = 75 - body_part = LEG_LEFT - - -/obj/item/organ/limb/r_arm - name = "r_arm" - desc = "why is it detached..." - icon_state = "r_arm" - max_damage = 75 - body_part = ARM_RIGHT - - -/obj/item/organ/limb/r_leg - name = "r_leg" - desc = "why is it detached..." - icon_state = "r_leg" - max_damage = 75 - body_part = LEG_RIGHT - -/obj/item/organ/severedtail - name = "tail" - desc = "A severed tail." - icon_state = "severedtail" - color = "#161" - var/markings = "Smooth" - -//Applies brute and burn damage to the organ. Returns 1 if the damage-icon states changed at all. -//Damage will not exceed max_damage using this proc -//Cannot apply negative damage -/obj/item/organ/limb/proc/take_damage(brute, burn) - if(owner && (owner.status_flags & GODMODE)) - return 0 //godmode - brute = max(brute,0) - burn = max(burn,0) - - - if(status == ORGAN_ROBOTIC) //This makes robolimbs not damageable by chems and makes it stronger - brute = max(0, brute - 5) - burn = max(0, burn - 4) - - var/can_inflict = max_damage - (brute_dam + burn_dam) - if(!can_inflict) - return 0 - - if((brute + burn) < can_inflict) - brute_dam += brute - burn_dam += burn - else - if(brute > 0) - if(burn > 0) - brute = round( (brute/(brute+burn)) * can_inflict, 1 ) - burn = can_inflict - brute //gets whatever damage is left over - brute_dam += brute - burn_dam += burn - else - brute_dam += can_inflict - else - if(burn > 0) - burn_dam += can_inflict - else - return 0 - if(owner) - owner.updatehealth() - return update_organ_icon() - - -//Heals brute and burn damage for the organ. Returns 1 if the damage-icon states changed at all. -//Damage cannot go below zero. -//Cannot remove negative damage (i.e. apply damage) -/obj/item/organ/limb/proc/heal_damage(brute, burn, robotic) - - if(robotic && status != ORGAN_ROBOTIC) // This makes organic limbs not heal when the proc is in Robotic mode. - brute = max(0, brute - 3) - burn = max(0, burn - 3) - - if(!robotic && status == ORGAN_ROBOTIC) // This makes robolimbs not healable by chems. - brute = max(0, brute - 3) - burn = max(0, burn - 3) - - brute_dam = max(brute_dam - brute, 0) - burn_dam = max(burn_dam - burn, 0) - if(owner) - owner.updatehealth() - return update_organ_icon() - - -//Returns total damage...kinda pointless really -/obj/item/organ/limb/proc/get_damage() - return brute_dam + burn_dam - - -//Updates an organ's brute/burn states for use by update_damage_overlays() -//Returns 1 if we need to update overlays. 0 otherwise. -/obj/item/organ/limb/proc/update_organ_icon() - if(status == ORGAN_ORGANIC) //Robotic limbs show no damage - RR - var/tbrute = round( (brute_dam/max_damage)*3, 1 ) - var/tburn = round( (burn_dam/max_damage)*3, 1 ) - if((tbrute != brutestate) || (tburn != burnstate)) - brutestate = tbrute - burnstate = tburn - return 1 - return 0 - -//Returns a display name for the organ -/obj/item/organ/limb/proc/getDisplayName() //Added "Chest" and "Head" just in case, this may not be needed - switch(name) - if("l_leg") - return "left leg" - if("r_leg") - return "right leg" - if("l_arm") - return "left arm" - if("r_arm") - return "right arm" - if("chest") - return "chest" - if("head") - return "head" - else - return name - - -//Remove all embedded objects from all limbs on the human mob -/mob/living/carbon/human/proc/remove_all_embedded_objects() - var/turf/T = get_turf(src) - - for(var/obj/item/organ/limb/L in organs) - for(var/obj/item/I in L.embedded_objects) - L.embedded_objects -= I - I.loc = T - - clear_alert("embeddedobject") - -/mob/living/carbon/human/proc/has_embedded_objects() - . = 0 - for(var/obj/item/organ/limb/L in organs) - for(var/obj/item/I in L.embedded_objects) - return 1 \ No newline at end of file diff --git a/code/modules/surgery/organs/organ_internal.dm b/code/modules/surgery/organs/organ_internal.dm index a8cd6be08e2..c7a170e356a 100644 --- a/code/modules/surgery/organs/organ_internal.dm +++ b/code/modules/surgery/organs/organ_internal.dm @@ -1,4 +1,9 @@ -/obj/item/organ/internal + +/obj/item/organ + name = "organ" + icon = 'icons/obj/surgery.dmi' + var/mob/living/carbon/owner = null + var/status = ORGAN_ORGANIC origin_tech = "biotech=2" force = 1 w_class = 2 @@ -9,11 +14,11 @@ var/vital = 0 -/obj/item/organ/internal/proc/Insert(mob/living/carbon/M, special = 0) +/obj/item/organ/proc/Insert(mob/living/carbon/M, special = 0) if(!iscarbon(M) || owner == M) return - var/obj/item/organ/internal/replaced = M.getorganslot(slot) + var/obj/item/organ/replaced = M.getorganslot(slot) if(replaced) replaced.Remove(M, special = 1) @@ -26,7 +31,7 @@ A.Grant(M) -/obj/item/organ/internal/proc/Remove(mob/living/carbon/M, special = 0) +/obj/item/organ/proc/Remove(mob/living/carbon/M, special = 0) owner = null if(M) M.internal_organs -= src @@ -39,19 +44,19 @@ A.Remove(M) -/obj/item/organ/internal/proc/on_find(mob/living/finder) +/obj/item/organ/proc/on_find(mob/living/finder) return -/obj/item/organ/internal/proc/on_life() +/obj/item/organ/proc/on_life() return -/obj/item/organ/internal/examine(mob/user) +/obj/item/organ/examine(mob/user) ..() if(status == ORGAN_ROBOTIC && crit_fail) user << "[src] seems to be broken!" -/obj/item/organ/internal/proc/prepare_eat() +/obj/item/organ/proc/prepare_eat() var/obj/item/weapon/reagent_containers/food/snacks/organ/S = new S.name = name S.desc = desc @@ -69,12 +74,12 @@ list_reagents = list("nutriment" = 5) -/obj/item/organ/internal/Destroy() +/obj/item/organ/Destroy() if(owner) Remove(owner, 1) return ..() -/obj/item/organ/internal/attack(mob/living/carbon/M, mob/user) +/obj/item/organ/attack(mob/living/carbon/M, mob/user) if(M == user && ishuman(user)) var/mob/living/carbon/human/H = user if(status == ORGAN_ORGANIC) @@ -87,7 +92,7 @@ else ..() -/obj/item/organ/internal/item_action_slot_check(slot,mob/user) +/obj/item/organ/item_action_slot_check(slot,mob/user) return //so we don't grant the organ's action to mobs who pick up the organ. //Looking for brains? @@ -95,7 +100,7 @@ -/obj/item/organ/internal/heart +/obj/item/organ/heart name = "heart" icon_state = "heart-on" zone = "chest" @@ -105,13 +110,13 @@ var/icon_base = "heart" attack_verb = list("beat", "thumped") -/obj/item/organ/internal/heart/update_icon() +/obj/item/organ/heart/update_icon() if(beating) icon_state = "[icon_base]-on" else icon_state = "[icon_base]-off" -/obj/item/organ/internal/heart/Remove(mob/living/carbon/M, special = 0) +/obj/item/organ/heart/Remove(mob/living/carbon/M, special = 0) ..() if(ishuman(M)) var/mob/living/carbon/human/H = M @@ -125,7 +130,7 @@ if(!owner) Stop() -/obj/item/organ/internal/heart/attack_self(mob/user) +/obj/item/organ/heart/attack_self(mob/user) ..() if(!beating) Restart() @@ -134,7 +139,7 @@ Stop() -/obj/item/organ/internal/heart/Insert(mob/living/carbon/M, special = 0) +/obj/item/organ/heart/Insert(mob/living/carbon/M, special = 0) ..() if(ishuman(M) && beating) var/mob/living/carbon/human/H = M @@ -142,23 +147,23 @@ H.heart_attack = 0 return -/obj/item/organ/internal/heart/proc/Stop() +/obj/item/organ/heart/proc/Stop() beating = 0 update_icon() return 1 -/obj/item/organ/internal/heart/proc/Restart() +/obj/item/organ/heart/proc/Restart() beating = 1 update_icon() return 1 -/obj/item/organ/internal/heart/prepare_eat() +/obj/item/organ/heart/prepare_eat() var/obj/S = ..() S.icon_state = "heart-off" return S -/obj/item/organ/internal/heart/cursed +/obj/item/organ/heart/cursed name = "cursed heart" desc = "it needs to be pumped..." icon_state = "cursedheart-off" @@ -176,7 +181,7 @@ var/heal_oxy = 0 -/obj/item/organ/internal/heart/cursed/attack(mob/living/carbon/human/H, mob/living/carbon/human/user, obj/target) +/obj/item/organ/heart/cursed/attack(mob/living/carbon/human/H, mob/living/carbon/human/user, obj/target) if(H == user && istype(H)) playsound(user,'sound/effects/singlebeat.ogg',40,1) user.drop_item() @@ -184,7 +189,7 @@ else return ..() -/obj/item/organ/internal/heart/cursed/on_life() +/obj/item/organ/heart/cursed/on_life() if(world.time > (last_pump + pump_delay)) if(ishuman(owner) && owner.client) //While this entire item exists to make people suffer, they can't control disconnects. var/mob/living/carbon/human/H = owner @@ -196,7 +201,7 @@ else last_pump = world.time //lets be extra fair *sigh* -/obj/item/organ/internal/heart/cursed/Insert(mob/living/carbon/M, special = 0) +/obj/item/organ/heart/cursed/Insert(mob/living/carbon/M, special = 0) ..() if(owner) owner << "Your heart has been replaced with a cursed one, you have to pump this one manually otherwise you'll die!" @@ -207,8 +212,8 @@ //You are now brea- pumping blood manually /datum/action/item_action/organ_action/cursed_heart/Trigger() . = ..() - if(. && istype(target,/obj/item/organ/internal/heart/cursed)) - var/obj/item/organ/internal/heart/cursed/cursed_heart = target + if(. && istype(target,/obj/item/organ/heart/cursed)) + var/obj/item/organ/heart/cursed/cursed_heart = target if(world.time < (cursed_heart.last_pump + (cursed_heart.pump_delay-10))) //no spam owner << "Too soon!" @@ -234,7 +239,7 @@ -/obj/item/organ/internal/lungs +/obj/item/organ/lungs name = "lungs" icon_state = "lungs" zone = "chest" @@ -242,12 +247,12 @@ gender = PLURAL w_class = 3 -/obj/item/organ/internal/lungs/prepare_eat() +/obj/item/organ/lungs/prepare_eat() var/obj/S = ..() S.reagents.add_reagent("salbutamol", 5) return S -/obj/item/organ/internal/tongue +/obj/item/organ/tongue name = "tongue" desc = "A fleshy muscle mostly used for lying." icon_state = "tonguenormal" @@ -256,26 +261,26 @@ var/say_mod = null attack_verb = list("licked", "slobbered", "slapped", "frenched", "tongued") -/obj/item/organ/internal/tongue/proc/TongueSpeech(var/message) +/obj/item/organ/tongue/proc/TongueSpeech(var/message) return message -/obj/item/organ/internal/tongue/Insert(mob/living/carbon/M, special = 0) +/obj/item/organ/tongue/Insert(mob/living/carbon/M, special = 0) ..() if(say_mod && M.dna && M.dna.species) M.dna.species.say_mod = say_mod -/obj/item/organ/internal/tongue/Remove(mob/living/carbon/M, special = 0) +/obj/item/organ/tongue/Remove(mob/living/carbon/M, special = 0) ..() if(say_mod && M.dna && M.dna.species) M.dna.species.say_mod = initial(M.dna.species.say_mod) -/obj/item/organ/internal/tongue/lizard +/obj/item/organ/tongue/lizard name = "forked tongue" desc = "A thin and long muscle typically found in reptilian races, apparently moonlights as a nose." icon_state = "tonguelizard" say_mod = "hisses" -/obj/item/organ/internal/tongue/lizard/TongueSpeech(var/message) +/obj/item/organ/tongue/lizard/TongueSpeech(var/message) var/regex/lizard_hiss = new("s+", "g") var/regex/lizard_hiSS = new("S+", "g") if(copytext(message, 1, 2) != "*") @@ -283,13 +288,13 @@ message = lizard_hiSS.Replace(message, "SSS") return message -/obj/item/organ/internal/tongue/fly +/obj/item/organ/tongue/fly name = "proboscis" desc = "A freakish looking meat tube that apparently can take in liquids." icon_state = "tonguefly" say_mod = "buzzes" -/obj/item/organ/internal/tongue/fly/TongueSpeech(var/message) +/obj/item/organ/tongue/fly/TongueSpeech(var/message) var/regex/fly_buzz = new("z+", "g") var/regex/fly_buZZ = new("Z+", "g") if(copytext(message, 1, 2) != "*") @@ -297,18 +302,18 @@ message = fly_buZZ.Replace(message, "ZZZ") return message -/obj/item/organ/internal/tongue/abductor +/obj/item/organ/tongue/abductor name = "superlingual matrix" desc = "A mysterious structure that allows for instant communication between users. Pretty impressive until you need to eat something." icon_state = "tongueayylmao" say_mod = "gibbers" -/obj/item/organ/internal/tongue/abductor/TongueSpeech(var/message) +/obj/item/organ/tongue/abductor/TongueSpeech(var/message) //Hacks var/mob/living/carbon/human/user = usr var/rendered = "[user.name]: [message]" for(var/mob/living/carbon/human/H in living_mob_list) - var/obj/item/organ/internal/tongue/T = H.getorganslot("tongue") + var/obj/item/organ/tongue/T = H.getorganslot("tongue") if(!T || T.type != type) continue else if(H.dna && H.dna.species.id == "abductor" && user.dna && user.dna.species.id == "abductor") @@ -321,13 +326,13 @@ M << "(F) [rendered]" return "" -/obj/item/organ/internal/tongue/zombie +/obj/item/organ/tongue/zombie name = "rotting tongue" desc = "Between the decay and the fact that it's just lying there you doubt a tongue has ever seemed less sexy." icon_state = "tonguezombie" say_mod = "moans" -/obj/item/organ/internal/tongue/zombie/TongueSpeech(var/message) +/obj/item/organ/tongue/zombie/TongueSpeech(var/message) var/list/message_list = splittext(message, " ") var/maxchanges = max(round(message_list.len / 1.5), 2) @@ -343,24 +348,24 @@ return jointext(message_list, " ") -/obj/item/organ/internal/tongue/alien +/obj/item/organ/tongue/alien name = "alien tongue" desc = "According to leading xenobiologists the evolutionary benefit of having a second mouth in your mouth is \"that it looks badass\"." icon_state = "tonguexeno" say_mod = "hiss" -/obj/item/organ/internal/tongue/alien/TongueSpeech(var/message) +/obj/item/organ/tongue/alien/TongueSpeech(var/message) playsound(owner, "hiss", 25, 1, 1) return message -/obj/item/organ/internal/appendix +/obj/item/organ/appendix name = "appendix" icon_state = "appendix" zone = "groin" slot = "appendix" var/inflamed = 0 -/obj/item/organ/internal/appendix/update_icon() +/obj/item/organ/appendix/update_icon() if(inflamed) icon_state = "appendixinflamed" name = "inflamed appendix" @@ -368,25 +373,25 @@ icon_state = "appendix" name = "appendix" -/obj/item/organ/internal/appendix/Remove(mob/living/carbon/M, special = 0) +/obj/item/organ/appendix/Remove(mob/living/carbon/M, special = 0) for(var/datum/disease/appendicitis/A in M.viruses) A.cure() inflamed = 1 update_icon() ..() -/obj/item/organ/internal/appendix/Insert(mob/living/carbon/M, special = 0) +/obj/item/organ/appendix/Insert(mob/living/carbon/M, special = 0) ..() if(inflamed) M.AddDisease(new /datum/disease/appendicitis) -/obj/item/organ/internal/appendix/prepare_eat() +/obj/item/organ/appendix/prepare_eat() var/obj/S = ..() if(inflamed) S.reagents.add_reagent("????", 5) return S -/obj/item/organ/internal/shadowtumor +/obj/item/organ/shadowtumor name = "black tumor" desc = "A tiny black mass with red tendrils trailing from it. It seems to shrivel in the light." icon_state = "blacktumor" @@ -396,15 +401,15 @@ slot = "brain_tumor" var/health = 3 -/obj/item/organ/internal/shadowtumor/New() +/obj/item/organ/shadowtumor/New() ..() SSobj.processing |= src -/obj/item/organ/internal/shadowtumor/Destroy() +/obj/item/organ/shadowtumor/Destroy() SSobj.processing.Remove(src) ..() -/obj/item/organ/internal/shadowtumor/process() +/obj/item/organ/shadowtumor/process() if(isturf(loc)) var/turf/T = loc var/light_count = T.get_lumcount() diff --git a/code/modules/surgery/prosthetic_replacement.dm b/code/modules/surgery/prosthetic_replacement.dm new file mode 100644 index 00000000000..050b0fefbd7 --- /dev/null +++ b/code/modules/surgery/prosthetic_replacement.dm @@ -0,0 +1,48 @@ +/datum/surgery/prosthetic_replacement + name = "prosthetic replacement" + steps = list(/datum/surgery_step/incise, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/retract_skin, /datum/surgery_step/add_prosthetic) + species = list(/mob/living/carbon/human) + possible_locs = list("r_arm", "l_arm", "l_leg", "r_leg", "head") + requires_bodypart = FALSE //need a missing limb + +/datum/surgery/prosthetic_replacement/can_start(mob/user, mob/living/carbon/target) + if(!ishuman(target)) + return 0 + var/mob/living/carbon/human/H = target + if(!H.get_bodypart(user.zone_selected)) //can only start if limb is missing + return 1 + + + +/datum/surgery_step/add_prosthetic + name = "add prosthetic" + implements = list(/obj/item/robot_parts = 100, /obj/item/bodypart = 100) + time = 32 + +/datum/surgery_step/add_prosthetic/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) + var/tool_body_zone + if(istype(tool, /obj/item/robot_parts)) + var/obj/item/robot_parts/RP = tool + tool_body_zone = RP.body_zone + else if(istype(tool, /obj/item/bodypart)) + var/obj/item/bodypart/L = tool + if(L.status != ORGAN_ROBOTIC) + user << "You need a robotic limb for this." + return -1 //fail + tool_body_zone = L.body_zone + if(target_zone == tool_body_zone) //so we can't replace a leg with an arm. + user.visible_message("[user] begins to replace [target]'s [parse_zone(target_zone)].", "You begin to replace [target]'s [parse_zone(target_zone)]...") + else + user << "[tool] isn't the right type for [parse_zone(target_zone)]." + +/datum/surgery_step/add_prosthetic/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) + var/obj/item/bodypart/L + if(istype(tool, /obj/item/robot_parts)) + L = newBodyPart(target_zone, 1, 1) + user.drop_item() + qdel(tool) + else + L = tool + L.attach_limb(target) + user.visible_message("[user] successfully replaces [target]'s [parse_zone(target_zone)]!", "You succeed in replacing [target]'s [parse_zone(target_zone)].") + return 1 \ No newline at end of file diff --git a/code/modules/surgery/remove_embedded_object.dm b/code/modules/surgery/remove_embedded_object.dm index 1573d010508..7117d276a76 100644 --- a/code/modules/surgery/remove_embedded_object.dm +++ b/code/modules/surgery/remove_embedded_object.dm @@ -8,7 +8,7 @@ name = "remove embedded objects" time = 32 accept_hand = 1 - var/obj/item/organ/limb/L = null + var/obj/item/bodypart/L = null /datum/surgery_step/remove_object/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) @@ -30,9 +30,9 @@ L.embedded_objects -= I if(objects > 0) - user.visible_message("[user] sucessfully removes [objects] objects from [H]'s [L.getDisplayName()]!", "You sucessfully remove [objects] objects from [H]'s [L.getDisplayName()].") + user.visible_message("[user] sucessfully removes [objects] objects from [H]'s [L]!", "You sucessfully remove [objects] objects from [H]'s [L.name].") else - user << "You find no objects embedded in [H]'s [L.getDisplayName()]!" + user << "You find no objects embedded in [H]'s [L]!" else user << "You can't find [target]'s [parse_zone(user.zone_selected)], let alone any objects embedded in it!" diff --git a/code/modules/surgery/surgery.dm b/code/modules/surgery/surgery.dm index 2e63fae2b66..8bb3cf641a5 100644 --- a/code/modules/surgery/surgery.dm +++ b/code/modules/surgery/surgery.dm @@ -10,7 +10,7 @@ var/list/possible_locs = list() //Multiple locations -- c0 var/ignore_clothes = 0 //This surgery ignores clothes var/obj/item/organ/organ //Operable body part - + var/requires_bodypart = TRUE //Surgery available only when a bodypart is present, or only when it is missing. /datum/surgery/proc/can_start(mob/user, mob/living/carbon/target) // if 0 surgery wont show up in list @@ -43,7 +43,7 @@ //Check /mob/living/carbon/attackby for how surgery progresses, and also /mob/living/carbon/attack_hand. //As of Feb 21 2013 they are in code/modules/mob/living/carbon/carbon.dm, lines 459 and 51 respectively. //Other important variables are var/list/surgeries (/mob/living) and var/list/internal_organs (/mob/living/carbon) -// var/list/organs (/mob/living/carbon/human) is the LIMBS of a Mob. +// var/list/bodyparts (/mob/living/carbon/human) is the LIMBS of a Mob. //Surgical procedures are initiated by attempt_initiate_surgery(), which is called by surgical drapes and bedsheets. // /code/modules/surgery/multiple_location_example.dm contains steps to setup a multiple location operation. diff --git a/code/modules/surgery/tail_modification.dm b/code/modules/surgery/tail_modification.dm index 68aa3e4fd47..1b60df3f839 100644 --- a/code/modules/surgery/tail_modification.dm +++ b/code/modules/surgery/tail_modification.dm @@ -32,7 +32,7 @@ L.dna.species.mutant_bodyparts -= "waggingtail_lizard" if("spines" in L.dna.features) L.dna.features -= "spines" - var/obj/item/organ/severedtail/S = new(get_turf(target)) + var/obj/item/severedtail/S = new(get_turf(target)) S.color = "#[L.dna.features["mcolor"]]" S.markings = "[L.dna.features["tail"]]" L.update_body() @@ -54,7 +54,7 @@ /datum/surgery_step/attach_tail name = "attach tail" - implements = list(/obj/item/organ/severedtail = 100) + implements = list(/obj/item/severedtail = 100) time = 64 /datum/surgery_step/attach_tail/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) @@ -65,7 +65,7 @@ user.visible_message("[user] gives [L] a tail!", "You give [L] a tail. It adjusts to [L]'s melanin.") // fluff for color if(!(L.dna.features["mcolor"])) L.dna.features["mcolor"] = tool.color - var/obj/item/organ/severedtail/T = tool + var/obj/item/severedtail/T = tool L.dna.features["tail_lizard"] = T.markings L.dna.species.mutant_bodyparts += "tail_lizard" qdel(tool) diff --git a/code/modules/uplink/uplink_item.dm b/code/modules/uplink/uplink_item.dm index 2374af37bca..ef819cb7189 100644 --- a/code/modules/uplink/uplink_item.dm +++ b/code/modules/uplink/uplink_item.dm @@ -844,10 +844,10 @@ var/list/uplink_items = list() // Global list so we only initialize this once. /datum/uplink_item/device_tools/c4 name = "Composition C-4" - desc = "C-4 is plastic explosive of the common variety Composition C. You can use it to breach walls or connect \ - a signaler to its wiring to make it remotely detonable. It has a modifiable timer with a \ + desc = "C-4 is plastic explosive of the common variety Composition C. You can use it to breach walls, sabotage equipment, or connect \ + an assembly to it in order to alter the way it detonates. It has a modifiable timer with a \ minimum setting of 10 seconds." - item = /obj/item/weapon/c4 + item = /obj/item/weapon/grenade/plastic/c4 cost = 1 /datum/uplink_item/device_tools/c4bag @@ -856,6 +856,13 @@ var/list/uplink_items = list() // Global list so we only initialize this once. item = /obj/item/weapon/storage/backpack/dufflebag/syndie/c4 cost = 9 //10% discount! +/datum/uplink_item/device_tools/x4bag + name = "Bag of X-4 explosives" + desc = "Contains 3 X-4 plastic explosives. Similar, but more powerful than C-4. X-4 can be placed on a solid surface, such as a wall or window, and it will \ + blast through the wall, injuring anything on the opposite side, while being safer to the user. For when you want a wider, deeper, hole." + item = /obj/item/weapon/storage/backpack/dufflebag/syndie/x4 + cost = 4 // + /datum/uplink_item/device_tools/powersink name = "Power Sink" desc = "When screwed to wiring attached to a power grid and activated, this large device places excessive \ @@ -995,7 +1002,7 @@ var/list/uplink_items = list() // Global list so we only initialize this once. /datum/uplink_item/cyber_implants/spawn_item(turf/loc, obj/item/device/uplink/U) if(item) - if(findtext(item, /obj/item/organ/internal/cyberimp)) + if(findtext(item, /obj/item/organ/cyberimp)) return new /obj/item/weapon/storage/box/cyber_implants(loc, item) else return ..() @@ -1003,26 +1010,26 @@ var/list/uplink_items = list() // Global list so we only initialize this once. /datum/uplink_item/cyber_implants/thermals name = "Thermal Vision Implant" desc = "These cybernetic eyes will give you thermal vision. They must be implanted via surgery." - item = /obj/item/organ/internal/cyberimp/eyes/thermals + item = /obj/item/organ/cyberimp/eyes/thermals cost = 8 /datum/uplink_item/cyber_implants/xray name = "X-Ray Vision Implant" desc = "These cybernetic eyes will give you X-ray vision. They must be implanted via surgery." - item = /obj/item/organ/internal/cyberimp/eyes/xray + item = /obj/item/organ/cyberimp/eyes/xray cost = 10 /datum/uplink_item/cyber_implants/antistun name = "CNS Rebooter Implant" desc = "This implant will help you get back up on your feet faster after being stunned. \ It must be implanted via surgery." - item = /obj/item/organ/internal/cyberimp/brain/anti_stun + item = /obj/item/organ/cyberimp/brain/anti_stun cost = 12 /datum/uplink_item/cyber_implants/reviver name = "Reviver Implant" desc = "This implant will attempt to revive you if you lose consciousness. It must be implanted via surgery." - item = /obj/item/organ/internal/cyberimp/chest/reviver + item = /obj/item/organ/cyberimp/chest/reviver cost = 8 /datum/uplink_item/cyber_implants/bundle diff --git a/code/world.dm b/code/world.dm index cbd4046227d..478b3790af7 100644 --- a/code/world.dm +++ b/code/world.dm @@ -149,6 +149,13 @@ var/last_irc_status = 0 C << "PR: [input["announce"]]" #undef CHAT_PULLR + else if("crossmessage" in input) + if(!key_valid) + return + else + if(input["crossmessage"] == "Ahelp") + relay_msg_admins("HELP: [input["source"]] [input["message"]]") + /world/Reboot(var/reason, var/feedback_c, var/feedback_r, var/time) if (reason == 1) //special reboot, do none of the normal stuff if (usr) @@ -283,21 +290,13 @@ var/inerror = 0 else if (n > 0) features += "~[n] player" - /* - is there a reason for this? the byond site shows 'hosted by X' when there is a proper host already. - if (host) - features += "hosted by [host]" - */ - if (!host && config && config.hostedby) features += "hosted by [config.hostedby]" if (features) s += ": [jointext(features, ", ")]" - /* does this help? I do not know */ - if (src.status != s) - src.status = s + status = s #define FAILED_DB_CONNECTION_CUTOFF 5 var/failed_db_connections = 0 diff --git a/config/admins.txt b/config/admins.txt index 8db72174aa7..b5d7d797fff 100644 --- a/config/admins.txt +++ b/config/admins.txt @@ -114,6 +114,6 @@ coiax = Game Master RandomMarine = Game Master PKPenguin321 = Game Master TechnoAlchemist = Game Master - +Aloraydrel = Game Master diff --git a/config/config.txt b/config/config.txt index 2bab69b8652..f1b4078f00f 100644 --- a/config/config.txt +++ b/config/config.txt @@ -168,6 +168,12 @@ TICKLAG 0.9 ## Communication key for receiving data through world/Topic(), you don't want to give this out #COMMS_KEY default_pwd +## World address and port for server recieving cross server messages +#CROSS_SERVER_ADDRESS byond:\\address:port + +## Name that the server calls itself in communications +#CROSS_COMMS_NAME + ## Uncomment this to let players see their own notes (they can still be set by admins only) #SEE_OWN_NOTES diff --git a/config/tips.txt b/config/tips.txt index d7e342157af..c7f7241a456 100644 --- a/config/tips.txt +++ b/config/tips.txt @@ -130,15 +130,19 @@ As an Alien, you take double damage from all burn attacks, such as lasers, weldi As an Alien, resin floors not only regenerate your plasma supply, but also passively heal you. Fight on resin floors to gain a home turf advantage! As an Alien, the facehugger is by far your most powerful weapon because of its ability to instantly win a fight. Remember however that certain helmets, such as biohoods or space helmets will completely block facehugger attacks. As an Alien, you are unable to pick up or use any human items or machinery. Instead, you should focus on sabotaging APCs, computers, cameras and either stowing, spacing, or melting any weapons you find. -As the Blob, you will spawn from your character from between a minute to 5 minutes after the round starts. Use this time to find a safe and well hidden location and evaluate where you will strike! -As the Blob, you can do various sabotage before you spawn, such as spacing the armory or disabling R&D. +When fighting the Blob, you can hit it with an analyzer to check its chemical effects and the type of blob analyzed. Examining it with a research scanner active will also reveal this information. +As the Blob, you can place your core at any clear, unobserved, spot you can move to after 3 minutes have passed. If you wait too long, you will be automatically placed at a random location. Use this wait time to coordinate with any other overminds. As the Blob, keep your core some distance from space, as it is both expensive to expand onto space, easy to be attacked from, and does not count towards your win condition. Emitter platforms built in space are especially dangerous. As the Blob, you can randomly repick your reagent type if the crew has adapted and protected themselves against your current one. As the Blob, you fight a war of attrition: Take out medbay and fight in chokepoints to prevent continued assaults and coordinated burst damage attacks! As the Blob, remember that you can only expand onto tiles from cardinal directions, while the crew can attack you diagonally. Fight in narrow corridors or expand and widen across the width of the hallway to force confrontations where you can hit them! As the Blob, don't neglect the creation of factories. These create spores that carry your reagent and can chase crewmembers far further than you. Spores can also be rallied to swarm the crew and cause panic, and can even take over corpses to create much more dangerous blob zombies! +As the Blob, you can produce a Blobbernaut from a factory for 40 resources. Blobbernauts are smart, gradually regenerate near nodes, and apply your chemical when attacking, but die when too far from the blob or if their factory is killed. However, the factory used becomes fragile and stops spawning spores. As the Blob, you can expand by clicking, create strong blobs with ctrl-click, rally spores with middle-click, and remove blobs with alt-click. -As the Blob, removing strong blobs, resource nodes, factories, and nodes will give you 2, 15, 25, and 25 resources back, respectively. +As the Blob, removing strong blobs, resource nodes, factories, and nodes will give you 4, 15, 25, and 25 resources back, respectively. +As the Blob, talking will send a message to all other overminds and all Blobbernauts, allowing you to direct attacks and coordinate. +As a Blobbernaut, you can communicate with overminds and other Blobbernauts via :b. +As a Blobbernaut, your HUD shows your health and the core health of the overmind that created you. As a Revolutionary, you cannot convert a head of staff or someone who has a loyalty implant, such as a security officer or those they implant. Implants can however be surgically removed, and do not carry over with cloning. Take control of medbay to keep control of conversions! As a Revolutionary, cargo can be your best friend or your worst nightmare. In the best case scenario you will be able to order a limitless amount of guns and armor, in the worst case scenario security will take control and order a limitless number of loyalty implants to turn your fellow revolutionaries against you. As a Revolutionary, your main power comes from how quickly you spread. Convert people as fast as you can and overwhelm the heads of staff before security can arm up. diff --git a/html/changelog.html b/html/changelog.html index dec2902c511..c30bb82c7f1 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -55,17 +55,149 @@ -->
+

07 May 2016

+

Robustin updated:

+
    +
  • A small pantry has been added to SW maintenance.
  • +
+

nullbear updated:

+
    +
  • Makes Shift+Middleclick the hotkey for pointing.
  • +
+

phil235 updated:

+
    +
  • DISMEMBERMENT! Humans can now lose their bodyparts. Explosions and being attacked with a heavy sharp item on a specific bodypart can cause dismemberment.
  • +
  • You can't be handcuffed or legcuffed if you're missing an arm or leg. You can't use items when you have no legs, your arms are too busy helping you crawl, unless your are buckled to a chair. You're slower when missing a leg.
  • +
  • You lose organs and items if the bodypart they are inside gets cut off. You can always retrieve them by cutting the dropped bodypart with a sharp object.
  • +
  • Medbay can replace your missing limbs with robotic parts via surgery, or amputate you.
  • +
  • Changelings do not die when decapitated! They can regrow all their limbs with Fleshmend, or just one arm with Arm Blade or Organic Shield.
  • +
  • Your chest cannot be dropped, but it will spill its organs onto the ground when dismembered.
  • +
+ +

05 May 2016

+

Joan updated:

+
    +
  • Revenants are slower while revealed.
  • +
  • Revenants can no longer cast inside dense objects.
  • +
  • Lying down will cure Blight much, much faster.
  • +
+

\"Macho Man\" Randy Savage updated:

+
    +
  • OOOHHH YEAAAAHHHH
  • +
  • SNAP INTO A JLIM SIM WITH THE ALL NEW WRESTLING BELT
  • +
  • YOU CAN FREAKOUT YOUR OPPONENTS WITH THE 5 HOT MOVES ON THIS BELT YEAH
  • +
  • PRAY TO THE LOCAL SPACE GODS TO EXCHANGE YOUR TELECRYSTALS TO ENSURE THE CREAM RISES TO THE TOP
  • +
+ +

04 May 2016

+

Fox McCloud updated:

+
    +
  • shock revolver projectiles are now energy instead of bullets
  • +
+

Joan updated:

+
    +
  • Cultists no longer communicate via tomes.
  • +
  • Cultists now communicate via the 'Communion' action button.
  • +
  • Examining the blob with an active research scanner or medical hud will display effects, akin to hitting it with an analyzer.
  • +
  • Improved medical HUDs to work on all living creatures.
  • +
  • Drones and swarmers, being machines, require a diagnostic HUD for analysis instead.
  • +
+

TechnoAlchemist updated:

+
    +
  • You can now craft cloaks from the scales of fallen ash drakes, look for the recipe in tablecrafting!
  • +
+

coiax updated:

+
    +
  • The Service and the Standard cyborg module now have a spraycan built in, for hijinks and passing on important urban messages. The Service cyborg module also has a cyborg-hand labeler, in case anything needs to be labelled.
  • +
  • Centcom Suicide Prevention wishes to remind the station: Please do not kill yourself with a hand labeler.
  • +
+

xxalpha updated:

+
    +
  • Fixed the mk-honk prototype shoes.
  • +
+ +

03 May 2016

+

coiax, Robustin updated:

+
    +
  • Changeling Fleshmend is much less effective when used repeatedly in a short time. Changeling Panacea is much more effective at purging reagents, reducing radiation and now reduces braindamage.
  • +
+ +

02 May 2016

+

Joan updated:

+
    +
  • Blob spores spawn from factories 2 seconds faster, but the factory goes on cooldown when any of its spores die.
  • +
  • You can examine tomes, soulstones, and construct shells to see what you can do with them.
  • +
  • Releasing a shade from a soulstone now allows you to reuse that soulstone for capturing shades or souls, instead of preventing the stone's use forever if the shade dies.
  • +
  • Runes now actually pulse red on failure.
  • +
  • The Summon Cultist rune no longer includes the cultists invoking it in the selection menu.
  • +
  • Imperfect Communication renamed to Emergency Communication.
  • +
  • You can no longer hide the Nar-Sie rune with a Talisman of Veiling/Revealing.
  • +
+

Kor updated:

+
    +
  • Engineering cyborgs now have internal blueprints.
  • +
+

Lzimann updated:

+
    +
  • Automatic nexus placing time changed from 2 to 15 minutes.
  • +
  • Prophet's gear(hat and staff) prioritizes the backpack instead of automatically equipping.
  • +
  • Divine telepathy and prophet to god speak now have a follow button for ghosts.
  • +
  • Divine telepathy and prophet to god speak now has the god's color.
  • +
  • CTF spawn protection trap is no longer constructable
  • +
+

Mercenaryblue updated:

+
    +
  • Drastically reduced the chances of eye damage when throwing a paper plane.
  • +
+

RandomMarine updated:

+
    +
  • Medical HUDs improved. To better prioritize patients, subjects deep into critical condition have a blinking red outline around the entire HUD icon, and will blink more rapidly when very close to death.
  • +
+

TechnoAlchemisto updated:

+
    +
  • Security uniforms have been made more professional, and more tactical.
  • +
+

TrustyGun updated:

+
    +
  • By crafting together a legion skull, a goliath steak, ketchup, and capsaicin oil, you can create Stuffed Legion! Be careful, it's hot.
  • +
+

coiax updated:

+
    +
  • Centcom Department of [REDACTED] have announced a change of supplier of [EXPLETIVE DELETED]. As such, for security reasons, the absinthe [MOVE ALONG CITIZEN] will instead be [NOTHING TO SEE HERE]. We hope that this will not affect the performance of the [INFORMATION ABOVE YOUR SECURITY CLEARANCE].
  • +
+

nullbear updated:

+
    +
  • A reminder for crew to avoid mopping floors in cold rooms, as the water will freeze and provide a dangerous slipping hazard known as 'ice'. Running on it is not recommended.
  • +
  • Frostoil is an effective chemical for rapidly cooling areas in the event of a fire.
  • +
  • Added X4, a breaching charge more destructive than C4, it can be purchased from uplinks.
  • +
  • C4 can be used with assemblies.
  • +
  • Fixes chembomb recipe to use any matter bin. Again.
  • +
  • ARG's disappear once finished reacting.
  • +
+

30 April 2016

Joan updated:

  • Blobs attempting to attack the supermatter will instead be eaten by it.
  • This doesn't mean throwing a supermatter shard at the blob is a good idea; blobs attacking it will gradually damage it, eventually resulting in a massive explosion, and it will not consume blobs if on a space turf.
  • +
  • Hitting a locker or crate with an ID, PDA with ID, or wallet with ID will try to toggle the lock instead of trying to open it.
  • +
  • Cable coils, cablecuffs, and zipties now all have properly colored inhands.
  • +
+

Kor updated:

+
    +
  • Megafauna have been added to lavaland.
  • +
  • Ash Drakes have been spotted roaming the wastes. Use your GPS to track their fiery signals.
  • +
  • You can now knock on the Necropolis door, but it's probably best that you don't.

Mercenaryblue updated:

  • Adds a basic paper plane to the game. Fold paper with alt-clicking.
  • Paper planes are now fully compatible with every stamps on station.
+

bgobandit updated:

+
    +
  • Nanotrasen has released Cards Against Spess! Visit your local library for a copy. Warning: may cause breakage of the fourth wall.
  • +

29 April 2016

Bawhoppen updated:

@@ -448,154 +580,6 @@
  • A working drone shell dispenser is now on display in MetaStation's museum, displaying the virtue of the tireless little workers!
  • Dreamstation now has a drone shell dispenser in the Toxins Launch Room
  • - -

    09 April 2016

    -

    GunHog updated:

    -
      -
    • Aliens may now force open unbolted, unwelded airlocks. Unpowered airlocks open faster than powered ones. Has a cool sound provided by @Ultimate-Chimera!
    • -
    • Alien Drone health increased to 125 hp.
    • -
    • Alien drone is now faster!
    • -
    • Alien egg and larva maturation times halved.
    • -
    • Resin membrane health increased to 160 hp.
    • -
    • Aliens may now open firelocks.
    • -
    • Aliens may now unweld scrubbers and vents. (From the outside!)
    • -
    • Droppers no longer affect aliens.
    • -
    -

    Joan updated:

    -
      -
    • You can no longer drop survival capsules on top of dense objects, such as the windows in the emergency shuttle. You can still drop them on non-dense objects and mobs, however.
    • -
    • Swarmers can now deconstruct objects simply by clicking.
    • -
    • Swarmers can still teleport mobs away via ctrl-click.
    • -
    • Emps will now properly damage swarmers.
    • -
    -

    Kor updated:

    -
      -
    • Added wisp lanterns to necropolis chests.
    • -
    • Added red/blue cube pairs to necropolis chests.
    • -
    • Added meat hooks to necropolis chests.
    • -
    • Added immortality talismans to necropolis chests.
    • -
    • Added paradox bags to necropolis chests.
    • -
    • Ripley drills work again. Go tear up lavaland.
    • -
    -

    PKPenguin321 updated:

    -
      -
    • Goofball's grab nerf has been reverted.
    • -
    -

    TechnoAlchemisto updated:

    -
      -
    • Pickaxe upgrades are now better.
    • -
    -

    coiax updated:

    -
      -
    • Efficiency Station Testing Lab now has a Drone Shell Dispenser
    • -
    • Fixed an issue with a door on the Golem Ship
    • -
    • The unfathomable entity Carp'sie has blessed vir followers with mysterious carp guardians.
    • -
    • Nanotrasen Cyborgs are now able to empty ore boxes without human assistance
    • -
    • Ore boxes are now craftable with 4 planks of wood
    • -
    • Ore boxes now drop their contents when destroyed, or dismantled with a crowbar
    • -
    -

    coiax, bobdobbington, Core0verload updated:

    -
      -
    • An experimental plant DNA manipulator, based on machinery recovered from ancient seed vaults, has been installed in the Botany department.
    • -
    - -

    07 April 2016

    -

    Kor updated:

    -
      -
    • The Laser Cannon in RD has been replaced with the Accelerator Laser Cannon. Try it out!
    • -
    • Mechas now have armour facings. Attacking the front will deal far less damage, while attacking the back will deal massive bonus damage.
    • -
    • EMPs now deal far less damage/drain to mechas.
    • -
    -

    Kor and Ausops updated:

    -
      -
    • Survival pod interiors have been redone.
    • -
    • Survival pods now contain a stationary GPS computer.
    • -
    • You can now toggle your GPS off with alt+click.
    • -
    -

    bgobandit updated:

    -
      -
    • Due to budget cuts, Nanotrasen is no longer utilizing copy-protected paper for its classified documents. Fortunately, our world-class security team has always prevented any thefts or photocopies from being made!
    • -
    • Secret documents can be photocopied. If you have an objective to steal any set of documents, a photocopy will be accepted. If you must steal red or blue documents, a photocopy will NOT be accepted. Enterprising traitors can forge the red/blue seal with a crayon to take advantage of this.
    • -
    - -

    06 April 2016

    -

    CoreOverload updated:

    -
      -
    • You can now put slimes in stasis by exposing them to room temp CO2. Useful for both fighting the slimes and safely storing them.
    • -
    -

    Erwgd updated:

    -
      -
    • The autolathe can now make hydroponics tools! Access the design routines in the Misc. category of the machine.
    • -
    -

    LanCartwright updated:

    -
      -
    • Custom viruses with stealth values of 3 or above are now invisible on the PANDEMIC and no longer visible on health huds.
    • -
    -

    MrStonedOne updated:

    -
      -
    • Centcom is happy to report that our single sided windows and our windoors should once again create an airtight seal.
    • -
    -

    bgobandit updated:

    -
      -
    • Honk! Nanotrasen's clowning and development department has invented the clown megaphone, standard in all clowning loadouts! Honk honk!
    • -
    - -

    05 April 2016

    -

    Erwgd updated:

    -
      -
    • Utility belts of all kinds can now accept gloves. Most belts, except janitorial belts, may now also hold station bounced radios.
    • -
    • Hazard vests and most jackets can carry a station bounced radio as well. Labcoats can be used to store a handheld crew monitor.
    • -
    • The autolathe can now make toolboxes.
    • -
    -

    Joan updated:

    -
      -
    • Adds protector holoparasites to traitor holoparasite injectors.
    • -
    • Protector holoparasites cause the summoner to teleport to them when out of range, instead of the other way around.
    • -
    • Protector holoparasites have two modes; Combat, where they do and take medium damage, and Protection, where they do and take almost no damage, but move slightly slower.
    • -
    • Explosive Holoparasites no longer teleport non-mobs when attacking, but have a higher chance to teleport mobs.
    • -
    • Explosive Holoparasite bombs no longer trigger on their summoner or any other parasites their summoner has.
    • -
    • Ranged Holoparasites no longer have nightvision active by default. It can still be toggled on.
    • -
    • Ranged Holoparasite snares no longer alert if the crossing mob is their summoner or one of the parasites their summoner has.
    • -
    • Ranged Holoparasites are slightly less visible in scout mode.
    • -
    • Standard Holoparasites attack 20% faster than other parasite types.
    • -
    • Support Holoparasite beacons no longer require safe atmospheric conditions, but the warp channel takes slightly longer, and is preceded with a visible message.
    • -
    • Zombies can no longer destroy more than one airlock at a time.
    • -
    • The mining station has been updated.
    • -
    -

    MrStonedOne updated:

    -
      -
    • Centcom is glad to announce the end of sending workers to our control group for space exposure testing, a fake station in "space" that noticeably had air in "space".
    • -
    -

    TechnoAlchemisto updated:

    -
      -
    • Detective scanners are now smaller.
    • -
    • Pickaxes now fit in explorer suit exosuit slots.
    • -
    -

    bgobandit updated:

    -
      -
    • Alt-clicking a fire extinguisher cabinet opens and closes it. That is all.
    • -
    - -

    04 April 2016

    -

    TechnoAlchemisto updated:

    -
      -
    • The recipes for some Trekchems are now back in the game
    • -
    • Bicaridine can be made with carbon, oxygen, and sugar.
    • -
    • Kelotane can be made with silicon and carbon.
    • -
    • Antitoxin can be made with nitrogen, silicon, and potassium
    • -
    • tricordrazine can be made by combining all three.
    • -
    - -

    03 April 2016

    -

    Erwgd updated:

    -
      -
    • Our valued colleagues in the security department are reminded to search boots for hidden items (such as knives or syringes) as part of standard search procedures. Alt-click a pair of boots to remove any hidden items.
    • -
    -

    Isratosh updated:

    -
      -
    • Fixed rudimentary transform not working properly on ghosts with minds.
    • -
    • Admin logs for bluespace capsules not activated on the mining Z level.
    • -
    GoonStation 13 Development Team diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml index 94109b63f59..c76b5b48f66 100644 --- a/html/changelogs/.all_changelog.yml +++ b/html/changelogs/.all_changelog.yml @@ -4788,6 +4788,126 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py. - experiment: This doesn't mean throwing a supermatter shard at the blob is a good idea; blobs attacking it will gradually damage it, eventually resulting in a massive explosion, and it will not consume blobs if on a space turf. + - tweak: Hitting a locker or crate with an ID, PDA with ID, or wallet with ID will + try to toggle the lock instead of trying to open it. + - imageadd: Cable coils, cablecuffs, and zipties now all have properly colored inhands. + Kor: + - rscadd: Megafauna have been added to lavaland. + - rscadd: Ash Drakes have been spotted roaming the wastes. Use your GPS to track + their fiery signals. + - rscadd: You can now knock on the Necropolis door, but it's probably best that + you don't. Mercenaryblue: - rscadd: Adds a basic paper plane to the game. Fold paper with alt-clicking. - rscadd: Paper planes are now fully compatible with every stamps on station. + bgobandit: + - rscadd: 'Nanotrasen has released Cards Against Spess! Visit your local library + for a copy. Warning: may cause breakage of the fourth wall.' +2016-05-02: + Joan: + - tweak: Blob spores spawn from factories 2 seconds faster, but the factory goes + on cooldown when any of its spores die. + - experiment: You can examine tomes, soulstones, and construct shells to see what + you can do with them. + - rscadd: Releasing a shade from a soulstone now allows you to reuse that soulstone + for capturing shades or souls, instead of preventing the stone's use forever + if the shade dies. + - imageadd: Runes now actually pulse red on failure. + - rscadd: The Summon Cultist rune no longer includes the cultists invoking it in + the selection menu. + - tweak: Imperfect Communication renamed to Emergency Communication. + - rscdel: You can no longer hide the Nar-Sie rune with a Talisman of Veiling/Revealing. + Kor: + - rscadd: Engineering cyborgs now have internal blueprints. + Lzimann: + - tweak: Automatic nexus placing time changed from 2 to 15 minutes. + - tweak: Prophet's gear(hat and staff) prioritizes the backpack instead of automatically + equipping. + - rscadd: Divine telepathy and prophet to god speak now have a follow button for + ghosts. + - rscadd: Divine telepathy and prophet to god speak now has the god's color. + - bugfix: CTF spawn protection trap is no longer constructable + Mercenaryblue: + - tweak: Drastically reduced the chances of eye damage when throwing a paper plane. + RandomMarine: + - tweak: Medical HUDs improved. To better prioritize patients, subjects deep into + critical condition have a blinking red outline around the entire HUD icon, and + will blink more rapidly when very close to death. + TechnoAlchemisto: + - tweak: Security uniforms have been made more professional, and more tactical. + TrustyGun: + - rscadd: By crafting together a legion skull, a goliath steak, ketchup, and capsaicin + oil, you can create Stuffed Legion! Be careful, it's hot. + coiax: + - rscadd: Centcom Department of [REDACTED] have announced a change of supplier of + [EXPLETIVE DELETED]. As such, for security reasons, the absinthe [MOVE ALONG + CITIZEN] will instead be [NOTHING TO SEE HERE]. We hope that this will not affect + the performance of the [INFORMATION ABOVE YOUR SECURITY CLEARANCE]. + nullbear: + - rscadd: A reminder for crew to avoid mopping floors in cold rooms, as the water + will freeze and provide a dangerous slipping hazard known as 'ice'. Running + on it is not recommended. + - rscadd: Frostoil is an effective chemical for rapidly cooling areas in the event + of a fire. + - rscadd: Added X4, a breaching charge more destructive than C4, it can be purchased + from uplinks. + - rscadd: C4 can be used with assemblies. + - bugfix: Fixes chembomb recipe to use any matter bin. Again. + - bugfix: ARG's disappear once finished reacting. +2016-05-03: + coiax, Robustin: + - tweak: Changeling Fleshmend is much less effective when used repeatedly in a short + time. Changeling Panacea is much more effective at purging reagents, reducing + radiation and now reduces braindamage. +2016-05-04: + Fox McCloud: + - tweak: shock revolver projectiles are now energy instead of bullets + Joan: + - rscdel: Cultists no longer communicate via tomes. + - rscadd: Cultists now communicate via the 'Communion' action button. + - rscadd: Examining the blob with an active research scanner or medical hud will + display effects, akin to hitting it with an analyzer. + - rscadd: Improved medical HUDs to work on all living creatures. + - rscadd: Drones and swarmers, being machines, require a diagnostic HUD for analysis + instead. + TechnoAlchemist: + - rscadd: You can now craft cloaks from the scales of fallen ash drakes, look for + the recipe in tablecrafting! + coiax: + - rscadd: The Service and the Standard cyborg module now have a spraycan built in, + for hijinks and passing on important urban messages. The Service cyborg module + also has a cyborg-hand labeler, in case anything needs to be labelled. + - rscadd: 'Centcom Suicide Prevention wishes to remind the station: Please do not + kill yourself with a hand labeler.' + xxalpha: + - bugfix: Fixed the mk-honk prototype shoes. +2016-05-05: + Joan: + - tweak: Revenants are slower while revealed. + - rscdel: Revenants can no longer cast inside dense objects. + - tweak: Lying down will cure Blight much, much faster. + \"Macho Man\" Randy Savage: + - rscadd: OOOHHH YEAAAAHHHH + - rscadd: SNAP INTO A JLIM SIM WITH THE ALL NEW WRESTLING BELT + - rscadd: YOU CAN FREAKOUT YOUR OPPONENTS WITH THE 5 HOT MOVES ON THIS BELT YEAH + - rscadd: PRAY TO THE LOCAL SPACE GODS TO EXCHANGE YOUR TELECRYSTALS TO ENSURE THE + CREAM RISES TO THE TOP +2016-05-07: + Robustin: + - rscadd: A small pantry has been added to SW maintenance. + nullbear: + - rscadd: Makes Shift+Middleclick the hotkey for pointing. + phil235: + - rscadd: DISMEMBERMENT! Humans can now lose their bodyparts. Explosions and being + attacked with a heavy sharp item on a specific bodypart can cause dismemberment. + - rscadd: You can't be handcuffed or legcuffed if you're missing an arm or leg. + You can't use items when you have no legs, your arms are too busy helping you + crawl, unless your are buckled to a chair. You're slower when missing a leg. + - rscadd: You lose organs and items if the bodypart they are inside gets cut off. + You can always retrieve them by cutting the dropped bodypart with a sharp object. + - rscadd: Medbay can replace your missing limbs with robotic parts via surgery, + or amputate you. + - rscadd: Changelings do not die when decapitated! They can regrow all their limbs + with Fleshmend, or just one arm with Arm Blade or Organic Shield. + - rscadd: Your chest cannot be dropped, but it will spill its organs onto the ground + when dismembered. diff --git a/html/changelogs/AutoChangeLog-pr-15872.yml b/html/changelogs/AutoChangeLog-pr-15872.yml deleted file mode 100644 index e8006c6be50..00000000000 --- a/html/changelogs/AutoChangeLog-pr-15872.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: bgobandit -delete-after: True -changes: - - rscadd: "Nanotrasen has released Cards Against Spess! Visit your local library for a copy. Warning: may cause breakage of the fourth wall." diff --git a/html/changelogs/AutoChangeLog-pr-17018.yml b/html/changelogs/AutoChangeLog-pr-17018.yml deleted file mode 100644 index a6b4149e70f..00000000000 --- a/html/changelogs/AutoChangeLog-pr-17018.yml +++ /dev/null @@ -1,6 +0,0 @@ -author: Kor -delete-after: True -changes: - - rscadd: "Megafauna have been added to lavaland." - - rscadd: "Ash Drakes have been spotted roaming the wastes. Use your GPS to track their fiery signals." - - rscadd: "You can now knock on the Necropolis door, but it's probably best that you don't." diff --git a/html/changelogs/AutoChangeLog-pr-17224.yml b/html/changelogs/AutoChangeLog-pr-17224.yml deleted file mode 100644 index c657ab9f167..00000000000 --- a/html/changelogs/AutoChangeLog-pr-17224.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: Joan -delete-after: True -changes: - - tweak: "Hitting a locker or crate with an ID, PDA with ID, or wallet with ID will try to toggle the lock instead of trying to open it." diff --git a/html/changelogs/AutoChangeLog-pr-17262.yml b/html/changelogs/AutoChangeLog-pr-17262.yml deleted file mode 100644 index 76ab51f12e2..00000000000 --- a/html/changelogs/AutoChangeLog-pr-17262.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: Joan -delete-after: True -changes: - - imageadd: "Cable coils, cablecuffs, and zipties now all have properly colored inhands." diff --git a/html/changelogs/__CHANGELOG_README.txt b/html/changelogs/__CHANGELOG_README.txt index b15854c38ac..048d67d3d21 100644 --- a/html/changelogs/__CHANGELOG_README.txt +++ b/html/changelogs/__CHANGELOG_README.txt @@ -4,6 +4,8 @@ Changelogs are included with commits as text .yml files created individually by TO MAKE A CHANGELOG .YML ENTRRY +0. Consider carefully if a change you make really needs a changelog, and if it does how many lines should be dedicated to it. A set of changes with no forward facing player effects like a refactor almost certainly doesn't need a changelog, nor does something that makes itself obvious during the normal course of play like adding an action button to an item players already commonly pick up. Likewise if you DO need a changelog consider packaging similar changes under a generalized line instead of listing out every little change as its own thing. Only you can prevent changelog clutter. + 1. Make a copy of the file example.yml in html/changelogs and rename it to [YOUR USERNAME]-PR-[YOUR PR NUMBER].yml (the pr and pr number are organizational and can be ignored if you so wish) 2. Change the author to yourself diff --git a/icons/effects/genetics.dmi b/icons/effects/genetics.dmi index 768be9b9231..2a4c02d38f3 100644 Binary files a/icons/effects/genetics.dmi and b/icons/effects/genetics.dmi differ diff --git a/icons/mob/actions.dmi b/icons/mob/actions.dmi index 7dee0928ecb..365d550bce6 100644 Binary files a/icons/mob/actions.dmi and b/icons/mob/actions.dmi differ diff --git a/icons/mob/animal.dmi b/icons/mob/animal.dmi index 1d56a4924ae..868c2204346 100644 Binary files a/icons/mob/animal.dmi and b/icons/mob/animal.dmi differ diff --git a/icons/mob/augments.dmi b/icons/mob/augments.dmi index 0600a4fb669..2b7239ba1a9 100644 Binary files a/icons/mob/augments.dmi and b/icons/mob/augments.dmi differ diff --git a/icons/mob/head.dmi b/icons/mob/head.dmi index fdbbd87d11d..0b021fb071a 100644 Binary files a/icons/mob/head.dmi and b/icons/mob/head.dmi differ diff --git a/icons/mob/hud.dmi b/icons/mob/hud.dmi index 2c4309a7893..80fd29fbd21 100644 Binary files a/icons/mob/hud.dmi and b/icons/mob/hud.dmi differ diff --git a/icons/mob/human_parts.dmi b/icons/mob/human_parts.dmi new file mode 100644 index 00000000000..01cec19a8b2 Binary files /dev/null and b/icons/mob/human_parts.dmi differ diff --git a/icons/mob/human_parts_greyscale.dmi b/icons/mob/human_parts_greyscale.dmi new file mode 100644 index 00000000000..e6a22fd6649 Binary files /dev/null and b/icons/mob/human_parts_greyscale.dmi differ diff --git a/icons/mob/lavaland/lavaland_monsters.dmi b/icons/mob/lavaland/lavaland_monsters.dmi index b7808452186..8cf32385df3 100644 Binary files a/icons/mob/lavaland/lavaland_monsters.dmi and b/icons/mob/lavaland/lavaland_monsters.dmi differ diff --git a/icons/mob/mob.dmi b/icons/mob/mob.dmi index 05cb8392c08..116fbe4090c 100644 Binary files a/icons/mob/mob.dmi and b/icons/mob/mob.dmi differ diff --git a/icons/mob/mutant_bodyparts.dmi b/icons/mob/mutant_bodyparts.dmi index 108699d328c..518a57469e5 100644 Binary files a/icons/mob/mutant_bodyparts.dmi and b/icons/mob/mutant_bodyparts.dmi differ diff --git a/icons/mob/screen_gen.dmi b/icons/mob/screen_gen.dmi index 9c5ae1a2043..ccc65f2bd92 100644 Binary files a/icons/mob/screen_gen.dmi and b/icons/mob/screen_gen.dmi differ diff --git a/icons/mob/suit.dmi b/icons/mob/suit.dmi index 11f55cbc902..cce17c5a3fb 100644 Binary files a/icons/mob/suit.dmi and b/icons/mob/suit.dmi differ diff --git a/icons/mob/uniform.dmi b/icons/mob/uniform.dmi index ddd23b6a127..b1bce203efe 100644 Binary files a/icons/mob/uniform.dmi and b/icons/mob/uniform.dmi differ diff --git a/icons/obj/apc_repair.dmi b/icons/obj/apc_repair.dmi index 8f66aa27c86..220a267fe7a 100644 Binary files a/icons/obj/apc_repair.dmi and b/icons/obj/apc_repair.dmi differ diff --git a/icons/obj/assemblies.dmi b/icons/obj/assemblies.dmi index 5a8719da0d8..6a862a263a8 100644 Binary files a/icons/obj/assemblies.dmi and b/icons/obj/assemblies.dmi differ diff --git a/icons/obj/clothing/hats.dmi b/icons/obj/clothing/hats.dmi index f7a82035102..9a1f8fc08e1 100644 Binary files a/icons/obj/clothing/hats.dmi and b/icons/obj/clothing/hats.dmi differ diff --git a/icons/obj/clothing/suits.dmi b/icons/obj/clothing/suits.dmi index b44076fdda4..623836f5898 100644 Binary files a/icons/obj/clothing/suits.dmi and b/icons/obj/clothing/suits.dmi differ diff --git a/icons/obj/clothing/uniforms.dmi b/icons/obj/clothing/uniforms.dmi index ec6e57938d5..540b32b193a 100644 Binary files a/icons/obj/clothing/uniforms.dmi and b/icons/obj/clothing/uniforms.dmi differ diff --git a/icons/obj/food/food.dmi b/icons/obj/food/food.dmi index 20fcc6a2450..956304f1fba 100644 Binary files a/icons/obj/food/food.dmi and b/icons/obj/food/food.dmi differ diff --git a/icons/obj/grenade.dmi b/icons/obj/grenade.dmi index e17974ecd19..4e38271e7ee 100644 Binary files a/icons/obj/grenade.dmi and b/icons/obj/grenade.dmi differ diff --git a/icons/obj/lavaland/artefacts.dmi b/icons/obj/lavaland/artefacts.dmi index 966dae264b1..a99a667bc59 100644 Binary files a/icons/obj/lavaland/artefacts.dmi and b/icons/obj/lavaland/artefacts.dmi differ diff --git a/icons/obj/mining.dmi b/icons/obj/mining.dmi index 28259f75fc5..11f388bc1af 100644 Binary files a/icons/obj/mining.dmi and b/icons/obj/mining.dmi differ diff --git a/icons/obj/surgery.dmi b/icons/obj/surgery.dmi index eb2bdb2f5c7..916d550ce23 100644 Binary files a/icons/obj/surgery.dmi and b/icons/obj/surgery.dmi differ diff --git a/sound/effects/pai_boot.ogg b/sound/effects/pai_boot.ogg new file mode 100644 index 00000000000..058866475c5 Binary files /dev/null and b/sound/effects/pai_boot.ogg differ diff --git a/sound/misc/desceration-01.ogg b/sound/misc/desceration-01.ogg new file mode 100644 index 00000000000..29bc568c575 Binary files /dev/null and b/sound/misc/desceration-01.ogg differ diff --git a/sound/misc/desceration-02.ogg b/sound/misc/desceration-02.ogg new file mode 100644 index 00000000000..761a73a7b9f Binary files /dev/null and b/sound/misc/desceration-02.ogg differ diff --git a/sound/misc/desceration-03.ogg b/sound/misc/desceration-03.ogg new file mode 100644 index 00000000000..876de18de50 Binary files /dev/null and b/sound/misc/desceration-03.ogg differ diff --git a/sound/misc/splort.ogg b/sound/misc/splort.ogg new file mode 100644 index 00000000000..c7990454446 Binary files /dev/null and b/sound/misc/splort.ogg differ diff --git a/strings/cas_black.txt b/strings/cas_black.txt index dec808fa46a..a3274c5be44 100644 --- a/strings/cas_black.txt +++ b/strings/cas_black.txt @@ -19,6 +19,7 @@ What's the Captain's fetish? ___________: more robust than a toolbox to the head! ________ is the crew's friend. Would you abandon a friend? _______ tastes good like a ________ should. +How did the detective conduct a successful interrogation? New in syndicate uplinks: __________! NanoTrasen's labor union decided to use _______ to raise employee morale. The Chemist's drug of choice is ______ @@ -26,6 +27,7 @@ According to space law, ________ is now punishable by ______. ________ is why I'm afraid of maintenance. ________ is the most robust person on the station. What made the nuclear operatives fluke? +Why did the Chief Engineer disable comms? Every spaceman receives an internals box and ________. What brought the space orgy to a grinding halt? Scientists are no longer allowed to make _____. @@ -50,15 +52,20 @@ My lizard name is _____-And-_____. What can solve any station crisis? The traitorous atmos tech slowly replaced the station's air with ________. _______ and _______ were found together in the dorms. +What's the Syndicate's real beef with Nanotrasen? What finally killed the Head of Security? +Code Delta: __________ has escaped containment! The rogue virologist released a disease with symptoms of __________ and ______. How do you drive an assistant to suicide? +With no chef on board, the crew was reduced to eating ________. Why was the emergency shuttle called? In the future, all ERP will involve ____________. Law 2 is not to be used for __________! What really goes on in the Prisoner Transfer Center? What will get you bluespace artilleried every time? This isn't omnizine, it's _________! +What's stopping the Space Station 13 remake? +When they make a movie about Space Station 13, they better include________. What's the worst thing an abductor can give you? One day while Andy was __________, Woody got _________. A good engineer always carries ________. @@ -85,6 +92,7 @@ The chaplain stopped performing marriages after seeing ___________. The gods were too busy with _______ to respond to _______. The Roboticist was fired after naming the borgs ______ and _________. What's funnier than a dead clown? +What made the mime speak? How do you get an assistant to assist? What was I last brigged for? Why does Security no longer use the gulag? diff --git a/strings/cas_white.txt b/strings/cas_white.txt index 45a38d2c2fa..4e5e920a959 100644 --- a/strings/cas_white.txt +++ b/strings/cas_white.txt @@ -12,12 +12,14 @@ A catsplosion. Mime porn. That fukken disk. G-g-g-ghosts! +A PDA shaped like a set of breasts. Woody-chan. Meaty ores. Yet another explosion in Toxins. The Captain thinking they're a badass. Mech bumper cars. Purrbation. +Baymed. Being in a cult. Racially biased lawsets. Abusing Law 2 to get laid. @@ -39,11 +41,13 @@ The grey tide. ASS BLAST USA. Fucking plasmamen. Lavaland. +Chainsaws for hands. Photocopies of the entire crew's asses. Venus human traps. Clown's Tears. Walking mushroom cockfights. Greentext. +Coating the whole station in blood. Defusing a syndicate bomb with another bomb. A petsplosion. Meat spikes. @@ -71,7 +75,7 @@ Cablecuffs. Hulk, TK and X-Ray. Paranoia. ERP-seeking meteors. -Paperwork Nazi HoPs. +Paperwork HoPs. A sexy clown. Rampant vending machines. The prisoner transfer center. @@ -88,14 +92,19 @@ Inviting all the lizards onto the holodeck for a party. A used corgi suit. Saxing. Carbon dioxide. +Lewd alien abduction. Warm donk pockets. Fucking your own cloned body. +MULEbot manslaughter. Hiding in a locker like a little bitch. Tabling. Gyrating slimes. A motherfucking sorcerer. Ash storms. Telescience. +Anatomically correct borgs. +The dixel. +Friendly neighborhood death squads. Rage cages. Lore that no one will read. A robust mongoloid. @@ -119,6 +128,8 @@ Six max-cap bombs. Xenos pleasuring their victims with anal. Forgetting you're a traitor. Itching powder. +Some overpowered bullshit. +Griff. Ash walkers. A fascist captain. FREE DRONE. @@ -134,6 +145,7 @@ Immulsions. The crotchety IBM piece of shit you're supposed to call an AI. An irritatingly chipper borg. The lizard fuckpile. +Fat sprites. The throbbing erection that the HoS gets at the thought of shooting something. Trying to stab someone and hugging them instead. Buttbots. @@ -142,6 +154,7 @@ The spread-eagled Honkmother. A disposal loop full of corpses. Assistant-on-assistant violence. The mystery of atmos. +PDA sexting. A cult rune drawn with menstrual blood. Magic missile spam. Double dongs. @@ -187,13 +200,16 @@ Farting in the air distro loop. Krokodil addiction. A H.O.N.K. mech. A dominatrix HoS. +Sexcurity. The Experimentor. That goddamn fucking mime. Actually taking a hostage instead of just murdering them. Spacing the clown at shift start. A rage suicide. +The Warden furiously masturbating to the prison monitor. Welderbombing. Validhunting. +Nar'Sie making love to Lord Singulo. Fun. Crashing the stock market. HONK! @@ -202,6 +218,7 @@ A defective comdom. Cleanbot. A beaker of dried space carp penis. voxtest2. +Nuking it from orbit. Harmbatonning. A Nanotrasen D-Notice. TALKING MIMES. @@ -209,6 +226,7 @@ The lusty xenomorph maid, Using assistants as human shields. Sentient securitrons. Decorative C4. +A universal recorder endlessly reciting porn. The suicide HoPline. Cultism. A corgi orgy. @@ -228,6 +246,7 @@ Writing out Woody's Got Wood in crayon. Begging the gods for free stuff. Whining to the gods after getting robusted. Committing sudoku. +A blood-soaked clown popping out of a morgue tray. SS13's toxic community. Wheelchair Ian. An actually helpful assistant. diff --git a/tgstation.dme b/tgstation.dme index 5724aef0ac7..89188803d3c 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -223,6 +223,7 @@ #include "code\datums\helper_datums\teleport.dm" #include "code\datums\helper_datums\topic_input.dm" #include "code\datums\martial\krav_maga.dm" +#include "code\datums\martial\wrestling.dm" #include "code\datums\wires\airalarm.dm" #include "code\datums\wires\airlock.dm" #include "code\datums\wires\apc.dm" @@ -299,6 +300,7 @@ #include "code\game\gamemodes\changeling\powers\tiny_prick.dm" #include "code\game\gamemodes\changeling\powers\transform.dm" #include "code\game\gamemodes\cult\cult.dm" +#include "code\game\gamemodes\cult\cult_comms.dm" #include "code\game\gamemodes\cult\cult_items.dm" #include "code\game\gamemodes\cult\cult_structures.dm" #include "code\game\gamemodes\cult\ritual.dm" @@ -469,6 +471,7 @@ #include "code\game\mecha\mech_bay.dm" #include "code\game\mecha\mech_fabricator.dm" #include "code\game\mecha\mecha.dm" +#include "code\game\mecha\mecha_actions.dm" #include "code\game\mecha\mecha_construction_paths.dm" #include "code\game\mecha\mecha_control_console.dm" #include "code\game\mecha\mecha_defense.dm" @@ -643,6 +646,7 @@ #include "code\game\objects\items\weapons\grenades\flashbang.dm" #include "code\game\objects\items\weapons\grenades\ghettobomb.dm" #include "code\game\objects\items\weapons\grenades\grenade.dm" +#include "code\game\objects\items\weapons\grenades\plastic.dm" #include "code\game\objects\items\weapons\grenades\smokebomb.dm" #include "code\game\objects\items\weapons\grenades\spawnergrenade.dm" #include "code\game\objects\items\weapons\grenades\syndieminibomb.dm" @@ -1354,6 +1358,7 @@ #include "code\modules\mob\living\simple_animal\shade.dm" #include "code\modules\mob\living\simple_animal\simple_animal.dm" #include "code\modules\mob\living\simple_animal\spawner.dm" +#include "code\modules\mob\living\simple_animal\status_procs.dm" #include "code\modules\mob\living\simple_animal\bot\bot.dm" #include "code\modules\mob\living\simple_animal\bot\cleanbot.dm" #include "code\modules\mob\living\simple_animal\bot\construction.dm" @@ -1678,6 +1683,7 @@ #include "code\modules\stock_market\logs.dm" #include "code\modules\stock_market\stockmarket.dm" #include "code\modules\stock_market\stocks.dm" +#include "code\modules\surgery\amputation.dm" #include "code\modules\surgery\cavity_implant.dm" #include "code\modules\surgery\core_removal.dm" #include "code\modules\surgery\dental_implant.dm" @@ -1691,19 +1697,22 @@ #include "code\modules\surgery\lipoplasty.dm" #include "code\modules\surgery\organ_manipulation.dm" #include "code\modules\surgery\plastic_surgery.dm" +#include "code\modules\surgery\prosthetic_replacement.dm" #include "code\modules\surgery\remove_embedded_object.dm" #include "code\modules\surgery\surgery.dm" #include "code\modules\surgery\surgery_step.dm" #include "code\modules\surgery\tail_modification.dm" #include "code\modules\surgery\tools.dm" +#include "code\modules\surgery\bodyparts\bodyparts.dm" +#include "code\modules\surgery\bodyparts\dismemberment.dm" +#include "code\modules\surgery\bodyparts\head.dm" +#include "code\modules\surgery\bodyparts\helpers.dm" #include "code\modules\surgery\organs\augments_arms.dm" #include "code\modules\surgery\organs\augments_chest.dm" -#include "code\modules\surgery\organs\augments_external.dm" #include "code\modules\surgery\organs\augments_eyes.dm" #include "code\modules\surgery\organs\augments_internal.dm" #include "code\modules\surgery\organs\autoimplanter.dm" #include "code\modules\surgery\organs\helpers.dm" -#include "code\modules\surgery\organs\organ_external.dm" #include "code\modules\surgery\organs\organ_internal.dm" #include "code\modules\telesci\bscrystal.dm" #include "code\modules\telesci\gps.dm" diff --git a/tools/mapmerge/maintloot.py b/tools/mapmerge/maintloot.py new file mode 100755 index 00000000000..6da36aa9fb9 --- /dev/null +++ b/tools/mapmerge/maintloot.py @@ -0,0 +1,64 @@ +#!/usr/bin/env python3 +import argparse +import collections +import re + +from map_helpers import parse_map + +if __name__=='__main__': + parser = argparse.ArgumentParser() + parser.add_argument("mapfile") + + args = parser.parse_args() + M = parse_map(args.mapfile) + # Format of this map parsing + # dict(coordinates->mapkey) + grid = M["grid"] + # dict(mapkey->tilecontents) + dictionary = M["dictionary"] + # tilecontents are a list of atoms, path is first + + lootdrop_path = "/obj/effect/spawner/lootdrop/maintenance" + area_path = "/area" + + follow_up = set() + for key, atoms in dictionary.items(): + #atom is a string + for atom in atoms: + if atom.startswith(lootdrop_path): + if(key in follow_up): + print("Hey, '{}' has multiple maintlootdrops...") + follow_up.add(key) + + # Count the number of times each map key appears + appears = collections.Counter() + for coord, key in grid.items(): + if key in follow_up: + appears[key] += 1 + + tally = collections.Counter() + for key in follow_up: + # Because I am a terrible person, and don't actually care about + # building a proper parser for this "object notation" that byond + # uses, I'm just going to cheat. + area = None + count = 0 + + for atom in dictionary[key]: + if atom.startswith(lootdrop_path): + amount = 1 + mo = re.search(r'lootcount = (\d+)', atom) + if mo is not None: + amount = int(mo.group(1)) + count += amount + + elif atom.startswith(area_path): + area = atom + + # Multiply by the number of times this model is used + tally[area] += (count * appears[key]) + + for area, total in tally.items(): + print("{}: {}".format(area, total)) + + print("TOTAL: {}".format(sum(tally.values())))