diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_seed_vault.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_seed_vault.dmm index fd2e56a53f..945ea515c7 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_seed_vault.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_seed_vault.dmm @@ -274,8 +274,7 @@ /area/ruin/powered/seedvault) "Z" = ( /obj/item/disk/design_disk/plant_disk, -/obj/machinery/autolathe{ - hacked = TRUE; +/obj/machinery/autolathe/hacked{ desc = "This autolathe seems to have its safety light off." }, /turf/open/floor/plasteel/freezer, diff --git a/_maps/RandomRuins/SpaceRuins/arcade.dmm b/_maps/RandomRuins/SpaceRuins/arcade.dmm new file mode 100644 index 0000000000..771c33c55b --- /dev/null +++ b/_maps/RandomRuins/SpaceRuins/arcade.dmm @@ -0,0 +1,711 @@ +//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE +"a" = ( +/turf/template_noop, +/area/template_noop) +"b" = ( +/turf/open/floor/plating/asteroid, +/area/ruin/powered) +"c" = ( +/turf/closed/mineral/random/high_chance, +/area/ruin/powered) +"d" = ( +/turf/closed/wall/mineral/titanium/survival/pod, +/area/ruin/powered) +"e" = ( +/obj/machinery/computer/arcade, +/turf/open/floor/engine, +/area/ruin/powered) +"f" = ( +/obj/machinery/light{ + dir = 1 + }, +/obj/machinery/vending/coffee, +/turf/open/floor/engine, +/area/ruin/powered) +"g" = ( +/obj/item/coin, +/obj/item/toy/plush/random, +/turf/open/floor/engine, +/area/ruin/powered) +"h" = ( +/obj/effect/mob_spawn/human/corpse/assistant, +/obj/effect/decal/cleanable/blood, +/obj/item/toy/plush/random, +/turf/open/floor/engine, +/area/ruin/powered) +"i" = ( +/obj/machinery/light{ + dir = 4 + }, +/obj/item/toy/plush/random, +/turf/open/floor/engine, +/area/ruin/powered) +"j" = ( +/obj/machinery/light{ + dir = 8 + }, +/turf/open/floor/engine, +/area/ruin/powered) +"k" = ( +/obj/item/coin/gold, +/turf/open/floor/engine, +/area/ruin/powered) +"l" = ( +/turf/open/floor/engine, +/area/ruin/powered) +"m" = ( +/obj/item/coin/iron, +/turf/open/floor/engine, +/area/ruin/powered) +"n" = ( +/obj/item/toy/plush/random, +/turf/open/floor/engine, +/area/ruin/powered) +"o" = ( +/obj/item/kitchen/knife{ + pixel_x = 5; + pixel_y = 11 + }, +/obj/item/toy/plush/random, +/turf/open/floor/engine, +/area/ruin/powered) +"p" = ( +/turf/closed/wall/mineral/titanium/survival/nodiagonal, +/area/ruin/powered) +"q" = ( +/turf/open/floor/light/colour_cycle/dancefloor_b, +/area/ruin/powered) +"r" = ( +/turf/open/floor/light/colour_cycle/dancefloor_a, +/area/ruin/powered) +"s" = ( +/obj/machinery/door/airlock/external/glass, +/obj/structure/fans/tiny, +/turf/open/floor/engine, +/area/ruin/powered) +"t" = ( +/obj/item/trash/chips, +/turf/open/floor/engine, +/area/ruin/powered) +"u" = ( +/obj/item/trash/cheesie, +/turf/open/floor/engine, +/area/ruin/powered) +"v" = ( +/obj/item/coin, +/turf/open/floor/engine, +/area/ruin/powered) +"w" = ( +/obj/item/coin/diamond, +/turf/open/floor/engine, +/area/ruin/powered) +"x" = ( +/obj/machinery/jukebox/disco/indestructible, +/turf/open/floor/light/colour_cycle/dancefloor_b, +/area/ruin/powered) +"y" = ( +/obj/machinery/light, +/turf/open/floor/engine, +/area/ruin/powered) +"z" = ( +/obj/machinery/light{ + dir = 4 + }, +/turf/open/floor/engine, +/area/ruin/powered) +"A" = ( +/obj/machinery/door/airlock/external/glass, +/turf/open/floor/engine, +/area/ruin/powered) +"B" = ( +/obj/machinery/vending/cola/random, +/turf/open/floor/engine, +/area/ruin/powered) +"C" = ( +/obj/machinery/vending/snack/random, +/turf/open/floor/engine, +/area/ruin/powered) +"D" = ( +/obj/item/trash/can, +/turf/open/floor/engine, +/area/ruin/powered) +"E" = ( +/obj/item/trash/sosjerky, +/turf/open/floor/engine, +/area/ruin/powered) +"F" = ( +/obj/structure/closet/crate/trashcart, +/turf/open/floor/plating/asteroid, +/area/ruin/powered) +"G" = ( +/obj/structure/chair/sofa/right, +/turf/open/floor/engine, +/area/ruin/powered) +"H" = ( +/obj/structure/chair/sofa/left, +/obj/item/bedsheet/ian, +/turf/open/floor/engine, +/area/ruin/powered) +"I" = ( +/obj/item/aiModule/toyAI, +/turf/open/floor/engine, +/area/ruin/powered) +"J" = ( +/obj/item/twohanded/dualsaber/toy, +/turf/open/floor/light/colour_cycle/dancefloor_b, +/area/ruin/powered) +"K" = ( +/obj/item/gun/energy/pumpaction/toy, +/turf/open/floor/engine, +/area/ruin/powered) + +(1,1,1) = {" +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +"} +(2,1,1) = {" +a +a +a +a +b +b +b +b +a +a +a +a +a +a +a +a +a +a +a +a +"} +(3,1,1) = {" +a +a +a +b +b +b +b +b +b +b +b +a +a +a +b +b +b +b +a +a +"} +(4,1,1) = {" +a +a +a +b +b +b +b +b +b +b +b +a +a +b +b +b +b +b +b +a +"} +(5,1,1) = {" +a +a +a +b +b +c +c +c +c +b +b +b +b +b +b +c +c +c +b +b +"} +(6,1,1) = {" +a +a +a +b +c +c +c +c +c +b +b +b +b +c +c +c +c +c +c +b +"} +(7,1,1) = {" +a +a +a +b +c +c +d +d +d +d +d +d +d +d +d +d +c +c +c +b +"} +(8,1,1) = {" +a +a +a +b +c +c +d +e +j +l +l +K +j +G +B +d +c +c +b +b +"} +(9,1,1) = {" +a +a +a +b +c +c +d +e +k +l +v +l +l +H +C +d +c +c +b +a +"} +(10,1,1) = {" +a +a +b +b +c +c +d +e +l +I +l +l +l +k +B +d +c +c +b +a +"} +(11,1,1) = {" +a +a +b +c +c +c +d +e +l +l +w +l +y +d +d +p +c +b +b +a +"} +(12,1,1) = {" +a +a +b +c +c +c +d +e +m +J +r +q +l +A +l +s +b +b +b +a +"} +(13,1,1) = {" +a +b +b +c +c +c +d +f +l +r +x +r +l +d +d +d +b +b +b +a +"} +(14,1,1) = {" +a +b +b +c +c +c +d +e +l +q +r +q +D +A +l +s +b +b +b +a +"} +(15,1,1) = {" +a +b +b +b +c +c +d +e +t +u +l +E +y +d +d +p +b +b +b +a +"} +(16,1,1) = {" +a +b +b +b +c +c +d +e +g +n +t +k +l +l +B +d +c +b +b +a +"} +(17,1,1) = {" +a +b +b +c +c +c +d +e +h +o +D +l +D +l +C +d +c +c +b +b +"} +(18,1,1) = {" +a +a +b +c +c +c +d +e +i +n +E +l +z +m +B +d +c +c +c +b +"} +(19,1,1) = {" +a +a +b +c +c +c +d +d +d +d +d +d +d +d +d +d +c +c +c +b +"} +(20,1,1) = {" +a +a +b +b +c +c +c +c +c +c +b +F +b +c +c +c +c +c +c +b +"} +(21,1,1) = {" +a +a +a +b +c +c +c +c +c +c +b +b +b +c +c +c +c +c +b +b +"} +(22,1,1) = {" +a +a +a +b +b +c +c +c +c +b +b +b +b +b +b +c +c +b +b +a +"} +(23,1,1) = {" +a +a +a +a +b +b +b +b +b +b +a +b +b +b +b +b +b +b +a +a +"} +(24,1,1) = {" +a +a +a +a +a +a +a +a +a +a +a +a +b +b +b +b +b +a +a +a +"} +(25,1,1) = {" +a +a +a +a +a +a +a +a +a +a +a +a +a +a +b +b +a +a +a +a +"} diff --git a/_maps/RandomRuins/SpaceRuins/augmentationfacility.dmm b/_maps/RandomRuins/SpaceRuins/augmentationfacility.dmm new file mode 100644 index 0000000000..c64050ce3a --- /dev/null +++ b/_maps/RandomRuins/SpaceRuins/augmentationfacility.dmm @@ -0,0 +1,731 @@ +//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE +"a" = ( +/turf/template_noop, +/area/template_noop) +"b" = ( +/turf/open/floor/plating/asteroid, +/area/ruin/powered) +"c" = ( +/turf/closed/mineral/random/high_chance, +/area/ruin/powered) +"d" = ( +/turf/closed/wall/r_wall/rust, +/area/ruin/powered) +"e" = ( +/obj/machinery/mecha_part_fabricator, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/ruin/powered) +"f" = ( +/turf/closed/wall/rust, +/area/ruin/powered) +"g" = ( +/obj/structure/table, +/obj/effect/decal/cleanable/dirt, +/obj/item/stack/sheet/glass/fifty, +/obj/item/stack/sheet/metal/fifty, +/turf/open/floor/plasteel, +/area/ruin/powered) +"h" = ( +/obj/machinery/mecha_part_fabricator, +/obj/machinery/light{ + dir = 1 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/ruin/powered) +"i" = ( +/obj/structure/table, +/obj/machinery/light{ + dir = 1 + }, +/obj/effect/decal/cleanable/dirt, +/obj/item/stack/sheet/glass/fifty, +/obj/item/stack/sheet/metal/fifty, +/turf/open/floor/plasteel, +/area/ruin/powered) +"j" = ( +/obj/structure/chair/sofa/right, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/ruin/powered) +"k" = ( +/turf/open/floor/plasteel, +/area/ruin/powered) +"l" = ( +/obj/structure/chair/sofa/left, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/ruin/powered) +"m" = ( +/obj/machinery/computer/rdconsole/production{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/ruin/powered) +"n" = ( +/obj/effect/decal/cleanable/oil/streak, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/ruin/powered) +"o" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/ruin/powered) +"p" = ( +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/ruin/powered) +"q" = ( +/obj/machinery/light{ + dir = 8 + }, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/aug_manipulator, +/turf/open/floor/plasteel, +/area/ruin/powered) +"r" = ( +/obj/structure/table, +/obj/effect/decal/cleanable/dirt, +/obj/item/organ/cyberimp/chest/reviver, +/turf/open/floor/plasteel, +/area/ruin/powered) +"s" = ( +/obj/structure/table, +/obj/effect/decal/cleanable/dirt, +/obj/item/organ/cyberimp/arm/surgery, +/turf/open/floor/plasteel, +/area/ruin/powered) +"t" = ( +/obj/structure/table, +/obj/effect/decal/cleanable/dirt, +/obj/item/storage/backpack/duffelbag/med/surgery, +/turf/open/floor/plasteel, +/area/ruin/powered) +"u" = ( +/obj/machinery/light{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/ruin/powered) +"v" = ( +/obj/machinery/porta_turret/syndicate/energy{ + mode = 1 + }, +/turf/closed/wall/r_wall/rust, +/area/ruin/powered) +"w" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/computer/mech_bay_power_console{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/ruin/powered) +"x" = ( +/obj/effect/decal/cleanable/oil, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/ruin/powered) +"y" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer1, +/turf/open/floor/plasteel, +/area/ruin/powered) +"z" = ( +/obj/structure/table, +/obj/effect/decal/cleanable/dirt, +/obj/item/storage/belt/utility/full, +/obj/item/clothing/glasses/welding, +/turf/open/floor/plasteel, +/area/ruin/powered) +"A" = ( +/obj/structure/table, +/obj/effect/decal/cleanable/dirt, +/obj/item/mmi/posibrain{ + pixel_y = 9 + }, +/obj/item/mmi, +/turf/open/floor/plasteel, +/area/ruin/powered) +"B" = ( +/obj/structure/table/optable, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/ruin/powered) +"C" = ( +/obj/machinery/mech_bay_recharge_port, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/ruin/powered) +"D" = ( +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/mech_bay_recharge_floor, +/area/ruin/powered) +"E" = ( +/obj/machinery/computer/operating{ + dir = 1 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/ruin/powered) +"F" = ( +/obj/structure/table, +/obj/effect/decal/cleanable/dirt, +/obj/item/autosurgeon{ + name = "rusted autosurgeon"; + desc = "A device that automatically inserts an implant or organ into the user without the hassle of extensive surgery. It has a slot to insert an organ of implant. But this rusted version looks like it could only manage one implant...."; + uses = 1 + }, +/turf/open/floor/plasteel, +/area/ruin/powered) +"G" = ( +/obj/machinery/light, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/airalarm{ + dir = 1; + pixel_y = -22 + }, +/turf/open/floor/plasteel, +/area/ruin/powered) +"H" = ( +/obj/effect/decal/cleanable/oil, +/obj/machinery/light, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/ruin/powered) +"I" = ( +/obj/machinery/door/airlock/external/glass, +/turf/open/floor/plasteel, +/area/ruin/powered) +"J" = ( +/obj/machinery/atmospherics/components/unary/outlet_injector/on/layer1{ + dir = 4 + }, +/turf/open/floor/plating/asteroid, +/area/ruin/powered) +"K" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{ + dir = 4 + }, +/turf/closed/mineral/random/high_chance, +/area/ruin/powered) +"L" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{ + dir = 4 + }, +/turf/closed/wall/r_wall/rust, +/area/ruin/powered) +"M" = ( +/obj/structure/mecha_wreckage/ripley, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/ruin/powered) +"N" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/ruin/powered) +"O" = ( +/obj/machinery/turretid{ + lethal = 1; + pixel_y = -25; + req_access = null + }, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ + dir = 5 + }, +/turf/open/floor/plasteel, +/area/ruin/powered) +"P" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/components/unary/vent_pump/on, +/turf/open/floor/plasteel, +/area/ruin/powered) +"Q" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/ruin/powered) +"R" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/simple/cyan/hidden, +/turf/open/floor/plasteel, +/area/ruin/powered) +"S" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{ + dir = 9 + }, +/turf/open/floor/plasteel, +/area/ruin/powered) +"T" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/components/unary/tank/air{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/ruin/powered) +"U" = ( +/obj/machinery/door/airlock/external/glass, +/obj/structure/fans/tiny, +/turf/open/floor/plasteel, +/area/ruin/powered) +"V" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/reagent_dispensers/fueltank, +/turf/open/floor/plasteel, +/area/ruin/powered) + +(1,1,1) = {" +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +"} +(2,1,1) = {" +a +a +a +a +a +a +b +b +b +b +a +a +a +a +a +a +a +a +a +a +"} +(3,1,1) = {" +a +a +a +a +b +b +c +c +c +c +J +b +b +a +a +a +a +a +a +a +"} +(4,1,1) = {" +a +a +a +b +c +c +c +c +c +c +K +c +b +b +b +a +a +a +a +a +"} +(5,1,1) = {" +a +a +b +c +c +d +d +d +d +d +L +d +c +c +b +a +a +a +a +a +"} +(6,1,1) = {" +a +a +b +c +d +d +m +q +w +C +M +d +d +c +b +a +a +a +a +a +"} +(7,1,1) = {" +a +b +b +c +d +e +n +o +x +D +N +f +d +v +b +a +a +a +a +a +"} +(8,1,1) = {" +a +b +c +c +d +g +o +o +y +Q +S +I +k +U +b +a +a +a +a +a +"} +(9,1,1) = {" +a +b +c +c +d +h +p +r +z +o +G +f +f +d +b +a +a +a +a +a +"} +(10,1,1) = {" +a +b +c +c +d +i +p +s +A +o +H +f +f +d +b +a +a +a +a +a +"} +(11,1,1) = {" +a +b +c +c +d +j +p +t +F +o +p +I +k +U +b +a +a +a +a +a +"} +(12,1,1) = {" +a +b +c +c +d +l +p +p +P +R +O +f +d +v +b +b +a +a +a +a +"} +(13,1,1) = {" +a +b +b +c +d +d +V +u +B +E +T +d +d +c +c +b +a +a +a +a +"} +(14,1,1) = {" +a +a +b +c +c +d +d +d +d +d +d +d +c +c +c +b +a +a +a +a +"} +(15,1,1) = {" +a +a +a +b +c +c +c +c +c +c +c +c +c +c +b +b +a +a +a +a +"} +(16,1,1) = {" +a +a +a +b +b +b +b +c +c +c +c +b +b +b +b +a +a +a +a +a +"} +(17,1,1) = {" +a +a +a +a +a +a +b +b +b +b +b +b +a +a +a +a +a +a +a +a +"} +(18,1,1) = {" +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +"} +(19,1,1) = {" +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +"} +(20,1,1) = {" +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +"} diff --git a/_maps/RandomRuins/SpaceRuins/bigape.dmm b/_maps/RandomRuins/SpaceRuins/bigape.dmm new file mode 100644 index 0000000000..09e85e129d --- /dev/null +++ b/_maps/RandomRuins/SpaceRuins/bigape.dmm @@ -0,0 +1,196 @@ +//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE +"a" = ( +/turf/template_noop, +/area/template_noop) +"b" = ( +/obj/structure/lattice, +/turf/template_noop, +/area/template_noop) +"c" = ( +/turf/open/floor/plating/beach/sand, +/area/ruin/powered) +"d" = ( +/obj/structure/fans/tiny/invisible, +/turf/open/floor/plating/beach/sand, +/area/ruin/powered) +"e" = ( +/obj/item/reagent_containers/food/snacks/grown/banana, +/obj/item/reagent_containers/food/snacks/grown/banana, +/obj/item/reagent_containers/food/snacks/grown/banana, +/obj/item/reagent_containers/food/snacks/grown/banana, +/obj/item/reagent_containers/food/snacks/grown/banana, +/obj/structure/fans/tiny/invisible, +/obj/structure/closet/secure_closet/freezer, +/turf/open/floor/plating/beach/sand, +/area/ruin/powered) +"f" = ( +/obj/structure/chair/sofa/left{ + dir = 4 + }, +/turf/open/floor/plating/beach/sand, +/area/ruin/powered) +"g" = ( +/obj/item/flashlight/lamp/bananalamp{ + brightness_on = 10 + }, +/obj/structure/table/wood, +/obj/structure/fans/tiny/invisible, +/turf/open/floor/plating/beach/sand, +/area/ruin/powered) +"h" = ( +/obj/structure/table/wood, +/obj/machinery/computer/security/wooden_tv, +/turf/open/floor/plating/beach/sand, +/area/ruin/powered) +"i" = ( +/obj/structure/chair/sofa/right{ + dir = 4 + }, +/turf/open/floor/plating/beach/sand, +/area/ruin/powered) +"j" = ( +/obj/structure/sink/puddle, +/turf/open/floor/plating/beach/sand, +/area/ruin/powered) +"k" = ( +/obj/structure/chair/sofa{ + dir = 4 + }, +/mob/living/simple_animal/hostile/gorilla{ + AIStatus = null; + desc = "There is no need to be upset."; + dir = 4; + name = "Familiar Gorilla" + }, +/turf/open/floor/plating/beach/sand, +/area/ruin/powered) +"l" = ( +/obj/effect/overlay/palmtree_r, +/obj/structure/fans/tiny/invisible, +/turf/open/floor/plating/beach/sand, +/area/ruin/powered) +"m" = ( +/obj/item/grown/bananapeel, +/turf/open/floor/plating/beach/sand, +/area/ruin/powered) + +(1,1,1) = {" +a +a +a +a +a +a +a +a +b +a +"} +(2,1,1) = {" +a +a +b +b +b +b +b +b +a +a +"} +(3,1,1) = {" +a +a +b +b +g +d +d +b +b +a +"} +(4,1,1) = {" +a +a +b +d +f +k +i +d +d +b +"} +(5,1,1) = {" +a +a +b +e +c +c +m +j +d +b +"} +(6,1,1) = {" +a +a +b +d +c +h +c +l +d +b +"} +(7,1,1) = {" +a +b +b +b +d +d +d +b +b +a +"} +(8,1,1) = {" +a +b +a +a +b +b +b +b +b +b +"} +(9,1,1) = {" +a +b +a +a +a +b +a +a +a +b +"} +(10,1,1) = {" +a +a +a +a +a +b +a +a +a +a +"} diff --git a/_maps/RandomRuins/SpaceRuins/originalcontent.dmm b/_maps/RandomRuins/SpaceRuins/originalcontent.dmm index 624aa03d7c..2945a06b25 100644 --- a/_maps/RandomRuins/SpaceRuins/originalcontent.dmm +++ b/_maps/RandomRuins/SpaceRuins/originalcontent.dmm @@ -742,6 +742,7 @@ /turf/open/indestructible/paper, /area/ruin/powered) "cc" = ( +/obj/item/book/granter/action/origami, /mob/living/simple_animal/hostile/boss/paper_wizard, /turf/open/indestructible/paper, /area/ruin/powered) @@ -912,6 +913,10 @@ }, /turf/open/indestructible/paper, /area/ruin/powered) +"Ns" = ( +/obj/item/paper/secretrecipe, +/turf/open/indestructible/paper, +/area/ruin/powered) (1,1,1) = {" aa @@ -2246,7 +2251,7 @@ ap az af al -aA +Ns bW ca af diff --git a/_maps/RandomRuins/SpaceRuins/spacehermit.dmm b/_maps/RandomRuins/SpaceRuins/spacehermit.dmm new file mode 100644 index 0000000000..341dcf7b99 --- /dev/null +++ b/_maps/RandomRuins/SpaceRuins/spacehermit.dmm @@ -0,0 +1,2941 @@ +//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE +"aa" = ( +/turf/template_noop, +/area/template_noop) +"ab" = ( +/turf/closed/mineral/random/low_chance, +/area/ruin/unpowered) +"ac" = ( +/turf/open/floor/plating/asteroid, +/area/ruin/unpowered) +"ad" = ( +/obj/machinery/hydroponics/soil, +/turf/open/floor/plating/asteroid, +/area/ruin/unpowered) +"ae" = ( +/turf/closed/wall/mineral/titanium, +/area/ruin/powered) +"af" = ( +/obj/effect/spawner/structure/window/shuttle, +/turf/open/floor/mineral/titanium, +/area/ruin/powered) +"ag" = ( +/obj/structure/shuttle/engine/propulsion/right{ + dir = 4 + }, +/turf/closed/wall/mineral/titanium, +/area/ruin/powered) +"ah" = ( +/obj/structure/table/wood, +/obj/item/shovel, +/turf/open/floor/plating/asteroid, +/area/ruin/unpowered) +"ai" = ( +/obj/structure/lattice, +/turf/template_noop, +/area/template_noop) +"aj" = ( +/obj/machinery/computer/cryopod, +/turf/closed/wall/mineral/titanium, +/area/ruin/powered) +"ak" = ( +/obj/structure/fluff/empty_cryostasis_sleeper, +/turf/open/floor/mineral/titanium, +/area/ruin/powered) +"al" = ( +/obj/machinery/status_display/shuttle, +/turf/closed/wall/mineral/titanium, +/area/ruin/powered) +"am" = ( +/obj/item/circuitboard/computer/rdconsole, +/obj/item/circuitboard/machine/protolathe/department/science, +/turf/open/floor/plating/asteroid, +/area/ruin/unpowered) +"an" = ( +/turf/open/floor/mineral/titanium, +/area/ruin/powered) +"ao" = ( +/obj/structure/chair/comfy/shuttle{ + dir = 8 + }, +/turf/open/floor/mineral/titanium, +/area/ruin/powered) +"ap" = ( +/obj/machinery/light{ + dir = 1 + }, +/turf/open/floor/mineral/titanium, +/area/ruin/powered) +"aq" = ( +/obj/machinery/computer{ + desc = "A computer long since rendered non-functional due to lack of maintenance. Spitting out error messages."; + dir = 4; + name = "Broken Computer" + }, +/turf/open/floor/mineral/titanium, +/area/ruin/powered) +"ar" = ( +/obj/machinery/door/airlock/titanium{ + name = "Escape Pod Airlock" + }, +/turf/open/floor/mineral/titanium, +/area/ruin/powered) +"as" = ( +/obj/machinery/light, +/turf/open/floor/mineral/titanium, +/area/ruin/powered) +"at" = ( +/obj/structure/shuttle/engine/propulsion/left{ + dir = 4 + }, +/turf/closed/wall/mineral/titanium, +/area/ruin/powered) +"au" = ( +/obj/item/seeds/tower, +/obj/item/seeds/tower, +/obj/item/seeds/tower, +/turf/open/floor/plating/asteroid, +/area/ruin/unpowered) +"av" = ( +/obj/structure/table/wood, +/obj/item/paper/crumpled{ + info = "

So this is it, I guess.. Always thought I'd go out doing something stupid, but.. not like this.
Should anyone find this note, tell Jeremy Clarke he can kiss my ass. Launching the pod unprepared like that..
Well. Now that I'm keeling over here, I guess I should write how I came to be the last one standing here.
Four of us took this pod.. only three of us woke up though.. fourth pod is locked from the inside, we couldn't figure out how to get it open.
Me and the clown set up a farm s'we can survive at least a while.. though, he didn't seem to understand that man cannot live on banana alone.
Had a bunch of circuits on him for some reason when he eventually passed, whispered to me something about a chem dispenser.. I.. don't know what he meant by that. I was never good with machinary. Maybe he wanted space lube?
The assistant that we gave the space suit to go out and find help never came back.. I'm betting he found salvation and left us behind.. never can trust those grubby greytiders." + }, +/obj/item/pen, +/turf/open/floor/plating/asteroid, +/area/ruin/unpowered) +"aw" = ( +/obj/item/stack/sheet/mineral/wood, +/obj/item/stack/sheet/mineral/wood, +/obj/item/stack/sheet/mineral/wood, +/obj/item/stack/sheet/mineral/wood, +/obj/item/stack/sheet/mineral/wood, +/turf/open/floor/plating/asteroid, +/area/ruin/unpowered) +"ax" = ( +/obj/item/twohanded/spear, +/turf/open/floor/plating/asteroid, +/area/ruin/unpowered) +"ay" = ( +/obj/item/grown/log, +/obj/item/grown/log, +/turf/open/floor/plating/asteroid, +/area/ruin/unpowered) +"az" = ( +/obj/structure/table/wood, +/obj/item/storage/bag/plants/portaseeder, +/turf/open/floor/plating/asteroid, +/area/ruin/unpowered) +"aA" = ( +/turf/open/floor/plating/asteroid/airless, +/area/ruin/unpowered) +"aB" = ( +/obj/item/seeds/banana, +/obj/item/seeds/banana, +/turf/open/floor/plating/asteroid, +/area/ruin/unpowered) +"aC" = ( +/obj/effect/mob_spawn/human/clown/corpse, +/obj/structure/fans/tiny/invisible, +/turf/open/floor/plating/asteroid, +/area/ruin/unpowered) +"aD" = ( +/obj/item/mining_scanner, +/turf/open/floor/plating/asteroid, +/area/ruin/unpowered) +"aE" = ( +/obj/machinery/status_display/shuttle, +/turf/closed/wall/mineral/titanium, +/area/ruin/unpowered) +"aF" = ( +/obj/item/pickaxe/emergency, +/turf/open/floor/plating/asteroid, +/area/ruin/unpowered) +"aG" = ( +/obj/structure/sink/puddle, +/turf/open/floor/plating/asteroid, +/area/ruin/unpowered) +"aH" = ( +/obj/structure/table/wood, +/obj/item/storage/firstaid/regular, +/turf/open/floor/plating/asteroid, +/area/ruin/unpowered) +"aI" = ( +/obj/effect/mob_spawn/human/corpse/assistant, +/turf/template_noop, +/area/template_noop) +"aJ" = ( +/obj/structure/table/wood, +/obj/item/storage/bag/ore, +/turf/open/floor/plating/asteroid, +/area/ruin/unpowered) +"aK" = ( +/obj/structure/reagent_dispensers/fueltank, +/turf/open/floor/plating/asteroid, +/area/ruin/unpowered) +"aL" = ( +/obj/structure/table/wood, +/obj/item/storage/toolbox/mechanical, +/obj/item/clothing/head/welding, +/turf/open/floor/plating/asteroid, +/area/ruin/unpowered) +"aM" = ( +/mob/living/simple_animal/hostile/carp, +/turf/template_noop, +/area/template_noop) +"aN" = ( +/obj/structure/mineral_door/sandstone, +/turf/open/floor/plating/asteroid, +/area/ruin/unpowered) +"aO" = ( +/mob/living/simple_animal/hostile/carp, +/turf/open/floor/plating/asteroid/airless, +/area/ruin/unpowered) +"aP" = ( +/obj/item/stack/ore/gold, +/turf/open/floor/plating/asteroid, +/area/ruin/unpowered) +"aQ" = ( +/obj/item/stack/ore/gold, +/obj/item/stack/ore/gold, +/obj/item/stack/ore/gold, +/turf/open/floor/plating/asteroid, +/area/ruin/unpowered) +"aR" = ( +/obj/item/stack/ore/iron, +/turf/open/floor/plating/asteroid, +/area/ruin/unpowered) +"aS" = ( +/turf/closed/wall/mineral/iron, +/area/ruin/unpowered) +"aT" = ( +/obj/item/stack/ore/iron, +/obj/item/stack/ore/iron, +/turf/open/floor/plating/asteroid, +/area/ruin/unpowered) +"aU" = ( +/obj/item/flashlight/lamp, +/obj/structure/table/wood, +/turf/open/floor/plating/asteroid, +/area/ruin/unpowered) +"aV" = ( +/obj/item/clothing/suit/space/orange, +/turf/template_noop, +/area/template_noop) +"aW" = ( +/obj/item/clothing/head/helmet/space/orange, +/turf/template_noop, +/area/template_noop) +"aX" = ( +/mob/living/simple_animal/hostile/carp/megacarp, +/turf/template_noop, +/area/template_noop) +"aY" = ( +/obj/effect/mob_spawn/human/hermit{ + flavour_text = "You've been late to awaken from your cryo slumber. Blasted machine, you set it to 10 days not 10 weeks! Where have the others gone while we were out? Did they manage to survive? These thoughts are dispelled by yet another recollection of how you got here... "; + job_description = "Space Hermit" + }, +/turf/open/floor/mineral/titanium, +/area/ruin/powered) +"aZ" = ( +/turf/closed/wall/mineral/titanium, +/area/ruin/unpowered) +"ba" = ( +/obj/effect/spawner/structure/window/shuttle, +/turf/open/floor/mineral/titanium, +/area/ruin/unpowered) +"bb" = ( +/obj/structure/shuttle/engine/propulsion/left{ + dir = 4 + }, +/turf/closed/wall/mineral/titanium, +/area/ruin/unpowered) +"bc" = ( +/obj/item/circuitboard/machine/circuit_imprinter, +/turf/open/floor/plating/asteroid, +/area/ruin/unpowered) +"bd" = ( +/obj/item/grown/bananapeel, +/turf/open/floor/plating/asteroid, +/area/ruin/unpowered) +"be" = ( +/obj/effect/mob_spawn/human/corpse/cargo_tech, +/obj/structure/fans/tiny/invisible, +/obj/effect/decal/cleanable/vomit, +/turf/open/floor/plating/asteroid, +/area/ruin/unpowered) +"bf" = ( +/obj/item/clothing/glasses/meson, +/turf/open/floor/plating/asteroid, +/area/ruin/unpowered) +"bg" = ( +/obj/item/stock_parts/matter_bin, +/turf/open/floor/plating/asteroid, +/area/ruin/unpowered) +"bh" = ( +/obj/item/circuitboard/machine/autolathe, +/turf/open/floor/mineral/titanium, +/area/ruin/powered) +"bi" = ( +/obj/item/stock_parts/manipulator, +/turf/open/floor/plating/asteroid, +/area/ruin/unpowered) +"bj" = ( +/obj/item/holosign_creator/atmos, +/turf/open/floor/plating/asteroid, +/area/ruin/unpowered) +"bk" = ( +/obj/structure/holosign/barrier/atmos, +/turf/open/floor/plating/asteroid, +/area/ruin/unpowered) +"bl" = ( +/obj/machinery/power/floodlight, +/obj/structure/cable{ + icon_state = "0-2" + }, +/turf/open/floor/plating/asteroid, +/area/ruin/unpowered) +"bm" = ( +/obj/structure/cable{ + icon_state = "1-4" + }, +/turf/open/floor/plating/asteroid, +/area/ruin/unpowered) +"bn" = ( +/obj/structure/cable{ + icon_state = "2-8" + }, +/turf/open/floor/plating/asteroid, +/area/ruin/unpowered) +"bo" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/plating/asteroid, +/area/ruin/unpowered) +"bp" = ( +/obj/item/stack/ore/iron, +/obj/item/stack/ore/iron, +/obj/item/stack/ore/iron, +/turf/open/floor/plating/asteroid, +/area/ruin/unpowered) +"bq" = ( +/obj/structure/cable, +/obj/machinery/power/port_gen/pacman{ + active = 1; + anchored = 1; + sheets = 10 + }, +/turf/open/floor/plating/asteroid, +/area/ruin/unpowered) +"br" = ( +/obj/item/stack/ore/iron, +/obj/item/stack/sheet/mineral/plasma, +/obj/item/stack/sheet/mineral/plasma, +/turf/open/floor/plating/asteroid, +/area/ruin/unpowered) +"bs" = ( +/obj/item/flashlight/lamp/bananalamp, +/turf/open/floor/plating/asteroid, +/area/ruin/unpowered) + +(1,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aM +aa +aa +aa +aa +aa +aa +aa +ac +aO +aA +aA +aA +aA +aA +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(2,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aM +aa +aa +aa +aa +aa +aa +aa +aA +aA +aA +aA +aA +aA +ab +ab +ab +ab +ab +ab +ab +aA +aA +aA +aa +aa +aa +aa +aM +aa +aa +aa +aa +aa +"} +(3,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aA +aA +aA +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aA +aA +aa +aa +aa +aa +aW +aa +aM +aa +"} +(4,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aA +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aA +aa +aa +aV +aI +aX +aa +aa +"} +(5,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aA +aA +aA +aA +aA +aA +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aA +aa +aa +aa +aa +aa +aa +"} +(6,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aA +ab +ab +ab +ab +aA +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aA +aa +aM +aa +aa +aa +"} +(7,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aM +aa +aA +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aA +aa +aa +aa +aa +"} +(8,1,1) = {" +aa +aa +aa +aa +aa +aa +ab +aa +aa +aa +aa +aa +aA +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ae +af +ae +ab +ab +ab +ab +ab +ab +ab +ab +aA +aa +aa +aa +"} +(9,1,1) = {" +aa +aa +aa +aa +aA +ab +ab +aA +aa +aa +aa +aa +aA +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +af +aq +af +ab +ab +ab +ab +ab +ab +ab +ab +ab +aA +aa +aa +"} +(10,1,1) = {" +aa +aa +aa +aa +ab +ab +ab +ab +aA +aa +aa +aA +aA +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ae +ae +ao +ae +ae +ab +ab +ab +ab +ab +ab +ab +ab +aA +aa +aa +"} +(11,1,1) = {" +aa +aa +aa +aA +ab +ab +ab +ab +aA +aa +aa +aA +aA +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +af +an +an +an +af +ab +ab +ab +ab +ab +ab +ab +ab +ab +aA +aa +"} +(12,1,1) = {" +aa +aa +aa +aA +ab +ab +ab +ab +aA +aa +aa +aA +aA +aA +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ae +ae +bh +an +an +ae +aZ +ab +ab +ab +ab +ab +ab +ab +ab +aA +aa +"} +(13,1,1) = {" +aa +aa +aa +aA +ab +ab +ab +ab +aA +aa +aa +aA +aA +aA +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +af +aY +ao +ao +ao +ak +ba +ab +ab +ab +ab +ab +ab +ab +ab +aA +aa +"} +(14,1,1) = {" +aa +aa +aa +aa +ab +ab +ab +ab +aA +aa +aa +aA +aA +aA +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +al +aj +ap +an +as +aj +aE +ab +ab +ab +ab +ab +ab +ab +ab +aA +aa +"} +(15,1,1) = {" +aa +aa +aa +aa +aA +ab +ab +aA +aa +aa +aa +aA +aA +aA +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +af +ak +ao +ao +ao +ak +ba +ac +ab +ab +ab +ab +ab +ab +ab +aA +aa +"} +(16,1,1) = {" +aa +aa +aa +aa +aa +aa +ab +aa +aa +aa +aa +aA +aA +ab +ab +ab +ab +ab +ab +ab +ab +ab +ah +az +ab +ab +ab +ab +ab +ab +ab +ab +aR +ae +ae +an +an +an +ae +aZ +ac +ab +ab +ab +ab +ab +ab +ab +aA +aM +"} +(17,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aA +aA +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac +ab +ab +ab +ab +ab +ab +ab +ab +aR +ag +ag +af +ar +af +at +bb +ac +ab +ab +ab +ab +ab +ab +ab +aA +aa +"} +(18,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aA +aA +ab +ab +ab +ab +ab +ab +ab +ab +ad +ac +ac +ac +ac +ab +aH +aJ +aL +ab +ab +aT +ac +ac +ac +ac +ac +ac +ac +aR +ab +ab +ab +ab +ab +ab +ab +aA +aa +"} +(19,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aA +aA +ab +ab +ab +ab +ab +ab +ab +ab +ab +ad +au +ac +aB +am +ac +ac +ac +ac +ab +ab +ac +ac +ac +ac +ac +ac +ac +ac +bg +ab +ab +ab +ab +ab +ab +ab +aA +aa +"} +(20,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aA +aA +ab +ab +ab +ab +ab +ab +ab +ab +ab +ad +aw +bs +aC +ac +ac +ac +ac +ac +ab +ab +ab +ac +ac +ac +ac +ac +ac +ac +ab +ab +ab +ab +ab +ab +ab +ab +aA +aa +"} +(21,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aM +aa +aa +aA +aA +ab +ab +ab +ab +ab +ab +ab +ab +ab +ad +ax +ac +aD +aF +ac +ac +ac +ab +ab +ab +aU +bd +ac +ac +bl +bm +ac +ac +ab +ab +ab +ab +ab +ab +ab +ab +aA +aa +"} +(22,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aA +aA +ab +ab +ab +ab +ab +ab +ab +ab +ab +ad +ay +ac +ac +ac +aG +ac +ac +ab +ab +ab +av +be +ac +ac +ac +bn +bo +bo +bq +ab +ab +ab +ab +ab +ab +ab +aA +aa +"} +(23,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aA +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac +ac +ac +ac +ac +ac +ab +ab +ab +bc +bf +ac +ac +ac +ac +ac +ac +br +ab +ab +ab +ab +ab +ab +aA +aa +aa +"} +(24,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aA +aA +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ab +ac +ac +ac +ac +ac +ab +ab +ac +ac +ac +ac +ac +ac +ac +ac +ac +ab +ab +ab +ab +ab +ab +aA +aa +aa +"} +(25,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aA +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac +ac +ac +ac +aN +ac +ac +ac +ac +aR +ac +ac +ac +ac +ab +ab +ab +ab +ab +ab +aA +aa +aa +aa +"} +(26,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aA +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac +ac +ab +ab +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ab +ab +ab +ab +aa +aa +aa +aa +"} +(27,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aA +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aK +ab +ab +ac +ac +ac +ac +ac +ac +ac +bp +ac +ac +aR +ab +ab +ab +aA +aa +aa +aa +aM +"} +(28,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aA +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aP +ac +ac +ac +ac +ac +ac +ac +ac +ac +aR +ab +ab +ab +aA +aa +aa +aa +aa +"} +(29,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aA +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aQ +aP +ac +ac +aR +ac +ac +ac +ac +ab +ac +ab +ab +ab +aA +aa +aa +aa +aa +"} +(30,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aA +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac +ac +ac +aP +ac +bg +ab +ab +ab +ab +ab +aa +aa +aa +aa +aa +"} +(31,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aA +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac +ac +ac +ac +ac +aS +ab +ab +ab +ab +aA +aa +aa +aa +ab +aA +"} +(32,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aA +aA +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +bg +ac +ac +ac +ac +ac +aS +ab +ab +ab +ab +aA +aa +aa +aO +ab +ab +"} +(33,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aA +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac +bj +ac +ac +ac +aS +ab +ab +ab +ab +aA +aa +aA +ab +ab +ab +"} +(34,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aA +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aS +bi +ac +ac +ac +aS +aS +ab +ab +ab +ab +aA +aa +aA +ab +ab +aA +"} +(35,1,1) = {" +aa +aa +aa +aa +aa +aa +aA +aA +aa +aa +aa +aa +aM +aa +aA +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aS +ac +ac +ac +ac +aS +aS +ab +ab +ab +aA +aa +aa +aA +ab +ab +ab +"} +(36,1,1) = {" +aa +aa +aa +aa +aa +aa +ab +ab +aA +aa +aa +aa +aa +aa +aA +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aA +aS +aS +aS +bk +bk +aS +aS +aS +aS +ab +ab +aA +aa +aa +aa +ab +ab +ab +"} +(37,1,1) = {" +aa +aa +aa +aa +aa +ab +ab +ab +ab +aa +aa +aa +aa +aa +aA +aA +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aA +aA +aA +aS +aS +aS +bk +aS +aS +aS +aA +aA +ab +aA +aa +aa +aa +aa +aA +aA +"} +(38,1,1) = {" +aa +aa +aa +aa +aa +ab +ab +ab +ab +ab +aa +aa +aa +aa +aa +aA +aA +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aA +aA +ai +ai +ai +ai +ai +ai +ai +ai +aA +aA +ab +aA +aa +aa +aa +aa +aa +aa +"} +(39,1,1) = {" +aa +aa +aa +aa +aa +aA +ab +ab +ab +ab +aa +aa +aa +aa +aa +aa +aA +aA +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aA +aa +aa +aa +ai +ai +ai +aa +ai +aa +aa +aA +ab +aA +aa +aa +aa +aa +aa +aa +"} +(40,1,1) = {" +aa +aa +aa +aa +aa +aa +aA +ab +ab +aA +aa +aa +aa +aa +aa +aa +aa +aA +aA +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aa +aa +aa +aa +aa +ai +aa +aa +ab +ab +aA +aa +aa +aa +aa +aa +aa +"} +(41,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aA +aA +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aa +aa +aa +aa +aa +aa +aa +aa +ab +ab +aA +aa +aa +aa +aa +aa +aa +"} +(42,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aA +aA +aA +aA +aA +aA +aA +aA +aA +ab +ab +ab +ab +ab +aa +aa +aa +aa +aa +aa +aa +aa +ab +aa +aa +aa +aa +aM +aa +aa +aa +"} +(43,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aA +aA +aA +aA +aA +ab +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(44,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +ac +aa +aa +aa +"} +(45,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aA +aa +aa +aa +aa +aM +aa +aa +aa +aa +aa +aa +aa +aM +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aM +aa +aa +aa +aa +ac +ab +ac +aa +aa +"} +(46,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aM +ab +ab +aA +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +ab +ab +ab +aa +aa +"} +(47,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +ab +ab +ab +ab +aA +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aA +aA +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +ab +ab +ab +aa +aa +"} +(48,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aA +ab +ab +ab +ab +aa +aa +aa +aM +aa +aa +aa +aa +aa +aa +aa +aa +aa +aA +ab +aA +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +ac +ab +ac +aa +aa +"} +(49,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aA +aA +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aA +aa +aa +aa +aa +aM +aa +aa +aa +aa +aa +aa +aa +ac +aa +aa +aa +aa +"} +(50,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +ab +aa +aa +aa +aa +"} diff --git a/_maps/map_files/PubbyStation/PubbyStation.dmm b/_maps/map_files/PubbyStation/PubbyStation.dmm index f9792a736e..0dc0afcd0c 100644 --- a/_maps/map_files/PubbyStation/PubbyStation.dmm +++ b/_maps/map_files/PubbyStation/PubbyStation.dmm @@ -35713,13 +35713,13 @@ /obj/structure/extinguisher_cabinet{ pixel_x = -26 }, -/obj/machinery/rnd/production/protolathe/department/medical, /obj/effect/turf_decal/tile/blue{ dir = 1 }, /obj/effect/turf_decal/tile/blue{ dir = 4 }, +/obj/machinery/rnd/production/techfab/department/medical, /turf/open/floor/plasteel/white, /area/medical/medbay/central) "bEw" = ( diff --git a/code/__DEFINES/components.dm b/code/__DEFINES/components.dm index dbe8cfbb62..210bdf57a6 100644 --- a/code/__DEFINES/components.dm +++ b/code/__DEFINES/components.dm @@ -130,6 +130,7 @@ #define COMSIG_MOB_ITEM_AFTERATTACK "mob_item_afterattack" //from base of obj/item/afterattack(): (atom/target, mob/user, proximity_flag, click_parameters) #define COMSIG_MOB_ATTACK_RANGED "mob_attack_ranged" //from base of mob/RangedAttack(): (atom/A, params) #define COMSIG_MOB_THROW "mob_throw" //from base of /mob/throw_item(): (atom/target) +#define COMSIG_MOB_UPDATE_SIGHT "mob_update_sight" //from base of /mob/update_sight(): () // /mob/living signals #define COMSIG_LIVING_RESIST "living_resist" //from base of mob/living/resist() (/mob/living) diff --git a/code/__DEFINES/construction.dm b/code/__DEFINES/construction.dm index aa9c5cf34e..ee51fb6909 100644 --- a/code/__DEFINES/construction.dm +++ b/code/__DEFINES/construction.dm @@ -102,7 +102,7 @@ #define CAT_SANDWICH "Sandwiches" #define CAT_SOUP "Soups" #define CAT_SPAGHETTI "Spaghettis" -#define CAT_SUSHI "Fish" +#define CAT_FISH "Fish" #define CAT_ICE "Frozen" #define RCD_FLOORWALL 1 diff --git a/code/__DEFINES/food.dm b/code/__DEFINES/food.dm index 2c7a66ce40..15c7af5749 100644 --- a/code/__DEFINES/food.dm +++ b/code/__DEFINES/food.dm @@ -16,3 +16,4 @@ #define DRINK_GOOD 2 #define DRINK_VERYGOOD 3 #define DRINK_FANTASTIC 4 +#define FOOD_AMAZING 5 diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm index 19710a89fe..175f3d45ab 100644 --- a/code/__DEFINES/misc.dm +++ b/code/__DEFINES/misc.dm @@ -114,8 +114,9 @@ Will print: "/mob/living/carbon/human/death" (you can optionally embed it in a s #define TRANSITIONEDGE 7 //Distance from edge to move to another z-level -#define BE_CLOSE 1 //in the case of a silicon, to select if they need to be next to the atom -#define NO_DEXTERY 1 //if other mobs (monkeys, aliens, etc) can use this +#define BE_CLOSE TRUE //in the case of a silicon, to select if they need to be next to the atom +#define NO_DEXTERY TRUE //if other mobs (monkeys, aliens, etc) can use this +#define NO_TK TRUE //used by canUseTopic() //singularity defines diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm index 4b42595b48..1d1dda6d99 100644 --- a/code/__DEFINES/mobs.dm +++ b/code/__DEFINES/mobs.dm @@ -54,6 +54,10 @@ #define BODYPART_ORGANIC 1 #define BODYPART_ROBOTIC 2 +#define BODYPART_NOT_DISABLED 0 +#define BODYPART_DISABLED_DAMAGE 1 +#define BODYPART_DISABLED_PARALYSIS 2 + #define DEFAULT_BODYPART_ICON_ORGANIC 'icons/mob/human_parts_greyscale.dmi' #define DEFAULT_BODYPART_ICON_ROBOTIC 'icons/mob/augmentation/augments.dmi' diff --git a/code/__DEFINES/subsystems.dm b/code/__DEFINES/subsystems.dm index f54a0542f4..ecd1ef1e21 100644 --- a/code/__DEFINES/subsystems.dm +++ b/code/__DEFINES/subsystems.dm @@ -102,7 +102,6 @@ #define FIRE_PRIORITY_SPACEDRIFT 30 #define FIRE_PRIORITY_FIELDS 30 #define FIRE_PRIOTITY_SMOOTHING 35 -#define FIRE_PRIORITY_ORBIT 35 #define FIRE_PRIORITY_NETWORKS 40 #define FIRE_PRIORITY_OBJ 40 #define FIRE_PRIORITY_ACID 40 diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm index 12e222e1ef..b42cbb8f00 100644 --- a/code/__DEFINES/traits.dm +++ b/code/__DEFINES/traits.dm @@ -108,7 +108,13 @@ #define TRAIT_NOHARDCRIT "nohardcrit" #define TRAIT_NOSOFTCRIT "nosoftcrit" #define TRAIT_MINDSHIELD "mindshield" +#define TRAIT_PARALYSIS_L_ARM "para-l-arm" //These are used for brain-based paralysis, where replacing the limb won't fix it +#define TRAIT_PARALYSIS_R_ARM "para-r-arm" +#define TRAIT_PARALYSIS_L_LEG "para-l-leg" +#define TRAIT_PARALYSIS_R_LEG "para-r-leg" + //non-mob traits +#define TRAIT_PARALYSIS "paralysis" //Used for limb-based paralysis, where replacing the limb will fix it #define TRAIT_ALCOHOL_TOLERANCE "alcohol_tolerance" #define TRAIT_AGEUSIA "ageusia" @@ -130,6 +136,7 @@ #define TRAIT_CROCRIN_IMMUNE "crocin_immune" #define TRAIT_NYMPHO "nymphomania" #define TRAIT_MASO "masochism" +#define TRAIT_PARA "paraplegic" #define TRAIT_EMPATH "empath" #define TRAIT_FRIENDLY "friendly" #define TRAIT_ASSBLASTUSA "assblastusa" diff --git a/code/__HELPERS/areas.dm b/code/__HELPERS/areas.dm index f05bf6f3e1..1f5b82f7bf 100644 --- a/code/__HELPERS/areas.dm +++ b/code/__HELPERS/areas.dm @@ -86,6 +86,8 @@ newA.contents += thing thing.change_area(old_area, newA) + newA.reg_in_areas_in_z() + var/list/firedoors = oldA.firedoors for(var/door in firedoors) var/obj/machinery/door/firedoor/FD = door diff --git a/code/__HELPERS/matrices.dm b/code/__HELPERS/matrices.dm index 8b77b170e0..d96ec76a7c 100644 --- a/code/__HELPERS/matrices.dm +++ b/code/__HELPERS/matrices.dm @@ -2,7 +2,7 @@ . = new_angle - old_angle Turn(.) //BYOND handles cases such as -270, 360, 540 etc. DOES NOT HANDLE 180 TURNS WELL, THEY TWEEN AND LOOK LIKE SHIT -/atom/proc/SpinAnimation(speed = 10, loops = -1, clockwise = 1, segments = 3) +/atom/proc/SpinAnimation(speed = 10, loops = -1, clockwise = 1, segments = 3, parallel = TRUE) if(!segments) return var/segment = 360/segments @@ -18,7 +18,11 @@ speed /= segments - animate(src, transform = matrices[1], time = speed, loops) + if(parallel) + animate(src, transform = matrices[1], time = speed, loops , flags = ANIMATION_PARALLEL) + else + animate(src, transform = matrices[1], time = speed, loops) + for(var/i in 2 to segments) //2 because 1 is covered above animate(transform = matrices[i], time = speed) //doesn't have an object argument because this is "Stacking" with the animate call above diff --git a/code/__HELPERS/reagents.dm b/code/__HELPERS/reagents.dm new file mode 100644 index 0000000000..f1208abdd3 --- /dev/null +++ b/code/__HELPERS/reagents.dm @@ -0,0 +1,74 @@ +/proc/chem_recipes_do_conflict(datum/chemical_reaction/r1, datum/chemical_reaction/r2) + //do the non-list tests first, because they are cheaper + if(r1.required_container != r2.required_container) + return FALSE + if(r1.is_cold_recipe == r2.is_cold_recipe) + if(r1.required_temp != r2.required_temp) + //one reaction requires a more extreme temperature than the other, so there is no conflict + return FALSE + else + var/datum/chemical_reaction/cold_one = r1.is_cold_recipe ? r1 : r2 + var/datum/chemical_reaction/warm_one = r1.is_cold_recipe ? r2 : r1 + if(cold_one.required_temp < warm_one.required_temp) + //the range of temperatures does not overlap, so there is no conflict + return FALSE + + //find the reactions with the shorter and longer required_reagents list + var/datum/chemical_reaction/long_req + var/datum/chemical_reaction/short_req + if(r1.required_reagents.len > r2.required_reagents.len) + long_req = r1 + short_req = r2 + else if(r1.required_reagents.len < r2.required_reagents.len) + long_req = r2 + short_req = r1 + else + //if they are the same length, sort instead by the length of the catalyst list + //this is important if the required_reagents lists are the same + if(r1.required_catalysts.len > r2.required_catalysts.len) + long_req = r1 + short_req = r2 + else + long_req = r2 + short_req = r1 + + + //check if the shorter reaction list is a subset of the longer one + var/list/overlap = r1.required_reagents & r2.required_reagents + if(overlap.len != short_req.required_reagents.len) + //there is at least one reagent in the short list that is not in the long list, so there is no conflict + return FALSE + + //check to see if the shorter reaction's catalyst list is also a subset of the longer reaction's catalyst list + //if the longer reaction's catalyst list is a subset of the shorter ones, that is fine + //if the reaction lists are the same, the short reaction will have the shorter required_catalysts list, so it will register as a conflict + var/list/short_minus_long_catalysts = short_req.required_catalysts - long_req.required_catalysts + if(short_minus_long_catalysts.len) + //there is at least one unique catalyst for the short reaction, so there is no conflict + return FALSE + + //if we got this far, the longer reaction will be impossible to create if the shorter one is earlier in GLOB.chemical_reactions_list, and will require the reagents to be added in a particular order otherwise + return TRUE + +/proc/get_chemical_reaction(id) + if(!GLOB.chemical_reactions_list) + return + for(var/reagent in GLOB.chemical_reactions_list) + for(var/datum/chemical_reaction/R in GLOB.chemical_reactions_list[reagent]) + if(R.id == id) + return R + +/proc/remove_chemical_reaction(datum/chemical_reaction/R) + if(!GLOB.chemical_reactions_list || !R) + return + for(var/rid in R.required_reagents) + GLOB.chemical_reactions_list[rid] -= R + +//see build_chemical_reactions_list in holder.dm for explanations +/proc/add_chemical_reaction(datum/chemical_reaction/R) + if(!GLOB.chemical_reactions_list || !R.id || !R.required_reagents || !R.required_reagents.len) + return + var/primary_reagent = R.required_reagents[1] + if(!GLOB.chemical_reactions_list[primary_reagent]) + GLOB.chemical_reactions_list[primary_reagent] = list() + GLOB.chemical_reactions_list[primary_reagent] += R diff --git a/code/__HELPERS/time.dm b/code/__HELPERS/time.dm index 200e1f907f..b28e7b5807 100644 --- a/code/__HELPERS/time.dm +++ b/code/__HELPERS/time.dm @@ -70,3 +70,6 @@ GLOBAL_VAR_INIT(rollovercheck_last_timeofday, 0) if(hour) hourT = " and [hour] hour[(hour != 1)? "s":""]" return "[day] day[(day != 1)? "s":""][hourT][minuteT][secondT]" + +/proc/daysSince(realtimev) + return round((world.realtime - realtimev) / (24 HOURS)) diff --git a/code/controllers/subsystem/augury.dm b/code/controllers/subsystem/augury.dm index 875f1ee7d3..1b1c7bc3b7 100644 --- a/code/controllers/subsystem/augury.dm +++ b/code/controllers/subsystem/augury.dm @@ -50,7 +50,7 @@ SUBSYSTEM_DEF(augury) watchers -= w continue var/mob/dead/observer/O = w - if(biggest_doom && (!O.orbiting || O.orbiting.orbiting != biggest_doom)) + if(biggest_doom && (!O.orbiting || O.orbiting.parent != biggest_doom)) O.ManualFollow(biggest_doom) /datum/action/innate/augury diff --git a/code/controllers/subsystem/mapping.dm b/code/controllers/subsystem/mapping.dm index e9a1a0e0c6..345e3bb44c 100644 --- a/code/controllers/subsystem/mapping.dm +++ b/code/controllers/subsystem/mapping.dm @@ -257,10 +257,13 @@ GLOBAL_LIST_EMPTY(the_station_areas) /datum/controller/subsystem/mapping/proc/generate_station_area_list() var/list/station_areas_blacklist = typecacheof(list(/area/space, /area/mine, /area/ruin, /area/asteroid/nearstation)) for(var/area/A in world) - var/turf/picked = safepick(get_area_turfs(A.type)) - if(picked && is_station_level(picked.z)) - if(!(A.type in GLOB.the_station_areas) && !is_type_in_typecache(A, station_areas_blacklist)) - GLOB.the_station_areas.Add(A.type) + if (is_type_in_typecache(A, station_areas_blacklist)) + continue + if (!A.contents.len || !A.unique) + continue + var/turf/picked = A.contents[1] + if (is_station_level(picked.z)) + GLOB.the_station_areas += A.type if(!GLOB.the_station_areas.len) log_world("ERROR: Station areas list failed to generate!") @@ -502,4 +505,9 @@ GLOBAL_LIST_EMPTY(the_station_areas) clearing |= used_turfs //used turfs is an associative list, BUT, reserve_turfs() can still handle it. If the code above works properly, this won't even be needed as the turfs would be freed already. unused_turfs.Cut() used_turfs.Cut() - reserve_turfs(clearing) \ No newline at end of file + reserve_turfs(clearing) + +/datum/controller/subsystem/mapping/proc/reg_in_areas_in_z(list/areas) + for(var/B in areas) + var/area/A = B + A.reg_in_areas_in_z() diff --git a/code/controllers/subsystem/orbit.dm b/code/controllers/subsystem/orbit.dm deleted file mode 100644 index 45d280b601..0000000000 --- a/code/controllers/subsystem/orbit.dm +++ /dev/null @@ -1,44 +0,0 @@ -SUBSYSTEM_DEF(orbit) - name = "Orbits" - priority = FIRE_PRIORITY_ORBIT - wait = 2 - flags = SS_NO_INIT|SS_TICKER - - var/list/currentrun = list() - var/list/processing = list() - -/datum/controller/subsystem/orbit/stat_entry() - ..("P:[processing.len]") - - -/datum/controller/subsystem/orbit/fire(resumed = 0) - if (!resumed) - src.currentrun = processing.Copy() - - //cache for sanic speed (lists are references anyways) - var/list/currentrun = src.currentrun - - while (currentrun.len) - var/datum/orbit/O = currentrun[currentrun.len] - currentrun.len-- - if (!O) - processing -= O - if (MC_TICK_CHECK) - return - continue - if (!O.orbiter) - qdel(O) - if (MC_TICK_CHECK) - return - continue - if (O.lastprocess >= world.time) //we already checked recently - if (MC_TICK_CHECK) - return - continue - var/targetloc = get_turf(O.orbiting) - if (targetloc != O.lastloc || O.orbiter.loc != targetloc) - O.Check(targetloc) - if (MC_TICK_CHECK) - return - - diff --git a/code/controllers/subsystem/persistence.dm b/code/controllers/subsystem/persistence.dm index 978eedb62f..455b53b1df 100644 --- a/code/controllers/subsystem/persistence.dm +++ b/code/controllers/subsystem/persistence.dm @@ -28,6 +28,7 @@ SUBSYSTEM_DEF(persistence) LoadPhotoPersistence() if(CONFIG_GET(flag/use_antag_rep)) LoadAntagReputation() + LoadRandomizedRecipes() return ..() /datum/controller/subsystem/persistence/proc/LoadSatchels() @@ -206,6 +207,7 @@ SUBSYSTEM_DEF(persistence) SavePhotoPersistence() //THIS IS PERSISTENCE, NOT THE LOGGING PORTION. if(CONFIG_GET(flag/use_antag_rep)) CollectAntagReputation() + SaveRandomizedRecipes() /datum/controller/subsystem/persistence/proc/GetPhotoAlbums() var/album_path = file("data/photo_albums.json") @@ -371,3 +373,43 @@ SUBSYSTEM_DEF(persistence) fdel(FILE_ANTAG_REP) text2file(json_encode(antag_rep), FILE_ANTAG_REP) +/datum/controller/subsystem/persistence/proc/LoadRandomizedRecipes() + var/json_file = file("data/RandomizedChemRecipes.json") + var/json + if(fexists(json_file)) + json = json_decode(file2text(json_file)) + + for(var/randomized_type in subtypesof(/datum/chemical_reaction/randomized)) + var/datum/chemical_reaction/randomized/R = new randomized_type + var/loaded = FALSE + if(R.persistent && json) + var/list/recipe_data = json[R.id] + if(recipe_data && R.LoadOldRecipe(recipe_data) && (daysSince(R.created) <= R.persistence_period)) + loaded = TRUE + if(!loaded) //We do not have information for whatever reason, just generate new one + R.GenerateRecipe() + + if(!R.HasConflicts()) //Might want to try again if conflicts happened in the future. + add_chemical_reaction(R) + +/datum/controller/subsystem/persistence/proc/SaveRandomizedRecipes() + var/json_file = file("data/RandomizedChemRecipes.json") + var/list/file_data = list() + + //asert globchems done + for(var/randomized_type in subtypesof(/datum/chemical_reaction/randomized)) + var/datum/chemical_reaction/randomized/R = randomized_type + R = get_chemical_reaction(initial(R.id)) //ew, would be nice to add some simple tracking + if(R && R.persistent && R.id) + var/recipe_data = list() + recipe_data["timestamp"] = R.created + recipe_data["required_reagents"] = R.required_reagents + recipe_data["required_catalysts"] = R.required_catalysts + recipe_data["required_temp"] = R.required_temp + recipe_data["is_cold_recipe"] = R.is_cold_recipe + recipe_data["results"] = R.results + recipe_data["required_container"] = "[R.required_container]" + file_data["[R.id]"] = recipe_data + + fdel(json_file) + WRITE_FILE(json_file, json_encode(file_data)) diff --git a/code/datums/brain_damage/severe.dm b/code/datums/brain_damage/severe.dm index e790e539c8..d094c162d7 100644 --- a/code/datums/brain_damage/severe.dm +++ b/code/datums/brain_damage/severe.dm @@ -60,18 +60,68 @@ /datum/brain_trauma/severe/paralysis name = "Paralysis" - desc = "Patient's brain can no longer control its motor functions." + desc = "Patient's brain can no longer control part of its motor functions." scan_desc = "cerebral paralysis" - gain_text = "You can't feel your body anymore!" - lose_text = "You can feel your limbs again!" + gain_text = "" + lose_text = "" + var/paralysis_type + var/list/paralysis_traits = list() + //for descriptions -/datum/brain_trauma/severe/paralysis/on_life() - owner.Knockdown(200, ignore_canknockdown = TRUE) +/datum/brain_trauma/severe/paralysis/New(specific_type) + if(specific_type) + paralysis_type = specific_type + if(!paralysis_type) + paralysis_type = pick("full","left","right","arms","legs","r_arm","l_arm","r_leg","l_leg") + var/subject + switch(paralysis_type) + if("full") + subject = "your body" + paralysis_traits = list(TRAIT_PARALYSIS_L_ARM, TRAIT_PARALYSIS_R_ARM, TRAIT_PARALYSIS_L_LEG, TRAIT_PARALYSIS_R_LEG) + if("left") + subject = "the left side of your body" + paralysis_traits = list(TRAIT_PARALYSIS_L_ARM, TRAIT_PARALYSIS_L_LEG) + if("right") + subject = "the right side of your body" + paralysis_traits = list(TRAIT_PARALYSIS_R_ARM, TRAIT_PARALYSIS_R_LEG) + if("arms") + subject = "your arms" + paralysis_traits = list(TRAIT_PARALYSIS_L_ARM, TRAIT_PARALYSIS_R_ARM) + if("legs") + subject = "your legs" + paralysis_traits = list(TRAIT_PARALYSIS_L_LEG, TRAIT_PARALYSIS_R_LEG) + if("r_arm") + subject = "your right arm" + paralysis_traits = list(TRAIT_PARALYSIS_R_ARM) + if("l_arm") + subject = "your left arm" + paralysis_traits = list(TRAIT_PARALYSIS_L_ARM) + if("r_leg") + subject = "your right leg" + paralysis_traits = list(TRAIT_PARALYSIS_R_LEG) + if("l_leg") + subject = "your left leg" + paralysis_traits = list(TRAIT_PARALYSIS_L_LEG) + + gain_text = "You can't feel [subject] anymore!" + lose_text = "You can feel [subject] again!" + +/datum/brain_trauma/severe/paralysis/on_gain() ..() + for(var/X in paralysis_traits) + ADD_TRAIT(owner, X, "trauma_paralysis") + owner.update_disabled_bodyparts() /datum/brain_trauma/severe/paralysis/on_lose() - owner.SetKnockdown(0) ..() + for(var/X in paralysis_traits) + REMOVE_TRAIT(owner, X, "trauma_paralysis") + owner.update_disabled_bodyparts() + +/datum/brain_trauma/severe/paralysis/paraplegic + //can_gain = FALSE maybe breaks. + paralysis_type = "legs" + resilience = TRAUMA_RESILIENCE_ABSOLUTE /datum/brain_trauma/severe/narcolepsy name = "Narcolepsy" @@ -203,4 +253,4 @@ /datum/brain_trauma/severe/pacifism/on_lose() REMOVE_TRAIT(owner, TRAIT_PACIFISM, TRAUMA_TRAIT) - ..() \ No newline at end of file + ..() diff --git a/code/datums/components/orbiter.dm b/code/datums/components/orbiter.dm new file mode 100644 index 0000000000..301e50dc42 --- /dev/null +++ b/code/datums/components/orbiter.dm @@ -0,0 +1,156 @@ +/datum/component/orbiter + dupe_mode = COMPONENT_DUPE_UNIQUE_PASSARGS + var/list/orbiters + var/datum/callback/orbiter_spy + var/datum/callback/orbited_spy + +//radius: range to orbit at, radius of the circle formed by orbiting (in pixels) +//clockwise: whether you orbit clockwise or anti clockwise +//rotation_speed: how fast to rotate (how many ds should it take for a rotation to complete) +//rotation_segments: the resolution of the orbit circle, less = a more block circle, this can be used to produce hexagons (6 segments) triangles (3 segments), and so on, 36 is the best default. +//pre_rotation: Chooses to rotate src 90 degress towards the orbit dir (clockwise/anticlockwise), useful for things to go "head first" like ghosts +/datum/component/orbiter/Initialize(atom/movable/orbiter, radius, clockwise, rotation_speed, rotation_segments, pre_rotation) + if(!istype(orbiter) || !isatom(parent) || isarea(parent)) + return COMPONENT_INCOMPATIBLE + + orbiters = list() + orbiter_spy = CALLBACK(src, .proc/orbiter_move_react) + orbited_spy = CALLBACK(src, .proc/move_react) + + var/atom/master = parent + master.orbiters = src + + begin_orbit(orbiter, radius, clockwise, rotation_speed, rotation_segments, pre_rotation) + +/datum/component/orbiter/RegisterWithParent() + var/atom/target = parent + while(ismovableatom(target)) + RegisterSignal(target, COMSIG_MOVABLE_MOVED, orbited_spy) + target = target.loc + +/datum/component/orbiter/UnregisterFromParent() + var/atom/target = parent + while(ismovableatom(target)) + UnregisterSignal(target, COMSIG_MOVABLE_MOVED) + target = target.loc + +/datum/component/orbiter/Destroy() + var/atom/master = parent + master.orbiters = null + for(var/i in orbiters) + end_orbit(i) + orbiters = null + QDEL_NULL(orbiter_spy) + QDEL_NULL(orbited_spy) + return ..() + +/datum/component/orbiter/InheritComponent(datum/component/orbiter/newcomp, original, list/arguments) + if(arguments) + begin_orbit(arglist(arguments)) + return + // The following only happens on component transfers + orbiters += newcomp.orbiters + +/datum/component/orbiter/PostTransfer() + if(!isatom(parent) || isarea(parent) || !get_turf(parent)) + return COMPONENT_INCOMPATIBLE + move_react() + +/datum/component/orbiter/proc/begin_orbit(atom/movable/orbiter, radius, clockwise, rotation_speed, rotation_segments, pre_rotation) + if(orbiter.orbiting) + if(orbiter.orbiting == src) + orbiter.orbiting.end_orbit(orbiter, TRUE) + else + orbiter.orbiting.end_orbit(orbiter) + orbiters[orbiter] = TRUE + orbiter.orbiting = src + RegisterSignal(orbiter, COMSIG_MOVABLE_MOVED, orbiter_spy) + var/matrix/initial_transform = matrix(orbiter.transform) + + // Head first! + if(pre_rotation) + var/matrix/M = matrix(orbiter.transform) + var/pre_rot = 90 + if(!clockwise) + pre_rot = -90 + M.Turn(pre_rot) + orbiter.transform = M + + var/matrix/shift = matrix(orbiter.transform) + shift.Translate(0, radius) + orbiter.transform = shift + + orbiter.SpinAnimation(rotation_speed, -1, clockwise, rotation_segments, parallel = FALSE) + + //we stack the orbits up client side, so we can assign this back to normal server side without it breaking the orbit + orbiter.transform = initial_transform + orbiter.forceMove(get_turf(parent)) + to_chat(orbiter, "Now orbiting [parent].") + +/datum/component/orbiter/proc/end_orbit(atom/movable/orbiter, refreshing=FALSE) + if(!orbiters[orbiter]) + return + UnregisterSignal(orbiter, COMSIG_MOVABLE_MOVED) + orbiter.SpinAnimation(0, 0) + orbiters -= orbiter + orbiter.stop_orbit(src) + orbiter.orbiting = null + if(!refreshing && !length(orbiters) && !QDELING(src)) + qdel(src) + +// This proc can receive signals by either the thing being directly orbited or anything holding it +/datum/component/orbiter/proc/move_react(atom/orbited, atom/oldloc, direction) + set waitfor = FALSE // Transfer calls this directly and it doesnt care if the ghosts arent done moving + + var/atom/movable/master = parent + if(master.loc == oldloc) + return + + var/turf/newturf = get_turf(master) + if(!newturf) + qdel(src) + + // Handling the signals of stuff holding us (or not anymore) + // These are prety rarely activated, how often are you following something in a bag? + if(oldloc && !isturf(oldloc)) // We used to be registered to it, probably + var/atom/target = oldloc + while(ismovableatom(target)) + UnregisterSignal(target, COMSIG_MOVABLE_MOVED) + target = target.loc + if(orbited?.loc && orbited.loc != newturf) // We want to know when anything holding us moves too + var/atom/target = orbited.loc + while(ismovableatom(target)) + RegisterSignal(target, COMSIG_MOVABLE_MOVED, orbited_spy, TRUE) + target = target.loc + + var/atom/curloc = master.loc + for(var/i in orbiters) + var/atom/movable/thing = i + if(QDELETED(thing) || thing.loc == newturf) + continue + thing.forceMove(newturf) + if(CHECK_TICK && master.loc != curloc) + // We moved again during the checktick, cancel current operation + break + + +/datum/component/orbiter/proc/orbiter_move_react(atom/movable/orbiter, atom/oldloc, direction) + if(orbiter.loc == get_turf(parent)) + return + end_orbit(orbiter) + +///////////////////// + +/atom/movable/proc/orbit(atom/A, radius = 10, clockwise = FALSE, rotation_speed = 20, rotation_segments = 36, pre_rotation = TRUE) + if(!istype(A) || !get_turf(A) || A == src) + return + + return A.AddComponent(/datum/component/orbiter, src, radius, clockwise, rotation_speed, rotation_segments, pre_rotation) + +/atom/movable/proc/stop_orbit(datum/component/orbiter/orbits) + return // We're just a simple hook + +/atom/proc/transfer_observers_to(atom/target) + if(!orbiters || !istype(target) || !get_turf(target) || target == src) + return + target.TakeComponent(orbiters) diff --git a/code/datums/mood_events/drink_events.dm b/code/datums/mood_events/drink_events.dm index db5a91009e..5d0eb0e0cb 100644 --- a/code/datums/mood_events/drink_events.dm +++ b/code/datums/mood_events/drink_events.dm @@ -22,3 +22,8 @@ description = "That drink was amazing!\n" mood_change = 4 timeout = 1200 + +/datum/mood_event/amazingtaste + description = "Amazing taste!\n" + mood_change = 50 + timeout = 10 MINUTES diff --git a/code/datums/ruins/space.dm b/code/datums/ruins/space.dm index 23580ca5d1..f992209584 100644 --- a/code/datums/ruins/space.dm +++ b/code/datums/ruins/space.dm @@ -282,9 +282,31 @@ name = "Ancient Cloning Lab" description = "An experimental cloning lab snapped off from an ancient ship. The cloner model inside lacks many modern functionalities and security measures." - /datum/map_template/ruin/space/hilbertresearchfacility id = "hilbert_facility" suffix = "hilbertshoteltestingsite.dmm" name = "Hilbert Research Facility" description = "A research facility of great bluespace discoveries. Long since abandoned, willingly or not..." +/datum/map_template/ruin/space/augmentation + id = "augmentationfacility" + suffix = "augmentationfacility.dmm" + name = "Roboticst Augmentation Facility" + description = "A mysterious lab in the depths of space containing robotics supplies and a one use autosurgeon." + +/datum/map_template/ruin/space/harambe + id = "bigape" + suffix = "bigape.dmm" + name = "Big Ape" + description = "A gorilla? Out here? But why." + +/datum/map_template/ruin/space/space_arcade + id = "arcade" + suffix = "arcade.dmm" + name = "Space Arcade" + description = "A lonely arcade in the depths of space." + +/datum/map_template/ruin/space/hermit + id = "spacehermit" + suffix = "spacehermit.dmm" + name = "Space Hermit" + description = "A late awakening cryo pod in a crashed escape pod wakes up to find what befell of his fellow survivors. Contains all the necessary resources to actually make it out alive. Good luck." diff --git a/code/datums/traits/negative.dm b/code/datums/traits/negative.dm index 43be1fa2a7..36c6733cf7 100644 --- a/code/datums/traits/negative.dm +++ b/code/datums/traits/negative.dm @@ -38,13 +38,13 @@ var/obj/item/heirloom_type switch(quirk_holder.mind.assigned_role) if("Clown") - heirloom_type = /obj/item/paint/anycolor - heirloom_type = /obj/item/bikehorn/golden + heirloom_type = pick(/obj/item/paint/anycolor, /obj/item/bikehorn/golden) if("Mime") - heirloom_type = /obj/item/paint/anycolor - heirloom_type = /obj/item/toy/dummy + heirloom_type = pick(/obj/item/paint/anycolor, /obj/item/toy/dummy) if("Cook") heirloom_type = /obj/item/kitchen/knife/scimitar + if("Botanist") + heirloom_type = pick(/obj/item/cultivator, /obj/item/reagent_containers/glass/bucket, /obj/item/storage/bag/plants, /obj/item/toy/plush/beeplushie) if("Medical Doctor") heirloom_type = /obj/item/healthanalyzer/advanced if("Station Engineer") @@ -187,6 +187,41 @@ to_chat(quirk_holder, "Your antagonistic nature has caused you to renounce your pacifism.") qdel(src) +/datum/quirk/paraplegic + name = "Paraplegic" + desc = "Your legs do not function. Nothing will ever fix this. But hey, free wheelchair!" + value = -3 + mob_trait = TRAIT_PARA + human_only = TRUE + gain_text = null // Handled by trauma. + lose_text = null + medical_record_text = "Patient has an untreatable impairment in motor function in the lower extremities." + +/datum/quirk/paraplegic/add() + var/datum/brain_trauma/severe/paralysis/paraplegic/T = new() + var/mob/living/carbon/human/H = quirk_holder + H.gain_trauma(T, TRAUMA_RESILIENCE_ABSOLUTE) + +/datum/quirk/paraplegic/on_spawn() + if(quirk_holder.buckled) // Handle late joins being buckled to arrival shuttle chairs. + quirk_holder.buckled.unbuckle_mob(quirk_holder) + + var/turf/T = get_turf(quirk_holder) + var/obj/structure/chair/spawn_chair = locate() in T + + var/obj/vehicle/ridden/wheelchair/wheels = new(T) + if(spawn_chair) // Makes spawning on the arrivals shuttle more consistent looking + wheels.setDir(spawn_chair.dir) + + wheels.buckle_mob(quirk_holder) + + // During the spawning process, they may have dropped what they were holding, due to the paralysis + // So put the things back in their hands. + + for(var/obj/item/I in T) + if(I.fingerprintslast == quirk_holder.ckey) + quirk_holder.put_in_hands(I) + /datum/quirk/poor_aim name = "Poor Aim" desc = "You're terrible with guns and can't line up a straight shot to save your life. Dual-wielding is right out." @@ -208,8 +243,12 @@ var/slot_string = "limb" /datum/quirk/prosthetic_limb/on_spawn() - var/limb_slot = pick(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG) var/mob/living/carbon/human/H = quirk_holder + var/limb_slot + if(HAS_TRAIT(H, TRAIT_PARA))//Prevent paraplegic legs being replaced + limb_slot = pick(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM) + else + limb_slot = pick(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG) var/obj/item/bodypart/old_part = H.get_bodypart(limb_slot) var/obj/item/bodypart/prosthetic switch(limb_slot) diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm index 10650153d6..dfbb59811b 100644 --- a/code/game/area/areas.dm +++ b/code/game/area/areas.dm @@ -76,7 +76,9 @@ GLOBAL_LIST_EMPTY(teleportlocs) continue if(GLOB.teleportlocs[AR.name]) continue - var/turf/picked = safepick(get_area_turfs(AR.type)) + if (!AR.contents.len) + continue + var/turf/picked = AR.contents[1] if (picked && is_station_level(picked.z)) GLOB.teleportlocs[AR.name] = AR @@ -120,6 +122,14 @@ GLOBAL_LIST_EMPTY(teleportlocs) if(!IS_DYNAMIC_LIGHTING(src)) add_overlay(/obj/effect/fullbright) + reg_in_areas_in_z() + + return INITIALIZE_HINT_LATELOAD + +/area/LateInitialize() + power_change() // all machines set to current power level, also updates icon + +/area/proc/reg_in_areas_in_z() if(contents.len) var/list/areas_in_z = SSmapping.areas_in_z var/z @@ -137,11 +147,6 @@ GLOBAL_LIST_EMPTY(teleportlocs) areas_in_z["[z]"] = list() areas_in_z["[z]"] += src - return INITIALIZE_HINT_LATELOAD - -/area/LateInitialize() - power_change() // all machines set to current power level, also updates icon - /area/Destroy() if(GLOB.areas_by_type[type] == src) GLOB.areas_by_type[type] = null diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 81e2371f9a..f2eb23808e 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -31,6 +31,8 @@ var/list/filter_data //For handling persistent filters + var/datum/component/orbiter/orbiters + var/rad_flags = NONE // Will move to flags_1 when i can be arsed to var/rad_insulation = RAD_NO_INSULATION diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index c37c120b93..f88f4f8e41 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -31,6 +31,7 @@ var/atom/movable/pulling var/grab_state = 0 var/throwforce = 0 + var/datum/component/orbiter/orbiting var/can_be_z_moved = TRUE /atom/movable/vv_edit_var(var_name, var_value) @@ -296,14 +297,7 @@ if (length(client_mobs_in_contents)) update_parallax_contents() - if (orbiters) - for (var/thing in orbiters) - var/datum/orbit/O = thing - O.Check() - if (orbiting) - orbiting.Check() - - return 1 + return TRUE /atom/movable/Destroy(force) QDEL_NULL(proximity_monitor) @@ -325,6 +319,10 @@ if(pulledby) pulledby.stop_pulling() + if(orbiting) + orbiting.end_orbit(src) + orbiting = null + // Make sure you know what you're doing if you call this, this is intended to only be called by byond directly. // You probably want CanPass() /atom/movable/Cross(atom/movable/AM) diff --git a/code/game/machinery/computer/arcade.dm b/code/game/machinery/computer/arcade.dm index efbbe36228..7f2fef18ac 100644 --- a/code/game/machinery/computer/arcade.dm +++ b/code/game/machinery/computer/arcade.dm @@ -1,7 +1,7 @@ #define ARCADE_WEIGHT_TRICK 4 #define ARCADE_WEIGHT_USELESS 2 #define ARCADE_WEIGHT_RARE 1 -#define ARCADE_WEIGHT_PLUSH 3 +#define ARCADE_WEIGHT_PLUSH 65 /obj/machinery/computer/arcade @@ -32,7 +32,6 @@ /obj/item/toy/spinningtoy = ARCADE_WEIGHT_TRICK, /obj/item/toy/sword = ARCADE_WEIGHT_TRICK, /obj/item/toy/sword/cx = ARCADE_WEIGHT_TRICK, - /obj/item/toy/sword/darksabre = ARCADE_WEIGHT_TRICK, /obj/item/toy/talking/AI = ARCADE_WEIGHT_USELESS, /obj/item/toy/talking/codex_gigas = ARCADE_WEIGHT_USELESS, /obj/item/toy/talking/griffin = ARCADE_WEIGHT_USELESS, diff --git a/code/game/machinery/dance_machine.dm b/code/game/machinery/dance_machine.dm index 7beb32eebb..1c6d713437 100644 --- a/code/game/machinery/dance_machine.dm +++ b/code/game/machinery/dance_machine.dm @@ -214,11 +214,11 @@ sparkles += S switch(i) if(1 to 8) - S.orbit(src, 30, TRUE, 60, 36, TRUE, FALSE) + S.orbit(src, 30, TRUE, 60, 36, TRUE) if(9 to 16) - S.orbit(src, 62, TRUE, 60, 36, TRUE, FALSE) + S.orbit(src, 62, TRUE, 60, 36, TRUE) if(17 to 24) - S.orbit(src, 95, TRUE, 60, 36, TRUE, FALSE) + S.orbit(src, 95, TRUE, 60, 36, TRUE) if(25) S.pixel_y = 7 S.forceMove(get_turf(src)) diff --git a/code/game/machinery/suit_storage_unit.dm b/code/game/machinery/suit_storage_unit.dm index b84db2ca8d..90166dacf0 100644 --- a/code/game/machinery/suit_storage_unit.dm +++ b/code/game/machinery/suit_storage_unit.dm @@ -51,6 +51,7 @@ /obj/machinery/suit_storage_unit/security suit_type = /obj/item/clothing/suit/space/hardsuit/security mask_type = /obj/item/clothing/mask/gas/sechailer + storage_type = /obj/item/tank/jetpack/oxygen/security /obj/machinery/suit_storage_unit/hos suit_type = /obj/item/clothing/suit/space/hardsuit/security/hos diff --git a/code/game/objects/items/devices/PDA/PDA.dm b/code/game/objects/items/devices/PDA/PDA.dm index 48b21d58bd..5d4984b321 100644 --- a/code/game/objects/items/devices/PDA/PDA.dm +++ b/code/game/objects/items/devices/PDA/PDA.dm @@ -171,12 +171,16 @@ GLOBAL_LIST_EMPTY(PDAs) overlay.icon_state = "pai_off_overlay" add_overlay(new /mutable_appearance(overlay)) -/obj/item/pda/MouseDrop(obj/over_object, src_location, over_location) +/obj/item/pda/MouseDrop(mob/over, src_location, over_location) var/mob/M = usr - if((!istype(over_object, /obj/screen)) && usr.canUseTopic(src)) + if((M == over) && usr.canUseTopic(src, BE_CLOSE, FALSE, NO_TK)) return attack_self(M) return ..() +/obj/item/pda/attack_self_tk(mob/user) + to_chat(user, "The PDA's capacitive touch screen doesn't seem to respond!") + return + /obj/item/pda/interact(mob/user) if(!user.IsAdvancedToolUser()) to_chat(user, "You don't have the dexterity to do this!") @@ -382,7 +386,7 @@ GLOBAL_LIST_EMPTY(PDAs) var/mob/living/U = usr //Looking for master was kind of pointless since PDAs don't appear to have one. - if(usr.canUseTopic(src) && !href_list["close"]) + if(usr.canUseTopic(src, BE_CLOSE, FALSE, NO_TK) && !href_list["close"]) add_fingerprint(U) U.set_machine(src) @@ -636,7 +640,7 @@ GLOBAL_LIST_EMPTY(PDAs) /obj/item/pda/proc/remove_id() - if(issilicon(usr) || !usr.canUseTopic(src, BE_CLOSE)) + if(issilicon(usr) || !usr.canUseTopic(src, BE_CLOSE, FALSE, NO_TK)) return if (id) @@ -802,7 +806,7 @@ GLOBAL_LIST_EMPTY(PDAs) /obj/item/pda/proc/remove_pen() - if(issilicon(usr) || !usr.canUseTopic(src, BE_CLOSE)) + if(issilicon(usr) || !usr.canUseTopic(src, BE_CLOSE, FALSE, NO_TK)) return if(inserted_item) diff --git a/code/game/objects/items/devices/flashlight.dm b/code/game/objects/items/devices/flashlight.dm index 40f2059d25..d8b539ac27 100644 --- a/code/game/objects/items/devices/flashlight.dm +++ b/code/game/objects/items/devices/flashlight.dm @@ -13,7 +13,8 @@ actions_types = list(/datum/action/item_action/toggle_light) var/on = FALSE var/brightness_on = 4 //range of light when on - var/flashlight_power = 1 //strength of the light when on + var/flashlight_power = 0.8 //strength of the light when on + light_color = "#FFCC66" /obj/item/flashlight/Initialize() . = ..() @@ -63,7 +64,7 @@ to_chat(user, "[M] doesn't have a head!") return - if(flashlight_power < 1) + if(flashlight_power < 0.3) to_chat(user, "\The [src] isn't bright enough to see anything! ") return @@ -168,6 +169,8 @@ item_state = "" flags_1 = CONDUCT_1 brightness_on = 2 + light_color = "#FFDDCC" + flashlight_power = 0.3 var/holo_cooldown = 0 /obj/item/flashlight/pen/afterattack(atom/target, mob/user, proximity_flag) @@ -204,6 +207,8 @@ righthand_file = 'icons/mob/inhands/equipment/security_righthand.dmi' force = 9 // Not as good as a stun baton. brightness_on = 5 // A little better than the standard flashlight. + light_color = "#CDDDFF" + flashlight_power = 0.9 hitsound = 'sound/weapons/genhit1.ogg' // the desk lamps are a bit special @@ -216,6 +221,7 @@ righthand_file = 'icons/mob/inhands/items_righthand.dmi' force = 10 brightness_on = 5 + light_color = "#FFDDBB" w_class = WEIGHT_CLASS_BULKY flags_1 = CONDUCT_1 materials = list() @@ -252,6 +258,7 @@ desc = "A red Nanotrasen issued flare. There are instructions on the side, it reads 'pull cord, make light'." w_class = WEIGHT_CLASS_SMALL brightness_on = 7 // Pretty bright. + light_color = "#FA421A" icon_state = "flare" item_state = "flare" actions_types = list() @@ -325,6 +332,7 @@ desc = "A torch fashioned from some leaves and a log." w_class = WEIGHT_CLASS_BULKY brightness_on = 4 + light_color = "#FAA44B" icon_state = "torch" item_state = "torch" lefthand_file = 'icons/mob/inhands/items_lefthand.dmi' @@ -341,6 +349,8 @@ righthand_file = 'icons/mob/inhands/equipment/mining_righthand.dmi' desc = "A mining lantern." brightness_on = 6 // luminosity when on + light_color = "#FFAA44" + flashlight_power = 0.75 /obj/item/flashlight/slime @@ -354,6 +364,8 @@ slot_flags = ITEM_SLOT_BELT materials = list() brightness_on = 6 //luminosity when on + light_color = "#FFEEAA" + flashlight_power = 0.6 /obj/item/flashlight/emp var/emp_max_charges = 4 @@ -517,6 +529,7 @@ icon_state = null light_color = null brightness_on = 0 + flashlight_power = 1 light_range = 0 light_power = 10 alpha = 0 @@ -538,7 +551,6 @@ name = "eyelight" desc = "This shouldn't exist outside of someone's head, how are you seeing this?" brightness_on = 15 - flashlight_power = 1 flags_1 = CONDUCT_1 item_flags = DROPDEL actions_types = list() diff --git a/code/game/objects/items/extinguisher.dm b/code/game/objects/items/extinguisher.dm index 882a50b3ba..9fb4206845 100644 --- a/code/game/objects/items/extinguisher.dm +++ b/code/game/objects/items/extinguisher.dm @@ -110,7 +110,7 @@ to_chat(user, "The safety is [safety ? "on" : "off"].") if(reagents.total_volume) - to_chat(user, "Alt-click to empty it.") + to_chat(user, "You can loose its screws to empty it.") /obj/item/extinguisher/proc/AttemptRefill(atom/target, mob/user) if(istype(target, tanktype) && target.Adjacent(user)) @@ -244,7 +244,7 @@ var/turf/open/theturf = T theturf.MakeSlippery(TURF_WET_WATER, min_wet_time = 10 SECONDS, wet_time_to_add = 5 SECONDS) - user.visible_message("[user] empties out \the [src] onto the floor using the release valve.", "You quietly empty out \the [src] using its release valve.") + user.visible_message("[user] empties out \the [src] onto the floor using the release valve.", "You quietly empty out \the [src] by loosing the release valve's screws.") //firebot assembly /obj/item/extinguisher/attackby(obj/O, mob/user, params) diff --git a/code/game/objects/items/granters.dm b/code/game/objects/items/granters.dm index 8d0d8d020e..34ce6bc521 100644 --- a/code/game/objects/items/granters.dm +++ b/code/game/objects/items/granters.dm @@ -87,6 +87,33 @@ active = FALSE UpdateButtonIcon() +/obj/item/book/granter/action/origami + granted_action = /datum/action/innate/origami + name = "The Art of Origami" + desc = "A meticulously in-depth manual explaining the art of paper folding." + icon_state = "origamibook" + actionname = "origami" + oneuse = TRUE + remarks = list("Dead-stick stability...", "Symmetry seems to play a rather large factor...", "Accounting for crosswinds... really?", "Drag coefficients of various paper types...", "Thrust to weight ratios?", "Positive dihedral angle?", "Center of gravity forward of the center of lift...") + +/datum/action/innate/origami + name = "Origami Folding" + desc = "Toggles your ability to fold and catch robust paper airplanes." + button_icon_state = "origami_off" + check_flags = NONE + +/datum/action/innate/origami/Activate() + to_chat(owner, "You will now fold origami planes.") + button_icon_state = "origami_on" + active = TRUE + UpdateButtonIcon() + +/datum/action/innate/origami/Deactivate() + to_chat(owner, "You will no longer fold origami planes.") + button_icon_state = "origami_off" + active = FALSE + UpdateButtonIcon() + ///SPELLS/// /obj/item/book/granter/spell diff --git a/code/game/objects/items/implants/implant_misc.dm b/code/game/objects/items/implants/implant_misc.dm index 889f702ee7..3a4295c61e 100644 --- a/code/game/objects/items/implants/implant_misc.dm +++ b/code/game/objects/items/implants/implant_misc.dm @@ -33,7 +33,7 @@ /obj/item/implant/adrenalin/activate() . = ..() uses-- - imp_in.do_adrenaline(150, TRUE, 0, 0, TRUE, list("inaprovaline" = 3, "synaptizine" = 10, "omnizine" = 10, "stimulants" = 10), "You feel a sudden surge of energy!") + imp_in.do_adrenaline(150, TRUE, 0, 0, TRUE, list("inaprovaline" = 3, "synaptizine" = 10, "regen_jelly" = 10, "stimulants" = 10), "You feel a sudden surge of energy!") to_chat(imp_in, "You feel a sudden surge of energy!") if(!uses) qdel(src) diff --git a/code/game/objects/items/plushes.dm b/code/game/objects/items/plushes.dm index 9528bf94ba..12de29c76e 100644 --- a/code/game/objects/items/plushes.dm +++ b/code/game/objects/items/plushes.dm @@ -613,6 +613,20 @@ icon_state = "plushie_awake" item_state = "plushie_awake" +/obj/item/toy/plush/awakenedplushie/ComponentInitialize() + . = ..() + AddComponent(/datum/component/edit_complainer) + + +/obj/item/toy/plush/beeplushie + name = "bee plushie" + desc = "A cute toy that resembles an even cuter bee." + icon_state = "plushie_h" + item_state = "plushie_h" + attack_verb = list("stung") + gender = FEMALE + squeak_override = list('modular_citadel/sound/voice/scream_moth.ogg' = 1) + /obj/item/toy/plush/mothplushie name = "insect plushie" desc = "An adorable stuffed toy that resembles some kind of insect" @@ -904,7 +918,3 @@ item_state = "fermis" attack_verb = list("cuddled", "petpatted", "wigglepurred") squeak_override = list('modular_citadel/sound/voice/merowr.ogg' = 1) - -/obj/item/toy/plush/awakenedplushie/ComponentInitialize() - . = ..() - AddComponent(/datum/component/edit_complainer) diff --git a/code/game/objects/items/shields.dm b/code/game/objects/items/shields.dm index b641e15d90..a9f0e038df 100644 --- a/code/game/objects/items/shields.dm +++ b/code/game/objects/items/shields.dm @@ -20,7 +20,6 @@ attack_verb = list("shoved", "bashed") var/cooldown = 0 //shield bash cooldown. based on world.time - /obj/item/shield/riot/attackby(obj/item/W, mob/user, params) if(istype(W, /obj/item/melee/baton)) if(cooldown < world.time - 25) @@ -166,3 +165,14 @@ block_chance = 25 force = 5 throwforce = 7 + +/obj/item/shield/riot/tower + name = "tower shield" + desc = "A massive shield that can block a lot of attacks, can take a lot of abuse before braking." + armor = list("melee" = 95, "bullet" = 95, "laser" = 75, "energy" = 60, "bomb" = 90, "bio" = 90, "rad" = 0, "fire" = 90, "acid" = 10) //Armor for the item, dosnt transfer to user + item_state = "metal" + block_chance = 75 //1/4 shots will hit* + force = 10 + slowdown = 2 + throwforce = 15 //Massive pice of metal + w_class = WEIGHT_CLASS_HUGE diff --git a/code/game/objects/items/stacks/sheets/sheet_types.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm index 050e4f7b15..b17bc87ffd 100644 --- a/code/game/objects/items/stacks/sheets/sheet_types.dm +++ b/code/game/objects/items/stacks/sheets/sheet_types.dm @@ -409,8 +409,10 @@ GLOBAL_LIST_INIT(brass_recipes, list ( \ new/datum/stack_recipe("brass pinion airlock - windowed", /obj/machinery/door/airlock/clockwork/brass, 5, time = 50, one_per_turf = TRUE, on_floor = TRUE), \ new/datum/stack_recipe("brass windoor", /obj/machinery/door/window/clockwork, 2, time = 30, on_floor = TRUE, window_checks = TRUE), \ null, - new/datum/stack_recipe("directional brass window", /obj/structure/window/reinforced/clockwork/unanchored, time = 0, on_floor = TRUE, window_checks = TRUE), \ - new/datum/stack_recipe("fulltile brass window", /obj/structure/window/reinforced/clockwork/fulltile/unanchored, 2, time = 0, on_floor = TRUE, window_checks = TRUE), \ + new/datum/stack_recipe("brass reflector", /obj/structure/destructible/clockwork/reflector, 10, time = 100, one_per_turf = TRUE, on_floor = TRUE, window_checks = TRUE), \ + null, + new/datum/stack_recipe("brass window - directional", /obj/structure/window/reinforced/clockwork/unanchored, time = 0, on_floor = TRUE, window_checks = TRUE), \ + new/datum/stack_recipe("brass window - fulltile", /obj/structure/window/reinforced/clockwork/fulltile/unanchored, 2, time = 0, on_floor = TRUE, window_checks = TRUE), \ new/datum/stack_recipe("brass chair", /obj/structure/chair/brass, 1, time = 0, one_per_turf = TRUE, on_floor = TRUE), \ new/datum/stack_recipe("brass table frame", /obj/structure/table_frame/brass, 1, time = 5, one_per_turf = TRUE, on_floor = TRUE), \ null, diff --git a/code/game/objects/items/storage/backpack.dm b/code/game/objects/items/storage/backpack.dm index 8178f0390a..c2929dafbd 100644 --- a/code/game/objects/items/storage/backpack.dm +++ b/code/game/objects/items/storage/backpack.dm @@ -589,3 +589,16 @@ new /obj/item/clothing/mask/gas/clown_hat(src) new /obj/item/bikehorn(src) new /obj/item/implanter/sad_trombone(src) + +obj/item/storage/backpack/duffelbag/syndie/shredderbundle + desc = "A large duffel bag containing two CX Shredders, some magazines, an elite hardsuit, and a chest rig." + +/obj/item/storage/backpack/duffelbag/syndie/shredderbundle/PopulateContents() + new /obj/item/ammo_box/magazine/flechette/shredder(src) + new /obj/item/ammo_box/magazine/flechette/shredder(src) + new /obj/item/ammo_box/magazine/flechette/shredder(src) + new /obj/item/ammo_box/magazine/flechette/shredder(src) + new /obj/item/gun/ballistic/automatic/flechette/shredder(src) + new /obj/item/gun/ballistic/automatic/flechette/shredder(src) + new /obj/item/storage/belt/military(src) + new /obj/item/clothing/suit/space/hardsuit/syndi/elite(src) diff --git a/code/game/objects/items/storage/belt.dm b/code/game/objects/items/storage/belt.dm index 57c77e5983..beb62d0ed1 100755 --- a/code/game/objects/items/storage/belt.dm +++ b/code/game/objects/items/storage/belt.dm @@ -541,6 +541,25 @@ /obj/item/ammo_casing/shotgun )) +/obj/item/storage/belt/medolier + name = "medolier" + desc = "A medical bandolier for holding smartdarts." + icon_state = "medolier" + item_state = "medolier" + +/obj/item/storage/belt/medolier/ComponentInitialize() + . = ..() + GET_COMPONENT(STR, /datum/component/storage) + STR.max_items = 15 + STR.display_numerical_stacking = FALSE + STR.can_hold = typecacheof(list( + /obj/item/reagent_containers/syringe/dart + )) + +/obj/item/storage/belt/medolier/full/PopulateContents() + for(var/i in 1 to 16) + new /obj/item/reagent_containers/syringe/dart/(src) + /obj/item/storage/belt/holster name = "shoulder holster" desc = "A holster to carry a handgun and ammo. WARNING: Badasses only." diff --git a/code/game/objects/items/storage/boxes.dm b/code/game/objects/items/storage/boxes.dm index ffeef0c8df..43611ee4e1 100644 --- a/code/game/objects/items/storage/boxes.dm +++ b/code/game/objects/items/storage/boxes.dm @@ -722,7 +722,7 @@ new /obj/item/ammo_casing/shotgun/rubbershot(src) /obj/item/storage/box/lethalshot - name = "box of lethal shotgun shots" + name = "box of buckshot (Lethal)" desc = "A box full of lethal shots, designed for riot shotguns." icon_state = "lethalshot_box" illustration = null @@ -749,7 +749,7 @@ /obj/item/storage/box/lethalslugs/PopulateContents() for(var/i in 1 to 7) - new /obj/item/projectile/bullet/shotgun_slug(src) + new /obj/item/ammo_casing/shotgun(src) /obj/item/storage/box/stunslug name = "box of stun slugs" @@ -759,7 +759,7 @@ /obj/item/storage/box/stunslug/PopulateContents() for(var/i in 1 to 7) - new /obj/item/projectile/bullet/shotgun_stunslug(src) + new /obj/item/ammo_casing/shotgun/stunslug(src) /obj/item/storage/box/techsslug name = "box of tech shotgun shells" @@ -773,11 +773,11 @@ /obj/item/storage/box/fireshot name = "box of incendiary ammo" - desc = "A box full of tech incendiary ammo." + desc = "A box full of incendiary ammo." icon_state = "fireshot_box" illustration = null -/obj/item/storage/box/techsslug/PopulateContents() +/obj/item/storage/box/fireshot/PopulateContents() for(var/i in 1 to 7) new /obj/item/ammo_casing/shotgun/incendiary(src) diff --git a/code/game/objects/items/storage/briefcase.dm b/code/game/objects/items/storage/briefcase.dm index 1f80cec0f5..46676b5adb 100644 --- a/code/game/objects/items/storage/briefcase.dm +++ b/code/game/objects/items/storage/briefcase.dm @@ -80,6 +80,21 @@ new /obj/item/ammo_box/magazine/sniper_rounds/soporific(src) new /obj/item/suppressor/specialoffer(src) + +/obj/item/storage/briefcase/modularbundle + desc = "It's label reads genuine hardened Captain leather, but suspiciously has no other tags or branding." + force = 10 + +/obj/item/storage/briefcase/modularbundle/PopulateContents() + new /obj/item/gun/ballistic/automatic/pistol/modular(src) + new /obj/item/suppressor(src) + new /obj/item/ammo_box/magazine/m10mm(src) + new /obj/item/ammo_box/magazine/m10mm/soporific(src) + new /obj/item/ammo_box/c10mm/soporific(src) + new /obj/item/clothing/under/lawyer/blacksuit(src) + new /obj/item/clothing/accessory/waistcoat(src) + new /obj/item/clothing/suit/toggle/lawyer/black/syndie(src) + /obj/item/storage/briefcase/medical name = "medical briefcase" icon_state = "medbriefcase" @@ -89,3 +104,4 @@ new /obj/item/clothing/neck/stethoscope(src) new /obj/item/healthanalyzer(src) ..() //In case of paperwork + diff --git a/code/game/objects/items/storage/firstaid.dm b/code/game/objects/items/storage/firstaid.dm index 1a666ce921..e9b074d40c 100644 --- a/code/game/objects/items/storage/firstaid.dm +++ b/code/game/objects/items/storage/firstaid.dm @@ -320,3 +320,46 @@ /obj/item/storage/pill_bottle/penis_enlargement/PopulateContents() for(var/i in 1 to 7) new /obj/item/reagent_containers/pill/penis_enlargement(src) + +///////////// +//Organ Box// +///////////// + +/obj/item/storage/belt/organbox + name = "Organ Storge" + desc = "A compact box that helps hold massive amounts of implants, organs, and some tools. Has a belt clip for easy carrying" + w_class = WEIGHT_CLASS_BULKY + icon = 'icons/obj/mysterybox.dmi' + icon_state = "organbox_open" + lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi' + throw_speed = 1 + throw_range = 1 + +/obj/item/storage/belt/organbox/ComponentInitialize() + . = ..() + GET_COMPONENT(STR, /datum/component/storage) + STR.max_items = 16 + STR.max_w_class = WEIGHT_CLASS_BULKY + STR.max_combined_w_class = 20 + STR.can_hold = typecacheof(list( + /obj/item/storage/pill_bottle, + /obj/item/reagent_containers/hypospray, + /obj/item/healthanalyzer, + /obj/item/reagent_containers/syringe, + /obj/item/clothing/glasses/hud/health, + /obj/item/hemostat, + /obj/item/scalpel, + /obj/item/retractor, + /obj/item/cautery, + /obj/item/surgical_drapes, + /obj/item/autosurgeon, + /obj/item/organ, + /obj/item/implant, + /obj/item/implantpad, + /obj/item/implantcase, + /obj/item/implanter, + /obj/item/circuitboard/computer/operating, + /obj/item/stack/sheet/mineral/silver, + /obj/item/organ_storage + )) diff --git a/code/game/objects/items/storage/toolbox.dm b/code/game/objects/items/storage/toolbox.dm index 9b8d2b4a21..cf220cb415 100644 --- a/code/game/objects/items/storage/toolbox.dm +++ b/code/game/objects/items/storage/toolbox.dm @@ -183,6 +183,22 @@ slab_type = /obj/item/clockwork/slab/debug fabricator_type = /obj/item/clockwork/replica_fabricator/scarab/debug +/obj/item/storage/toolbox/durasteel + name = "durasteel toolbox" + desc = "A toolbox made out of durasteel. Probably packs a massive punch." + total_mass = 5 + icon_state = "blue" + item_state = "toolbox_blue" + w_class = WEIGHT_CLASS_HUGE //heyo no bohing this! + force = 18 //spear damage + +/obj/item/storage/toolbox/durasteel/afterattack(atom/A, mob/user, proximity) + . = ..() + if(proximity && isobj(A) && !isitem(A)) + var/obj/O = A + //50 total object damage but split up for stuff like damage deflection. + O.take_damage(22) + O.take_damage(10) /obj/item/storage/toolbox/artistic name = "artistic toolbox" diff --git a/code/game/objects/items/storage/uplink_kits.dm b/code/game/objects/items/storage/uplink_kits.dm index 69c8f7aee9..a6a3cea373 100644 --- a/code/game/objects/items/storage/uplink_kits.dm +++ b/code/game/objects/items/storage/uplink_kits.dm @@ -2,7 +2,7 @@ /obj/item/storage/box/syndicate/PopulateContents() switch (pickweight(list("bloodyspai" = 3, "stealth" = 2, "bond" = 2, "screwed" = 2, "sabotage" = 3, "guns" = 2, "murder" = 2, "implant" = 1, "hacker" = 3, "darklord" = 1, "sniper" = 1, "metaops" = 1, "ninja" = 1))) - if("bloodyspai") // 27 tc now this is more right + if("bloodyspai") // 30 tc now this is more right new /obj/item/clothing/under/chameleon(src) // 2 tc since it's not the full set new /obj/item/clothing/mask/chameleon(src) // Goes with above new /obj/item/card/id/syndicate(src) // 2 tc @@ -11,7 +11,7 @@ new /obj/item/multitool/ai_detect(src) // 1 tc new /obj/item/encryptionkey/syndicate(src) // 2 tc new /obj/item/reagent_containers/syringe/mulligan(src) // 4 tc - new /obj/item/switchblade(src) //I'll count this as 2 tc + new /obj/item/switchblade(src) //I'll count this as 5 tc new /obj/item/storage/fancy/cigarettes/cigpack_syndicate (src) // 2 tc this shit heals new /obj/item/flashlight/emp(src) // 2 tc new /obj/item/chameleon(src) // 7 tc @@ -25,13 +25,13 @@ new /obj/item/clothing/glasses/thermal/syndi(src) if("bond") // 29 tc - new /obj/item/gun/ballistic/automatic/pistol(src) - new /obj/item/suppressor(src) + new /obj/item/gun/ballistic/automatic/pistol/suppressed(src) new /obj/item/ammo_box/magazine/m10mm(src) new /obj/item/ammo_box/magazine/m10mm(src) new /obj/item/clothing/under/chameleon(src) new /obj/item/card/id/syndicate(src) new /obj/item/reagent_containers/syringe/stimulants(src) + new /obj/item/clothing/neck/tie/red(src) if("screwed") // 29 tc new /obj/item/sbeacondrop/bomb(src) @@ -41,7 +41,7 @@ new /obj/item/clothing/head/helmet/space/syndicate/black/red(src) new /obj/item/encryptionkey/syndicate(src) - if("guns") // 28 tc now + if("guns") // 30 tc now new /obj/item/gun/ballistic/revolver(src) new /obj/item/ammo_box/a357(src) new /obj/item/ammo_box/a357(src) @@ -50,39 +50,53 @@ 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) + new /obj/item/screwdriver/power(src) //2 tc item - if("murder") // 28 tc now + if("murder") // 35 tc now new /obj/item/melee/transforming/energy/sword/saber(src) new /obj/item/clothing/glasses/thermal/syndi(src) new /obj/item/card/emag(src) new /obj/item/clothing/shoes/chameleon/noslip(src) new /obj/item/encryptionkey/syndicate(src) new /obj/item/grenade/syndieminibomb(src) + new /obj/item/clothing/glasses/phantomthief/syndicate(src) + new /obj/item/reagent_containers/syringe/stimulants(src) - if("implant") // 55+ tc holy shit what the fuck this is a lottery disguised as fun boxes isn't it? + if("implant") // 67+ tc holy shit what the fuck this is a lottery disguised as fun boxes isn't it? new /obj/item/implanter/freedom(src) new /obj/item/implanter/uplink/precharged(src) new /obj/item/implanter/emp(src) new /obj/item/implanter/adrenalin(src) new /obj/item/implanter/explosive(src) new /obj/item/implanter/storage(src) + new /obj/item/implanter/radio/syndicate(src) + new /obj/item/implanter/stealth(src) - if("hacker") // 26 tc + if("hacker") // 30 tc new /obj/item/aiModule/syndicate(src) new /obj/item/card/emag(src) new /obj/item/encryptionkey/binary(src) new /obj/item/aiModule/toyAI(src) new /obj/item/multitool/ai_detect(src) + new /obj/item/flashlight/emp(src) + new /obj/item/emagrecharge(src) - if("lordsingulo") // 24 tc - new /obj/item/sbeacondrop(src) - new /obj/item/clothing/suit/space/syndicate/black/red(src) - new /obj/item/clothing/head/helmet/space/syndicate/black/red(src) - new /obj/item/card/emag(src) + if("lordsingulo") // "36" tc aka 23 tc + new /obj/item/sbeacondrop(src) // 14 kinda useless + new /obj/item/clothing/suit/space/syndicate/black/red(src) //2 + new /obj/item/clothing/head/helmet/space/syndicate/black/red(src) //2 + new /obj/item/card/emag(src) //6 + new /obj/item/emagrecharge(src) //2 + new /obj/item/storage/toolbox/syndicate(src) //1 + new /obj/item/card/id/syndicate(src) //2 + new /obj/item/flashlight/emp(src) //2 + new /obj/item/jammer(src) //5 - if("sabotage") // 26 tc now + if("sabotage") // ~28 tc now new /obj/item/grenade/plastic/c4 (src) new /obj/item/grenade/plastic/c4 (src) + new /obj/item/grenade/plastic/x4 (src) + new /obj/item/grenade/plastic/x4 (src) new /obj/item/doorCharge(src) new /obj/item/doorCharge(src) new /obj/item/camera_bug(src) @@ -117,15 +131,15 @@ new /obj/item/grenade/plastic/c4 (src) // 1 tc new /obj/item/card/emag(src) // 6 tc - if("ninja") // 33 tc worth - new /obj/item/katana(src) // Unique , hard to tell how much tc this is worth. 8 tc? + if("ninja") // 40~ tc worth + new /obj/item/katana(src) // Unique , basicly a better esword. 10 tc? new /obj/item/implanter/adrenalin(src) // 8 tc new /obj/item/throwing_star(src) // ~5 tc for all 6 new /obj/item/throwing_star(src) new /obj/item/throwing_star(src) - new /obj/item/throwing_star(src) - new /obj/item/throwing_star(src) - new /obj/item/throwing_star(src) + new /obj/item/implanter/emp(src) + new /obj/item/grenade/smokebomb(src) + new /obj/item/grenade/smokebomb(src) new /obj/item/storage/belt/chameleon(src) // Unique but worth at least 2 tc new /obj/item/card/id/syndicate(src) // 2 tc new /obj/item/chameleon(src) // 7 tc diff --git a/code/game/objects/items/tanks/jetpack.dm b/code/game/objects/items/tanks/jetpack.dm index 2e8074f656..0b520d9dc1 100644 --- a/code/game/objects/items/tanks/jetpack.dm +++ b/code/game/objects/items/tanks/jetpack.dm @@ -1,237 +1,239 @@ -/obj/item/tank/jetpack - name = "jetpack (empty)" - desc = "A tank of compressed gas for use as propulsion in zero-gravity areas. Use with caution." - icon_state = "jetpack" - item_state = "jetpack" - lefthand_file = 'icons/mob/inhands/equipment/jetpacks_lefthand.dmi' - righthand_file = 'icons/mob/inhands/equipment/jetpacks_righthand.dmi' - w_class = WEIGHT_CLASS_BULKY - distribute_pressure = ONE_ATMOSPHERE * O2STANDARD - actions_types = list(/datum/action/item_action/set_internals, /datum/action/item_action/toggle_jetpack, /datum/action/item_action/jetpack_stabilization) - var/gas_type = /datum/gas/oxygen - var/on = FALSE - var/stabilizers = FALSE - var/full_speed = TRUE // If the jetpack will have a speedboost in space/nograv or not - var/datum/effect_system/trail_follow/ion/ion_trail - -/obj/item/tank/jetpack/New() - ..() - if(gas_type) - air_contents.gases[gas_type] = (6 * ONE_ATMOSPHERE) * volume / (R_IDEAL_GAS_EQUATION * T20C) - - ion_trail = new - ion_trail.set_up(src) - -/obj/item/tank/jetpack/ui_action_click(mob/user, action) - if(istype(action, /datum/action/item_action/toggle_jetpack)) - cycle(user) - else if(istype(action, /datum/action/item_action/jetpack_stabilization)) - if(on) - stabilizers = !stabilizers - to_chat(user, "You turn the jetpack stabilization [stabilizers ? "on" : "off"].") - else - toggle_internals(user) - -/obj/item/tank/jetpack/proc/cycle(mob/user) - if(user.incapacitated()) - return - - if(!on) - turn_on() - to_chat(user, "You turn the jetpack on.") - else - turn_off() - to_chat(user, "You turn the jetpack off.") - for(var/X in actions) - var/datum/action/A = X - A.UpdateButtonIcon() - -/obj/item/tank/jetpack/proc/turn_on() - on = TRUE - icon_state = "[initial(icon_state)]-on" - ion_trail.start() - -/obj/item/tank/jetpack/proc/turn_off() - on = FALSE - stabilizers = FALSE - icon_state = initial(icon_state) - ion_trail.stop() - -/obj/item/tank/jetpack/proc/allow_thrust(num, mob/living/user) - if(!on) - return - if((num < 0.005 || air_contents.total_moles() < num)) - turn_off() - return - - var/datum/gas_mixture/removed = air_contents.remove(num) - if(removed.total_moles() < 0.005) - turn_off() - return - - var/turf/T = get_turf(user) - T.assume_air(removed) - - return 1 - -/obj/item/tank/jetpack/suicide_act(mob/user) - if (istype(user, /mob/living/carbon/human/)) - var/mob/living/carbon/human/H = user - H.forcesay("WHAT THE FUCK IS CARBON DIOXIDE?") - H.visible_message("[user] is suffocating [user.p_them()]self with [src]! It looks like [user.p_they()] didn't read what that jetpack says!") - return (OXYLOSS) - else - ..() - -/obj/item/tank/jetpack/improvised - name = "improvised jetpack" - desc = "A jetpack made from two air tanks, a fire extinguisher and some atmospherics equipment. It doesn't look like it can hold much." - icon_state = "jetpack-improvised" - item_state = "jetpack-sec" - volume = 30 //normal jetpacks have 70 volume - gas_type = null //it starts empty - full_speed = FALSE //moves at hardsuit jetpack speeds - -/obj/item/tank/jetpack/improvised/allow_thrust(num, mob/living/user) - if(!on) - return - if((num < 0.005 || air_contents.total_moles() < num)) - turn_off() - return - if(rand(0,250) == 0) - to_chat(user, "You feel your jetpack's engines cut out.") - turn_off() - return - - var/datum/gas_mixture/removed = air_contents.remove(num) - if(removed.total_moles() < 0.005) - turn_off() - return - - var/turf/T = get_turf(user) - T.assume_air(removed) - - return 1 - -/obj/item/tank/jetpack/void - name = "void jetpack (oxygen)" - desc = "It works well in a void." - volume = 60 - icon_state = "jetpack-void" - item_state = "jetpack-void" - full_speed = FALSE //Old pre-hardsuit tech - -/obj/item/tank/jetpack/oxygen - name = "jetpack (oxygen)" - desc = "A tank of compressed oxygen for use as propulsion in zero-gravity areas. Use with caution." - icon_state = "jetpack" - item_state = "jetpack" - -/obj/item/tank/jetpack/oxygen/harness - name = "jet harness (oxygen)" - desc = "A lightweight tactical harness, used by those who don't want to be weighed down by traditional jetpacks." - icon_state = "jetpack-mini" - item_state = "jetpack-mini" - volume = 50 - throw_range = 7 - w_class = WEIGHT_CLASS_NORMAL - -/obj/item/tank/jetpack/oxygen/captain - name = "\improper Captain's jetpack" - desc = "A compact, lightweight jetpack containing a high amount of compressed oxygen." - icon_state = "jetpack-captain" - item_state = "jetpack-captain" - w_class = WEIGHT_CLASS_NORMAL - volume = 90 - resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF //steal objective items are hard to destroy. - -/obj/item/tank/jetpack/oxygen/security - name = "security jetpack (oxygen)" - desc = "A tank of compressed oxygen for use as propulsion in zero-gravity areas by security forces." - icon_state = "jetpack-sec" - item_state = "jetpack-sec" - -/obj/item/tank/jetpack/carbondioxide - name = "jetpack (carbon dioxide)" - desc = "A tank of compressed carbon dioxide for use as propulsion in zero-gravity areas. Painted black to indicate that it should not be used as a source for internals." - icon_state = "jetpack-black" - item_state = "jetpack-black" - distribute_pressure = 0 - gas_type = /datum/gas/carbon_dioxide - -/obj/item/tank/jetpack/suit - name = "hardsuit jetpack upgrade" - desc = "A modular, compact set of thrusters designed to integrate with a hardsuit. It is fueled by a tank inserted into the suit's storage compartment." - icon_state = "jetpack-mining" - item_state = "jetpack-black" - w_class = WEIGHT_CLASS_NORMAL - actions_types = list(/datum/action/item_action/toggle_jetpack, /datum/action/item_action/jetpack_stabilization) - volume = 1 - slot_flags = null - gas_type = null - full_speed = FALSE - var/datum/gas_mixture/temp_air_contents - var/obj/item/tank/internals/tank = null - -/obj/item/tank/jetpack/suit/New() - ..() - STOP_PROCESSING(SSobj, src) - temp_air_contents = air_contents - -/obj/item/tank/jetpack/suit/attack_self() - return - -/obj/item/tank/jetpack/suit/cycle(mob/user) - if(!istype(loc, /obj/item/clothing/suit/space/hardsuit)) - to_chat(user, "\The [src] must be connected to a hardsuit!") - return - - var/mob/living/carbon/human/H = user - if(!istype(H.s_store, /obj/item/tank/internals)) - to_chat(user, "You need a tank in your suit storage!") - return - ..() - -/obj/item/tank/jetpack/suit/turn_on() - if(!istype(loc, /obj/item/clothing/suit/space/hardsuit) || !ishuman(loc.loc)) - return - var/mob/living/carbon/human/H = loc.loc - tank = H.s_store - air_contents = tank.air_contents - START_PROCESSING(SSobj, src) - ..() - -/obj/item/tank/jetpack/suit/turn_off() - tank = null - air_contents = temp_air_contents - STOP_PROCESSING(SSobj, src) - ..() - -/obj/item/tank/jetpack/suit/process() - if(!istype(loc, /obj/item/clothing/suit/space/hardsuit) || !ishuman(loc.loc)) - turn_off() - return - var/mob/living/carbon/human/H = loc.loc - if(!tank || tank != H.s_store) - turn_off() - return - ..() - -//Return a jetpack that the mob can use -//Back worn jetpacks, hardsuit internal packs, and so on. -//Used in Process_Spacemove() and wherever you want to check for/get a jetpack - -/mob/proc/get_jetpack() - return - -/mob/living/carbon/get_jetpack() - var/obj/item/tank/jetpack/J = back - if(istype(J)) - return J - -/mob/living/carbon/human/get_jetpack() - var/obj/item/tank/jetpack/J = ..() - if(!istype(J) && istype(wear_suit, /obj/item/clothing/suit/space/hardsuit)) - var/obj/item/clothing/suit/space/hardsuit/C = wear_suit - J = C.jetpack - return J +/obj/item/tank/jetpack + name = "jetpack (empty)" + desc = "A tank of compressed gas for use as propulsion in zero-gravity areas. Use with caution." + icon_state = "jetpack" + item_state = "jetpack" + lefthand_file = 'icons/mob/inhands/equipment/jetpacks_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/jetpacks_righthand.dmi' + w_class = WEIGHT_CLASS_BULKY + distribute_pressure = ONE_ATMOSPHERE * O2STANDARD + actions_types = list(/datum/action/item_action/set_internals, /datum/action/item_action/toggle_jetpack, /datum/action/item_action/jetpack_stabilization) + var/gas_type = /datum/gas/oxygen + var/on = FALSE + var/stabilizers = FALSE + var/full_speed = TRUE // If the jetpack will have a speedboost in space/nograv or not + var/datum/effect_system/trail_follow/ion/ion_trail + +/obj/item/tank/jetpack/New() + ..() + if(gas_type) + air_contents.gases[gas_type] = (6 * ONE_ATMOSPHERE) * volume / (R_IDEAL_GAS_EQUATION * T20C) + + ion_trail = new + ion_trail.set_up(src) + +/obj/item/tank/jetpack/ui_action_click(mob/user, action) + if(istype(action, /datum/action/item_action/toggle_jetpack)) + cycle(user) + else if(istype(action, /datum/action/item_action/jetpack_stabilization)) + if(on) + stabilizers = !stabilizers + to_chat(user, "You turn the jetpack stabilization [stabilizers ? "on" : "off"].") + else + toggle_internals(user) + +/obj/item/tank/jetpack/proc/cycle(mob/user) + if(user.incapacitated()) + return + + if(!on) + turn_on() + to_chat(user, "You turn the jetpack on.") + else + turn_off() + to_chat(user, "You turn the jetpack off.") + for(var/X in actions) + var/datum/action/A = X + A.UpdateButtonIcon() + +/obj/item/tank/jetpack/proc/turn_on() + on = TRUE + icon_state = "[initial(icon_state)]-on" + ion_trail.start() + +/obj/item/tank/jetpack/proc/turn_off() + on = FALSE + stabilizers = FALSE + icon_state = initial(icon_state) + ion_trail.stop() + +/obj/item/tank/jetpack/proc/allow_thrust(num, mob/living/user) + if(!on) + return + if((num < 0.005 || air_contents.total_moles() < num)) + turn_off() + return + + var/datum/gas_mixture/removed = air_contents.remove(num) + if(removed.total_moles() < 0.005) + turn_off() + return + + var/turf/T = get_turf(user) + T.assume_air(removed) + + return 1 + +/obj/item/tank/jetpack/suicide_act(mob/user) + if (istype(user, /mob/living/carbon/human/)) + var/mob/living/carbon/human/H = user + H.forcesay("WHAT THE FUCK IS CARBON DIOXIDE?") + H.visible_message("[user] is suffocating [user.p_them()]self with [src]! It looks like [user.p_they()] didn't read what that jetpack says!") + return (OXYLOSS) + else + ..() + +/obj/item/tank/jetpack/improvised + name = "improvised jetpack" + desc = "A jetpack made from two air tanks, a fire extinguisher and some atmospherics equipment. It doesn't look like it can hold much." + icon_state = "jetpack-improvised" + item_state = "jetpack-sec" + volume = 30 //normal jetpacks have 70 volume + gas_type = null //it starts empty + full_speed = FALSE //moves at hardsuit jetpack speeds + +/obj/item/tank/jetpack/improvised/allow_thrust(num, mob/living/user) + if(!on) + return + if((num < 0.005 || air_contents.total_moles() < num)) + turn_off() + return + if(rand(0,250) == 0) + to_chat(user, "You feel your jetpack's engines cut out.") + turn_off() + return + + var/datum/gas_mixture/removed = air_contents.remove(num) + if(removed.total_moles() < 0.005) + turn_off() + return + + var/turf/T = get_turf(user) + T.assume_air(removed) + + return 1 + +/obj/item/tank/jetpack/void + name = "void jetpack (oxygen)" + desc = "It works well in a void." + volume = 60 + icon_state = "jetpack-void" + item_state = "jetpack-void" + full_speed = FALSE //Old pre-hardsuit tech + +/obj/item/tank/jetpack/oxygen + name = "jetpack (oxygen)" + desc = "A tank of compressed oxygen for use as propulsion in zero-gravity areas. Use with caution." + icon_state = "jetpack" + item_state = "jetpack" + +/obj/item/tank/jetpack/oxygen/harness + name = "jet harness (oxygen)" + desc = "A lightweight tactical harness, used by those who don't want to be weighed down by traditional jetpacks." + icon_state = "jetpack-mini" + item_state = "jetpack-mini" + volume = 50 + throw_range = 7 + w_class = WEIGHT_CLASS_NORMAL + +/obj/item/tank/jetpack/oxygen/captain + name = "\improper Captain's jetpack" + desc = "A compact, lightweight jetpack containing a high amount of compressed oxygen." + icon_state = "jetpack-captain" + item_state = "jetpack-captain" + w_class = WEIGHT_CLASS_NORMAL + volume = 90 + resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF //steal objective items are hard to destroy. + +/obj/item/tank/jetpack/oxygen/security + name = "security jetpack (oxygen)" + desc = "A tank of compressed oxygen for use as propulsion in zero-gravity areas by security forces." + icon_state = "jetpack-sec" + item_state = "jetpack-sec" + full_speed = FALSE + +/obj/item/tank/jetpack/carbondioxide + name = "jetpack (carbon dioxide)" + desc = "A tank of compressed carbon dioxide for use as propulsion in zero-gravity areas. Painted black to indicate that it should not be used as a source for internals." + icon_state = "jetpack-black" + item_state = "jetpack-black" + distribute_pressure = 0 + gas_type = /datum/gas/carbon_dioxide + +/obj/item/tank/jetpack/suit + name = "hardsuit jetpack upgrade" + desc = "A modular, compact set of thrusters designed to integrate with a hardsuit. It is fueled by a tank inserted into the suit's storage compartment." + icon_state = "jetpack-mining" + item_state = "jetpack-black" + w_class = WEIGHT_CLASS_NORMAL + actions_types = list(/datum/action/item_action/toggle_jetpack, /datum/action/item_action/jetpack_stabilization) + volume = 1 + slot_flags = null + gas_type = null + full_speed = FALSE + var/datum/gas_mixture/temp_air_contents + var/obj/item/tank/internals/tank = null + +/obj/item/tank/jetpack/suit/New() + ..() + STOP_PROCESSING(SSobj, src) + temp_air_contents = air_contents + +/obj/item/tank/jetpack/suit/attack_self() + return + +/obj/item/tank/jetpack/suit/cycle(mob/user) + if(!istype(loc, /obj/item/clothing/suit/space/hardsuit)) + to_chat(user, "\The [src] must be connected to a hardsuit!") + return + + var/mob/living/carbon/human/H = user + if(!istype(H.s_store, /obj/item/tank/internals)) + to_chat(user, "You need a tank in your suit storage!") + return + ..() + +/obj/item/tank/jetpack/suit/turn_on() + if(!istype(loc, /obj/item/clothing/suit/space/hardsuit) || !ishuman(loc.loc)) + return + var/mob/living/carbon/human/H = loc.loc + tank = H.s_store + air_contents = tank.air_contents + START_PROCESSING(SSobj, src) + ..() + +/obj/item/tank/jetpack/suit/turn_off() + tank = null + air_contents = temp_air_contents + STOP_PROCESSING(SSobj, src) + ..() + +/obj/item/tank/jetpack/suit/process() + if(!istype(loc, /obj/item/clothing/suit/space/hardsuit) || !ishuman(loc.loc)) + turn_off() + return + var/mob/living/carbon/human/H = loc.loc + if(!tank || tank != H.s_store) + turn_off() + return + ..() + +//Return a jetpack that the mob can use +//Back worn jetpacks, hardsuit internal packs, and so on. +//Used in Process_Spacemove() and wherever you want to check for/get a jetpack + +/mob/proc/get_jetpack() + return + +/mob/living/carbon/get_jetpack() + var/obj/item/tank/jetpack/J = back + if(istype(J)) + return J + +/mob/living/carbon/human/get_jetpack() + var/obj/item/tank/jetpack/J = ..() + if(!istype(J) && istype(wear_suit, /obj/item/clothing/suit/space/hardsuit)) + var/obj/item/clothing/suit/space/hardsuit/C = wear_suit + J = C.jetpack + return J + diff --git a/code/game/objects/structures/mirror.dm b/code/game/objects/structures/mirror.dm index ea2e99d371..b15d686b7b 100644 --- a/code/game/objects/structures/mirror.dm +++ b/code/game/objects/structures/mirror.dm @@ -24,15 +24,13 @@ if(ishuman(user)) var/mob/living/carbon/human/H = user - var/userloc = H.loc - //see code/modules/mob/dead/new_player/preferences.dm at approx line 545 for comments! //this is largely copypasted from there. //handle facial hair (if necessary) if(H.gender == MALE) var/new_style = input(user, "Select a facial hair style", "Grooming") as null|anything in GLOB.facial_hair_styles_list - if(userloc != H.loc) + if(!user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK)) return //no tele-grooming if(new_style) H.facial_hair_style = new_style @@ -41,7 +39,7 @@ //handle normal hair var/new_style = input(user, "Select a hair style", "Grooming") as null|anything in GLOB.hair_styles_list - if(userloc != H.loc) + if(!user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK)) return //no tele-grooming if(new_style) H.hair_style = new_style @@ -90,9 +88,9 @@ /obj/structure/mirror/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0) switch(damage_type) if(BRUTE) - playsound(src.loc, 'sound/effects/hit_on_shattered_glass.ogg', 70, 1) + playsound(src, 'sound/effects/hit_on_shattered_glass.ogg', 70, 1) if(BURN) - playsound(src.loc, 'sound/effects/hit_on_shattered_glass.ogg', 70, 1) + playsound(src, 'sound/effects/hit_on_shattered_glass.ogg', 70, 1) /obj/structure/mirror/magic @@ -131,7 +129,7 @@ var/choice = input(user, "Something to change?", "Magical Grooming") as null|anything in list("name", "race", "gender", "hair", "eyes") - if(!Adjacent(user)) + if(!user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK)) return switch(choice) @@ -140,7 +138,7 @@ if(!newname) return - if(!Adjacent(user)) + if(!user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK)) return H.real_name = newname H.name = newname @@ -156,7 +154,7 @@ if(!newrace) return - if(!Adjacent(user)) + if(!user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK)) return H.set_species(newrace, icon_update=0) @@ -186,7 +184,7 @@ if("gender") if(!(H.gender in list("male", "female"))) //blame the patriarchy return - if(!Adjacent(user)) + if(!user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK)) return if(H.gender == "male") if(alert(H, "Become a Witch?", "Confirmation", "Yes", "No") == "Yes") @@ -207,7 +205,7 @@ if("hair") var/hairchoice = alert(H, "Hair style or hair color?", "Change Hair", "Style", "Color") - if(!Adjacent(user)) + if(!user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK)) return if(hairchoice == "Style") //So you just want to use a mirror then? ..() @@ -225,7 +223,7 @@ if(BODY_ZONE_PRECISE_EYES) var/new_eye_color = input(H, "Choose your eye color", "Eye Color","#"+H.eye_color) as color|null - if(!Adjacent(user)) + if(!user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK)) return if(new_eye_color) H.eye_color = sanitize_hexcolor(new_eye_color) diff --git a/code/game/turfs/simulated/wall/misc_walls.dm b/code/game/turfs/simulated/wall/misc_walls.dm index 8efac31f65..dfc6972578 100644 --- a/code/game/turfs/simulated/wall/misc_walls.dm +++ b/code/game/turfs/simulated/wall/misc_walls.dm @@ -77,6 +77,14 @@ return ..() +/turf/closed/wall/clockwork/rcd_vals(mob/user, obj/item/construction/rcd/the_rcd) + if(heated && the_rcd.canRturf) + return ..() + +/turf/closed/wall/clockwork/rcd_act(mob/user, obj/item/construction/rcd/the_rcd, passed_mode) + if(heated && the_rcd.canRturf) + return ..() + /turf/closed/wall/clockwork/try_destroy(obj/item/I, mob/user, turf/T) if(!heated) return ..() diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm index 57dc357859..e15613c43d 100644 --- a/code/modules/admin/verbs/debug.dm +++ b/code/modules/admin/verbs/debug.dm @@ -29,69 +29,62 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that /client/proc/callproc() set category = "Debug" set name = "Advanced ProcCall" - set waitfor = 0 + set waitfor = FALSE if(!check_rights(R_DEBUG)) return var/datum/target = null - var/targetselected = 0 + var/targetselected = FALSE var/returnval = null - switch(alert("Proc owned by something?",,"Yes","No")) - if("Yes") - targetselected = 1 - var/list/value = vv_get_value(default_class = VV_ATOM_REFERENCE, classes = list(VV_ATOM_REFERENCE, VV_DATUM_REFERENCE, VV_MOB_REFERENCE, VV_CLIENT)) - if (!value["class"] || !value["value"]) - return - target = value["value"] - if("No") - target = null - targetselected = 0 - - var/procname = input("Proc path, eg: /proc/fake_blood","Path:", null) as text|null - if(!procname) - return - - //hascall() doesn't support proc paths (eg: /proc/gib(), it only supports "gib") - var/testname = procname - if(targetselected) - //Find one of the 3 possible ways they could have written /proc/PROCNAME - if(findtext(procname, "/proc/")) - testname = replacetext(procname, "/proc/", "") - else if(findtext(procname, "/proc")) - testname = replacetext(procname, "/proc", "") - else if(findtext(procname, "proc/")) - testname = replacetext(procname, "proc/", "") - //Clear out any parenthesis if they're a dummy - testname = replacetext(testname, "()", "") - - if(targetselected && !hascall(target,testname)) - to_chat(usr, "Error: callproc(): type [target.type] has no proc named [procname].") - return - else - var/procpath = text2path(procname) - if (!procpath) - to_chat(usr, "Error: callproc(): proc [procname] does not exist. (Did you forget the /proc/ part?)") + if(alert("Proc owned by something?",,"Yes","No") == "Yes") + targetselected = TRUE + var/list/value = vv_get_value(default_class = VV_ATOM_REFERENCE, classes = list(VV_ATOM_REFERENCE, VV_DATUM_REFERENCE, VV_MOB_REFERENCE, VV_CLIENT)) + if (!value["class"] || !value["value"]) return + target = value["value"] + + var/procpath = input("Proc path, eg: /proc/fake_blood","Path:", null) as text|null + if(!procpath) + return + + //strip away everything but the proc name + var/list/proclist = splittext(procpath, "/") + if (!length(proclist)) + return + + var/procname = proclist[proclist.len] + var/proctype = ("verb" in proclist) ? "verb" :"proc" + + if(targetselected) + if(!hascall(target, procname)) + to_chat(usr, "Error: callproc(): type [target.type] has no [proctype] named [procpath].") + return + else + procpath = "/[proctype]/[procname]" + if(!text2path(procpath)) + to_chat(usr, "Error: callproc(): [procpath] does not exist.") + return + var/list/lst = get_callproc_args() if(!lst) return if(targetselected) if(!target) - to_chat(usr, "Error: callproc(): owner of proc no longer exists.") + to_chat(usr, "Error: callproc(): owner of proc no longer exists.") return - var/msg = "[key_name(src)] called [target]'s [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no arguments"]." + var/msg = "[key_name(src)] called [target]'s [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no argument"]." log_admin(msg) message_admins(msg) admin_ticket_log(target, msg) - returnval = WrapAdminProcCall(target, procname, lst) // Pass the lst as an argument list to the proc + returnval = WrapAdminProcCall(target, procname, lst) else - //this currently has no hascall protection. wasn't able to get it working. - log_admin("[key_name(src)] called [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no arguments"].") - message_admins("[key_name(src)] called [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no arguments"].") - returnval = WrapAdminProcCall(GLOBAL_PROC, procname, lst) // Pass the lst as an argument list to the proc + var/msg = "[key_name(src)] called [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no argument"]." + log_admin(msg) + message_admins(msg) + returnval = WrapAdminProcCall(GLOBAL_PROC, procpath, lst) //calling globals needs full qualified name (e.g /proc/foo) . = get_callproc_returnval(returnval, procname) if(.) to_chat(usr, .) @@ -111,8 +104,8 @@ GLOBAL_LIST_EMPTY(AdminProcCallSpamPrevention) GLOBAL_PROTECT(AdminProcCallSpamPrevention) /proc/WrapAdminProcCall(datum/target, procname, list/arguments) - if(target && procname == "Del") - to_chat(usr, "Calling Del() is not allowed") + if(target != GLOBAL_PROC && procname == "Del") + to_chat(usr, "Calling Del() is not allowed") return if(target != GLOBAL_PROC && !target.CanProcCall(procname)) @@ -159,7 +152,7 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention) /client/proc/callproc_datum(datum/A as null|area|mob|obj|turf) set category = "Debug" set name = "Atom ProcCall" - set waitfor = 0 + set waitfor = FALSE if(!check_rights(R_DEBUG)) return @@ -168,7 +161,7 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention) if(!procname) return if(!hascall(A,procname)) - to_chat(usr, "Error: callproc_datum(): type [A.type] has no proc named [procname].") + to_chat(usr, "Error: callproc_datum(): type [A.type] has no proc named [procname].") return var/list/lst = get_callproc_args() if(!lst) @@ -177,8 +170,8 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention) if(!A || !IsValidSrc(A)) to_chat(usr, "Error: callproc_datum(): owner of proc no longer exists.") return - log_admin("[key_name(src)] called [A]'s [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no arguments"].") var/msg = "[key_name(src)] called [A]'s [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no arguments"]." + log_admin(msg) message_admins(msg) admin_ticket_log(A, msg) SSblackbox.record_feedback("tally", "admin_verb", 1, "Atom ProcCall") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! @@ -188,8 +181,6 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention) if(.) to_chat(usr, .) - - /client/proc/get_callproc_args() var/argnum = input("Number of arguments","Number:",0) as num|null if(isnull(argnum)) @@ -213,7 +204,7 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention) . = "" if(islist(returnval)) var/list/returnedlist = returnval - . = "" + . = "" if(returnedlist.len) var/assoc_check = returnedlist[1] if(istext(assoc_check) && (returnedlist[assoc_check] != null)) @@ -227,11 +218,10 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention) . += "\n[elem]" else . = "[procname] returned an empty list" - . += "" + . += "" else - . = "[procname] returned: [!isnull(returnval) ? returnval : "null"]" - + . = "[procname] returned: [!isnull(returnval) ? returnval : "null"]" /client/proc/Cell() set category = "Debug" diff --git a/code/modules/antagonists/abductor/machinery/console.dm b/code/modules/antagonists/abductor/machinery/console.dm index a14b667069..52bda50b86 100644 --- a/code/modules/antagonists/abductor/machinery/console.dm +++ b/code/modules/antagonists/abductor/machinery/console.dm @@ -126,8 +126,20 @@ if(vest) vest.flip_mode() -/obj/machinery/abductor/console/proc/SelectDisguise(remote = 0) - var/entry_name = input( "Choose Disguise", "Disguise") as null|anything in disguises +/obj/machinery/abductor/console/proc/SelectDisguise(remote = FALSE) + var/list/disguises2 = list() + for(var/name in disguises) + var/datum/icon_snapshot/snap = disguises[name] + var/image/dummy = image(snap.icon, src, snap.icon_state) + dummy.overlays = snap.overlays + disguises2[name] = dummy + + var/entry_name + if(remote) + entry_name = show_radial_menu(usr, camera.eyeobj, disguises2) + else + entry_name = show_radial_menu(usr, src, disguises2) + var/datum/icon_snapshot/chosen = disguises[entry_name] if(chosen && vest && (remote || in_range(usr,src))) vest.SetDisguise(chosen) diff --git a/code/modules/antagonists/changeling/powers/adrenaline.dm b/code/modules/antagonists/changeling/powers/adrenaline.dm index a9d85d0fed..d1088f0025 100644 --- a/code/modules/antagonists/changeling/powers/adrenaline.dm +++ b/code/modules/antagonists/changeling/powers/adrenaline.dm @@ -12,5 +12,5 @@ //Recover from stuns. /obj/effect/proc_holder/changeling/adrenaline/sting_action(mob/living/user) - user.do_adrenaline(100, FALSE, 70, 0, TRUE, list("epinephrine" = 3, "changelingmeth" = 10, "mannitol" = 10, "omnizine" = 10, "changelingadrenaline" = 5), "Energy rushes through us.") + user.do_adrenaline(0, FALSE, 70, 0, TRUE, list("epinephrine" = 3, "changelingmeth" = 10, "mannitol" = 10, "regen_jelly" = 10, "changelingadrenaline" = 5), "Energy rushes through us.", 0, 0.75, 0) return TRUE diff --git a/code/modules/antagonists/changeling/powers/panacea.dm b/code/modules/antagonists/changeling/powers/panacea.dm index 9f7a36f214..8d571d21e3 100644 --- a/code/modules/antagonists/changeling/powers/panacea.dm +++ b/code/modules/antagonists/changeling/powers/panacea.dm @@ -29,7 +29,7 @@ O.forceMove(get_turf(user)) user.reagents.add_reagent("mutadone", 10) - user.reagents.add_reagent("pen_acid", 20) + user.reagents.add_reagent("pen_jelly", 20) user.reagents.add_reagent("antihol", 10) user.reagents.add_reagent("mannitol", 25) diff --git a/code/modules/antagonists/clockcult/clock_structures/reflector.dm b/code/modules/antagonists/clockcult/clock_structures/reflector.dm new file mode 100644 index 0000000000..34ad051d19 --- /dev/null +++ b/code/modules/antagonists/clockcult/clock_structures/reflector.dm @@ -0,0 +1,86 @@ +/obj/structure/destructible/clockwork/reflector + name = "reflector" + desc = "A large lantern-shaped machine made of thin brass. It looks fragile." + clockwork_desc = "A lantern-shaped generator that produces power when near starlight." + icon_state = "reflector" + unanchored_icon = "reflector_unwrenched" + max_integrity = 40 + construction_value = 5 + layer = WALL_OBJ_LAYER + break_message = "The reflectors's fragile shield shatters into pieces!" + resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF + light_color = "#DAAA18" + var/list/allowed_projectile_typecache = list( + /obj/item/projectile/beam + ) + + var/ini_dir = null + +/obj/structure/destructible/clockwork/reflector/Initialize() + . = ..() + allowed_projectile_typecache = typecacheof(allowed_projectile_typecache) + +/obj/structure/destructible/clockwork/reflector/ComponentInitialize() + . = ..() + AddComponent(/datum/component/simple_rotation,ROTATION_ALTCLICK | ROTATION_CLOCKWISE | ROTATION_COUNTERCLOCKWISE | ROTATION_VERBS ,null,CALLBACK(src, .proc/can_be_rotated),CALLBACK(src,.proc/after_rotation)) + +/obj/structure/destructible/clockwork/reflector/bullet_act(obj/item/projectile/P) + if(!anchored || !allowed_projectile_typecache[P.type] || !(P.dir in GLOB.cardinals)) + return ..() + + if(auto_reflect(P, P.dir, get_turf(P), P.Angle) != -1) + return ..() + + return -1 + +/obj/structure/destructible/clockwork/reflector/proc/auto_reflect(obj/item/projectile/P, pdir, turf/ploc, pangle) + + //Yell at me if this exists already. + + var/real_angle = 0 + + switch(dir) + if(NORTH) + real_angle = 0 + if(EAST) + real_angle = 90 + if(SOUTH) + real_angle = 180 + if(WEST) + real_angle = 270 + + var/incidence = GET_ANGLE_OF_INCIDENCE(real_angle, (P.Angle + 180)) + if(abs(incidence) > 90 && abs(incidence) < 270) + return FALSE + var/new_angle = SIMPLIFY_DEGREES(real_angle + incidence) + P.setAngle(new_angle) + P.ignore_source_check = TRUE + P.range = P.decayedRange + P.decayedRange = max(P.decayedRange--, 0) + return -1 + +/obj/structure/destructible/clockwork/reflector/proc/can_be_rotated(mob/user,rotation_type) + if(anchored) + to_chat(user, "[src] cannot be rotated while it is fastened to the floor!") + return FALSE + + return TRUE + +/obj/structure/destructible/clockwork/reflector/Move() + . = ..() + setDir(ini_dir) + +/obj/structure/destructible/clockwork/reflector/proc/after_rotation(mob/user,rotation_type) + ini_dir = dir + add_fingerprint(user) + + +/obj/structure/destructible/clockwork/reflector/wrench_act(mob/living/user, obj/item/I) + + if(!is_servant_of_ratvar(user)) + return ..() + + anchored = !anchored + to_chat(user, "You [anchored ? "secure" : "unsecure"] \the [src].") + I.play_tool_sound(src) + return TRUE \ No newline at end of file diff --git a/code/modules/antagonists/cult/cult.dm b/code/modules/antagonists/cult/cult.dm index 32442ee72c..47cf2abf3f 100644 --- a/code/modules/antagonists/cult/cult.dm +++ b/code/modules/antagonists/cult/cult.dm @@ -361,6 +361,7 @@ reshape.Shift(EAST, 1) reshape.Crop(7,4,26,31) reshape.Crop(-5,-3,26,30) + return reshape /mob/living/carbon/human/get_sac_image() var/datum/job/sacjob = SSjob.GetJob(mind.assigned_role) @@ -370,6 +371,7 @@ reshape.Shift(EAST, 1) reshape.Crop(7,4,26,31) reshape.Crop(-5,-3,26,30) + return reshape /datum/objective/sacrifice var/sacced = FALSE diff --git a/code/modules/antagonists/cult/cult_comms.dm b/code/modules/antagonists/cult/cult_comms.dm index 8452f78ed3..761412e9f8 100644 --- a/code/modules/antagonists/cult/cult_comms.dm +++ b/code/modules/antagonists/cult/cult_comms.dm @@ -342,10 +342,7 @@ if(cooldown>world.time) to_chat(owner, "You aren't ready to place another blood mark yet!") return - if(owner.orbiting && owner.orbiting.orbiting) - target = owner.orbiting.orbiting - else - target = get_turf(owner) + target = owner.orbiting?.parent || get_turf(owner) if(!target) return C.cult_team.blood_target = target diff --git a/code/modules/antagonists/devil/true_devil/_true_devil.dm b/code/modules/antagonists/devil/true_devil/_true_devil.dm index 923a224b81..1df81a797b 100644 --- a/code/modules/antagonists/devil/true_devil/_true_devil.dm +++ b/code/modules/antagonists/devil/true_devil/_true_devil.dm @@ -94,7 +94,7 @@ visible_message("[src] easily breaks out of [p_their()] handcuffs!", \ "With just a thought your handcuffs fall off.") -/mob/living/carbon/true_devil/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE) +/mob/living/carbon/true_devil/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE, no_tk=FALSE) if(incapacitated()) to_chat(src, "You can't do that right now!") return FALSE diff --git a/code/modules/cargo/packs.dm b/code/modules/cargo/packs.dm index 2effbd7ada..7042913b0d 100644 --- a/code/modules/cargo/packs.dm +++ b/code/modules/cargo/packs.dm @@ -516,14 +516,16 @@ /datum/supply_pack/security/armory/ballistic name = "Combat Shotguns Crate" - desc = "For when the enemy absolutely needs to be replaced with lead. Contains three Aussec-designed Combat Shotguns, and three Shotgun Bandoliers. Requires Armory access to open." + desc = "For when the enemy absolutely needs to be replaced with lead. Contains three Aussec-designed Combat Shotguns, with three Shotgun Bandoliers, as well as seven buchshot and 12g shotgun slugs. Requires Armory access to open." cost = 8000 contains = list(/obj/item/gun/ballistic/shotgun/automatic/combat, /obj/item/gun/ballistic/shotgun/automatic/combat, /obj/item/gun/ballistic/shotgun/automatic/combat, /obj/item/storage/belt/bandolier, /obj/item/storage/belt/bandolier, - /obj/item/storage/belt/bandolier) + /obj/item/storage/belt/bandolier, + /obj/item/storage/box/lethalshot, + /obj/item/storage/box/lethalslugs) crate_name = "combat shotguns crate" /datum/supply_pack/security/armory/dragnetgun @@ -567,7 +569,7 @@ /datum/supply_pack/security/armory/fire name = "Incendiary Weapons Crate" - desc = "Burn, baby burn. Contains three incendiary grenades, three plasma canisters, and a flamethrower. Requires Brige access to open." + desc = "Burn, baby burn. Contains three incendiary grenades, seven incendiary slugs, three plasma canisters, and a flamethrower. Requires Brige access to open." cost = 1500 access = ACCESS_HEADS contains = list(/obj/item/flamethrower/full, @@ -576,7 +578,8 @@ /obj/item/tank/internals/plasma, /obj/item/grenade/chem_grenade/incendiary, /obj/item/grenade/chem_grenade/incendiary, - /obj/item/grenade/chem_grenade/incendiary) + /obj/item/grenade/chem_grenade/incendiary, + /obj/item/storage/box/fireshot) crate_name = "incendiary weapons crate" crate_type = /obj/structure/closet/crate/secure/plasma dangerous = TRUE @@ -629,11 +632,13 @@ /datum/supply_pack/security/armory/riotshotguns name = "Riot Shotgun Crate" - desc = "For when the greytide gets really uppity. Contains three riot Shotguns. Requires Armory access to open." + desc = "For when the greytide gets really uppity. Contains three riot shotguns, seven rubber shot and beanbag shells. Requires Armory access to open." cost = 6000 contains = list(/obj/item/gun/ballistic/shotgun/riot, /obj/item/gun/ballistic/shotgun/riot, - /obj/item/gun/ballistic/shotgun/riot) + /obj/item/gun/ballistic/shotgun/riot, + /obj/item/storage/box/rubbershot, + /obj/item/storage/box/beanbag) crate_name = "riot shotgun crate" /datum/supply_pack/security/armory/swat @@ -1540,6 +1545,15 @@ crate_type = /obj/structure/closet/crate/secure/science dangerous = TRUE +/datum/supply_pack/science/tech_slugs + name = "Tech Slug Ammo Shells" + desc = "A new type of shell that is able to be made into a few different dangerous types. Contains two boxes of tech slugs, 14 shells in all." + cost = 1000 + contains = list(/obj/item/storage/box/techsslug, + /obj/item/storage/box/techsslug) + crate_name = "tech slug crate" + + ////////////////////////////////////////////////////////////////////////////// /////////////////////////////// Service ////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index a0eea344a3..501e9fc7cc 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -2236,8 +2236,11 @@ GLOBAL_LIST_EMPTY(preferences_datums) character.hair_style = hair_style character.facial_hair_style = facial_hair_style character.underwear = underwear + character.saved_underwear = underwear character.undershirt = undershirt + character.saved_undershirt = undershirt character.socks = socks + character.saved_socks = socks character.backbag = backbag diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm index 746d5da60d..767b700051 100644 --- a/code/modules/clothing/clothing.dm +++ b/code/modules/clothing/clothing.dm @@ -216,6 +216,34 @@ BLIND // can't see anything ..() +/obj/item/clothing/under/CtrlClick(mob/user) + . = ..() + + if (!(item_flags & IN_INVENTORY)) + return + + if(!isliving(user) || !user.canUseTopic(src, BE_CLOSE, ismonkey(user))) + return + + if(has_sensor == LOCKED_SENSORS) + to_chat(user, "The controls are locked.") + return + if(has_sensor == BROKEN_SENSORS) + to_chat(user, "The sensors have shorted out!") + return + if(has_sensor <= NO_SENSORS) + to_chat(user, "This suit does not have any sensors.") + return + + sensor_mode = SENSOR_COORDS + + to_chat(user, "Your suit will now report your exact vital lifesigns as well as your coordinate position.") + + if(ishuman(user)) + var/mob/living/carbon/human/H = user + if(H.w_uniform == src) + H.update_suit_sensors() + /obj/item/clothing/under/AltClick(mob/user) if(..()) return 1 diff --git a/code/modules/clothing/suits/jobs.dm b/code/modules/clothing/suits/jobs.dm index deaedfec18..bf11d40caf 100644 --- a/code/modules/clothing/suits/jobs.dm +++ b/code/modules/clothing/suits/jobs.dm @@ -124,6 +124,9 @@ icon_state = "suitjacket_black" item_state = "ro_suit" +/obj/item/clothing/suit/toggle/lawyer/black/syndie + desc = "A snappy dress jacket. Suspiciously has no tags or branding." + armor = list("melee" = 10, "bullet" = 10, "laser" = 10, "energy" = 10, "bomb" = 10, "bio" = 10, "rad" = 10, "fire" = 40, "acid" = 40) //Mime /obj/item/clothing/suit/suspenders diff --git a/code/modules/clothing/under/miscellaneous.dm b/code/modules/clothing/under/miscellaneous.dm index 97e9a8f8ca..91fde0dbd0 100644 --- a/code/modules/clothing/under/miscellaneous.dm +++ b/code/modules/clothing/under/miscellaneous.dm @@ -1,759 +1,758 @@ -/obj/item/clothing/under/pj/red - name = "red pj's" - desc = "Sleepwear." - icon_state = "red_pyjamas" - item_color = "red_pyjamas" - item_state = "w_suit" - can_adjust = FALSE - -/obj/item/clothing/under/pj/blue - name = "blue pj's" - desc = "Sleepwear." - icon_state = "blue_pyjamas" - item_color = "blue_pyjamas" - item_state = "w_suit" - can_adjust = FALSE - -/obj/item/clothing/under/patriotsuit - name = "Patriotic Suit" - desc = "Motorcycle not included." - icon_state = "ek" - item_state = "ek" - item_color = "ek" - can_adjust = FALSE - -/obj/item/clothing/under/scratch - name = "white suit" - desc = "A white suit, suitable for an excellent host." - icon_state = "scratch" - item_state = "scratch" - item_color = "scratch" - can_adjust = FALSE - -/obj/item/clothing/under/sl_suit - desc = "It's a very amish looking suit." - name = "amish suit" - icon_state = "sl_suit" - item_color = "sl_suit" - can_adjust = FALSE - -/obj/item/clothing/under/roman - name = "\improper Roman armor" - desc = "Ancient Roman armor. Made of metallic and leather straps." - icon_state = "roman" - item_color = "roman" - item_state = "armor" - can_adjust = FALSE - strip_delay = 100 - resistance_flags = NONE - -/obj/item/clothing/under/waiter - name = "waiter's outfit" - desc = "It's a very smart uniform with a special pocket for tip." - icon_state = "waiter" - item_state = "waiter" - item_color = "waiter" - can_adjust = FALSE - -/obj/item/clothing/under/rank/prisoner - name = "prison jumpsuit" - desc = "It's standardised Nanotrasen prisoner-wear. Its suit sensors are stuck in the \"Fully On\" position." - icon_state = "prisoner" - item_state = "o_suit" - item_color = "prisoner" - has_sensor = LOCKED_SENSORS - sensor_mode = SENSOR_COORDS - random_sensor = FALSE - -/obj/item/clothing/under/rank/mailman - name = "mailman's jumpsuit" - desc = "'Special delivery!'" - icon_state = "mailman" - item_state = "b_suit" - item_color = "mailman" - -/obj/item/clothing/under/rank/psyche - name = "psychedelic jumpsuit" - desc = "Groovy!" - icon_state = "psyche" - item_state = "p_suit" - item_color = "psyche" - -/obj/item/clothing/under/rank/clown/sexy - name = "sexy-clown suit" - desc = "It makes you look HONKable!" - icon_state = "sexyclown" - item_state = "sexyclown" - item_color = "sexyclown" - can_adjust = FALSE - -/obj/item/clothing/under/jabroni - name = "Jabroni Outfit" - desc = "The leather club is two sectors down." - icon_state = "darkholme" - item_state = "darkholme" - item_color = "darkholme" - can_adjust = FALSE - -/obj/item/clothing/under/rank/vice - name = "vice officer's jumpsuit" - desc = "It's the standard issue pretty-boy outfit, as seen on Holo-Vision." - icon_state = "vice" - item_state = "gy_suit" - item_color = "vice" - can_adjust = FALSE - -/obj/item/clothing/under/rank/centcom_officer - desc = "It's a jumpsuit worn by CentCom Officers." - name = "\improper CentCom officer's jumpsuit" - icon_state = "officer" - item_state = "g_suit" - item_color = "officer" - alt_covers_chest = TRUE - -/obj/item/clothing/under/rank/centcom_commander - desc = "It's a jumpsuit worn by CentCom's highest-tier Commanders." - name = "\improper CentCom officer's jumpsuit" - icon_state = "centcom" - item_state = "dg_suit" - item_color = "centcom" - -/obj/item/clothing/under/space - name = "\improper NASA jumpsuit" - desc = "It has a NASA logo on it and is made of space-proofed materials." - icon_state = "black" - item_state = "bl_suit" - item_color = "black" - w_class = WEIGHT_CLASS_BULKY - gas_transfer_coefficient = 0.01 - permeability_coefficient = 0.02 - body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS - cold_protection = CHEST | GROIN | LEGS | ARMS //Needs gloves and shoes with cold protection to be fully protected. - min_cold_protection_temperature = SPACE_SUIT_MIN_TEMP_PROTECT - heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS - max_heat_protection_temperature = SPACE_SUIT_MAX_TEMP_PROTECT - can_adjust = FALSE - resistance_flags = NONE - -/obj/item/clothing/under/acj - name = "administrative cybernetic jumpsuit" - icon_state = "syndicate" - item_state = "bl_suit" - item_color = "syndicate" - desc = "A cybernetically enhanced jumpsuit used for administrative duties." - gas_transfer_coefficient = 0.01 - permeability_coefficient = 0.01 - body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS - armor = list("melee" = 100, "bullet" = 100, "laser" = 100,"energy" = 100, "bomb" = 100, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100) - cold_protection = CHEST | GROIN | LEGS | FEET | ARMS | HANDS - min_cold_protection_temperature = SPACE_SUIT_MIN_TEMP_PROTECT - heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS - max_heat_protection_temperature = SPACE_SUIT_MAX_TEMP_PROTECT - can_adjust = FALSE - resistance_flags = FIRE_PROOF | ACID_PROOF - -/obj/item/clothing/under/owl - name = "owl uniform" - desc = "A soft brown jumpsuit made of synthetic feathers and strong conviction." - icon_state = "owl" - item_color = "owl" - can_adjust = FALSE - -/obj/item/clothing/under/griffin - name = "griffon uniform" - desc = "A soft brown jumpsuit with a white feather collar made of synthetic feathers and a lust for mayhem." - icon_state = "griffin" - item_color = "griffin" - can_adjust = FALSE - -/obj/item/clothing/under/cloud - name = "cloud" - desc = "cloud" - icon_state = "cloud" - item_color = "cloud" - can_adjust = FALSE - -/obj/item/clothing/under/gimmick/rank/captain/suit - name = "captain's suit" - desc = "A green suit and yellow necktie. Exemplifies authority." - icon_state = "green_suit" - item_state = "dg_suit" - item_color = "green_suit" - can_adjust = FALSE - -/obj/item/clothing/under/gimmick/rank/head_of_personnel/suit - name = "head of personnel's suit" - desc = "A teal suit and yellow necktie. An authoritative yet tacky ensemble." - icon_state = "teal_suit" - item_state = "g_suit" - item_color = "teal_suit" - can_adjust = FALSE - -/obj/item/clothing/under/suit_jacket - name = "black suit" - desc = "A black suit and red tie. Very formal." - icon_state = "black_suit" - item_state = "bl_suit" - item_color = "black_suit" - can_adjust = FALSE - -/obj/item/clothing/under/suit_jacket/really_black - name = "executive suit" - desc = "A formal black suit and red tie, intended for the station's finest." - icon_state = "really_black_suit" - item_state = "bl_suit" - item_color = "black_suit" - -/obj/item/clothing/under/suit_jacket/female - name = "executive suit" - desc = "A formal trouser suit for women, intended for the station's finest." - icon_state = "black_suit_fem" - item_state = "black_suit_fem" - item_color = "black_suit_fem" - -/obj/item/clothing/under/suit_jacket/green - name = "green suit" - desc = "A green suit and yellow necktie. Baller." - icon_state = "green_suit" - item_state = "dg_suit" - item_color = "green_suit" - can_adjust = FALSE - -/obj/item/clothing/under/suit_jacket/red - name = "red suit" - desc = "A red suit and blue tie. Somewhat formal." - icon_state = "red_suit" - item_state = "r_suit" - item_color = "red_suit" - -/obj/item/clothing/under/suit_jacket/charcoal - name = "charcoal suit" - desc = "A charcoal suit and red tie. Very professional." - icon_state = "charcoal_suit" - item_state = "charcoal_suit" - item_color = "charcoal_suit" - -/obj/item/clothing/under/suit_jacket/navy - name = "navy suit" - desc = "A navy suit and red tie, intended for the station's finest." - icon_state = "navy_suit" - item_state = "navy_suit" - item_color = "navy_suit" - -/obj/item/clothing/under/suit_jacket/burgundy - name = "burgundy suit" - desc = "A burgundy suit and black tie. Somewhat formal." - icon_state = "burgundy_suit" - item_state = "burgundy_suit" - item_color = "burgundy_suit" - -/obj/item/clothing/under/suit_jacket/checkered - name = "checkered suit" - desc = "That's a very nice suit you have there. Shame if something were to happen to it, eh?" - icon_state = "checkered_suit" - item_state = "checkered_suit" - item_color = "checkered_suit" - -/obj/item/clothing/under/suit_jacket/tan - name = "tan suit" - desc = "A tan suit with a yellow tie. Smart, but casual." - icon_state = "tan_suit" - item_state = "tan_suit" - item_color = "tan_suit" - -/obj/item/clothing/under/suit_jacket/white - name = "white suit" - desc = "A white suit and jacket with a blue shirt. You wanna play rough? OKAY!" - icon_state = "white_suit" - item_state = "white_suit" - item_color = "white_suit" - -/obj/item/clothing/under/burial - name = "burial garments" - desc = "Traditional burial garments from the early 22nd century." - icon_state = "burial" - item_state = "burial" - item_color = "burial" - has_sensor = NO_SENSORS - -/obj/item/clothing/under/skirt/black - name = "black skirt" - desc = "A black skirt, very fancy!" - icon_state = "blackskirt" - item_color = "blackskirt" - body_parts_covered = CHEST|GROIN|ARMS - fitted = FEMALE_UNIFORM_TOP - can_adjust = FALSE - -/obj/item/clothing/under/skirt/blue - name = "blue skirt" - desc = "A blue, casual skirt." - icon_state = "blueskirt" - item_color = "blueskirt" - item_state = "b_suit" - body_parts_covered = CHEST|GROIN|ARMS - fitted = FEMALE_UNIFORM_TOP - can_adjust = FALSE - -/obj/item/clothing/under/skirt/red - name = "red skirt" - desc = "A red, casual skirt." - icon_state = "redskirt" - item_color = "redskirt" - item_state = "r_suit" - body_parts_covered = CHEST|GROIN|ARMS - fitted = FEMALE_UNIFORM_TOP - can_adjust = FALSE - -/obj/item/clothing/under/skirt/purple - name = "purple skirt" - desc = "A purple, casual skirt." - icon_state = "purpleskirt" - item_color = "purpleskirt" - item_state = "p_suit" - body_parts_covered = CHEST|GROIN|ARMS - fitted = FEMALE_UNIFORM_TOP - can_adjust = FALSE - - -/obj/item/clothing/under/schoolgirl - name = "blue schoolgirl uniform" - desc = "It's just like one of my Japanese animes!" - icon_state = "schoolgirl" - item_state = "schoolgirl" - item_color = "schoolgirl" - body_parts_covered = CHEST|GROIN|ARMS - fitted = FEMALE_UNIFORM_TOP - can_adjust = FALSE - -/obj/item/clothing/under/schoolgirl/red - name = "red schoolgirl uniform" - icon_state = "schoolgirlred" - item_state = "schoolgirlred" - item_color = "schoolgirlred" - -/obj/item/clothing/under/schoolgirl/green - name = "green schoolgirl uniform" - icon_state = "schoolgirlgreen" - item_state = "schoolgirlgreen" - item_color = "schoolgirlgreen" - -/obj/item/clothing/under/schoolgirl/orange - name = "orange schoolgirl uniform" - icon_state = "schoolgirlorange" - item_state = "schoolgirlorange" - item_color = "schoolgirlorange" - -/obj/item/clothing/under/overalls - name = "laborer's overalls" - desc = "A set of durable overalls for getting the job done." - icon_state = "overalls" - item_state = "lb_suit" - item_color = "overalls" - can_adjust = FALSE - -/obj/item/clothing/under/pirate - name = "pirate outfit" - desc = "Yarr." - icon_state = "pirate" - item_state = "pirate" - item_color = "pirate" - can_adjust = FALSE - -/obj/item/clothing/under/soviet - name = "soviet uniform" - desc = "For the Motherland!" - icon_state = "soviet" - item_state = "soviet" - item_color = "soviet" - can_adjust = FALSE - -/obj/item/clothing/under/redcoat - name = "redcoat uniform" - desc = "Looks old." - icon_state = "redcoat" - item_state = "redcoat" - item_color = "redcoat" - can_adjust = FALSE - -/obj/item/clothing/under/kilt - name = "kilt" - desc = "Includes shoes and plaid." - icon_state = "kilt" - item_state = "kilt" - item_color = "kilt" - body_parts_covered = CHEST|GROIN|LEGS|FEET - fitted = FEMALE_UNIFORM_TOP - can_adjust = FALSE - -/obj/item/clothing/under/kilt/highlander - desc = "You're the only one worthy of this kilt." - item_flags = NODROP - -/obj/item/clothing/under/sexymime - name = "sexy mime outfit" - desc = "The only time when you DON'T enjoy looking at someone's rack." - icon_state = "sexymime" - item_state = "sexymime" - item_color = "sexymime" - body_parts_covered = CHEST|GROIN|LEGS - fitted = FEMALE_UNIFORM_TOP - can_adjust = FALSE - -/obj/item/clothing/under/gladiator - name = "gladiator uniform" - desc = "Are you not entertained? Is that not why you are here?" - icon_state = "gladiator" - item_state = "gladiator" - item_color = "gladiator" - body_parts_covered = CHEST|GROIN|ARMS - fitted = NO_FEMALE_UNIFORM - can_adjust = FALSE - resistance_flags = NONE - -/obj/item/clothing/under/gladiator/ash_walker - desc = "This gladiator uniform appears to be covered in ash and fairly dated." - has_sensor = NO_SENSORS - -/obj/item/clothing/under/sundress - name = "sundress" - desc = "Makes you want to frolic in a field of daisies." - icon_state = "sundress" - item_state = "sundress" - item_color = "sundress" - body_parts_covered = CHEST|GROIN - fitted = FEMALE_UNIFORM_TOP - can_adjust = FALSE - -/obj/item/clothing/under/captainparade - name = "captain's parade uniform" - desc = "A captain's luxury-wear, for special occasions." - icon_state = "captain_parade" - item_state = "by_suit" - item_color = "captain_parade" - can_adjust = FALSE - -/obj/item/clothing/under/hosparademale - name = "head of security's parade uniform" - desc = "A male head of security's luxury-wear, for special occasions." - icon_state = "hos_parade_male" - item_state = "r_suit" - item_color = "hos_parade_male" - can_adjust = FALSE - -/obj/item/clothing/under/hosparadefem - name = "head of security's parade uniform" - desc = "A female head of security's luxury-wear, for special occasions." - icon_state = "hos_parade_fem" - item_state = "r_suit" - item_color = "hos_parade_fem" - fitted = FEMALE_UNIFORM_TOP - can_adjust = FALSE - -/obj/item/clothing/under/assistantformal - name = "assistant's formal uniform" - desc = "An assistant's formal-wear. Why an assistant needs formal-wear is still unknown." - icon_state = "assistant_formal" - item_state = "gy_suit" - item_color = "assistant_formal" - can_adjust = FALSE - -/obj/item/clothing/under/blacktango - name = "black tango dress" - desc = "Filled with Latin fire." - icon_state = "black_tango" - item_state = "wcoat" - item_color = "black_tango" - fitted = FEMALE_UNIFORM_TOP - can_adjust = FALSE - body_parts_covered = CHEST|GROIN - -/obj/item/clothing/under/stripeddress - name = "striped dress" - desc = "Fashion in space." - icon_state = "striped_dress" - item_state = "stripeddress" - item_color = "striped_dress" - body_parts_covered = CHEST|GROIN|ARMS - fitted = FEMALE_UNIFORM_FULL - can_adjust = FALSE - -/obj/item/clothing/under/sailordress - name = "sailor dress" - desc = "Formal wear for a leading lady." - icon_state = "sailor_dress" - item_state = "sailordress" - item_color = "sailor_dress" - body_parts_covered = CHEST|GROIN|ARMS - fitted = FEMALE_UNIFORM_TOP - can_adjust = FALSE - -/obj/item/clothing/under/redeveninggown - name = "red evening gown" - desc = "Fancy dress for space bar singers." - icon_state = "red_evening_gown" - item_state = "redeveninggown" - item_color = "red_evening_gown" - fitted = FEMALE_UNIFORM_TOP - can_adjust = FALSE - -/obj/item/clothing/under/maid - name = "maid costume" - desc = "Maid in China." - icon_state = "maid" - item_state = "maid" - item_color = "maid" - body_parts_covered = CHEST|GROIN - fitted = FEMALE_UNIFORM_TOP - can_adjust = FALSE - -/obj/item/clothing/under/maid/Initialize() - . = ..() - var/obj/item/clothing/accessory/maidapron/A = new (src) - attach_accessory(A) - -/obj/item/clothing/under/janimaid - name = "maid uniform" - desc = "A simple maid uniform for housekeeping." - icon_state = "janimaid" - item_state = "janimaid" - item_color = "janimaid" - body_parts_covered = CHEST|GROIN - fitted = FEMALE_UNIFORM_TOP - can_adjust = FALSE - -/obj/item/clothing/under/plaid_skirt - name = "red plaid skirt" - desc = "A preppy red skirt with a white blouse." - icon_state = "plaid_red" - item_state = "plaid_red" - item_color = "plaid_red" - fitted = FEMALE_UNIFORM_TOP - can_adjust = TRUE - alt_covers_chest = TRUE - -/obj/item/clothing/under/plaid_skirt/blue - name = "blue plaid skirt" - desc = "A preppy blue skirt with a white blouse." - icon_state = "plaid_blue" - item_state = "plaid_blue" - item_color = "plaid_blue" - fitted = FEMALE_UNIFORM_TOP - can_adjust = TRUE - alt_covers_chest = TRUE - -/obj/item/clothing/under/plaid_skirt/purple - name = "purple plaid skirt" - desc = "A preppy purple skirt with a white blouse." - icon_state = "plaid_purple" - item_state = "plaid_purple" - item_color = "plaid_purple" - fitted = FEMALE_UNIFORM_TOP - can_adjust = TRUE - alt_covers_chest = TRUE - -/obj/item/clothing/under/singery - name = "yellow performer's outfit" - desc = "Just looking at this makes you want to sing." - icon_state = "ysing" - item_state = "ysing" - item_color = "ysing" - body_parts_covered = CHEST|GROIN|ARMS - fitted = NO_FEMALE_UNIFORM - alternate_worn_layer = ABOVE_SHOES_LAYER - can_adjust = FALSE - -/obj/item/clothing/under/singerb - name = "blue performer's outfit" - desc = "Just looking at this makes you want to sing." - icon_state = "bsing" - item_state = "bsing" - item_color = "bsing" - body_parts_covered = CHEST|GROIN|ARMS - alternate_worn_layer = ABOVE_SHOES_LAYER - fitted = FEMALE_UNIFORM_TOP - can_adjust = FALSE - -/obj/item/clothing/under/plaid_skirt/green - name = "green plaid skirt" - desc = "A preppy green skirt with a white blouse." - icon_state = "plaid_green" - item_state = "plaid_green" - item_color = "plaid_green" - fitted = FEMALE_UNIFORM_TOP - can_adjust = TRUE - alt_covers_chest = TRUE - -/obj/item/clothing/under/jester - name = "jester suit" - desc = "A jolly dress, well suited to entertain your master, nuncle." - icon_state = "jester" - item_color = "jester" - can_adjust = FALSE - -/obj/item/clothing/under/jester/alt - icon_state = "jester2" - -/obj/item/clothing/under/geisha - name = "geisha suit" - desc = "Cute space ninja senpai not included." - icon_state = "geisha" - item_color = "geisha" - body_parts_covered = CHEST|GROIN|ARMS - can_adjust = FALSE - -/obj/item/clothing/under/villain - name = "villain suit" - desc = "A change of wardrobe is necessary if you ever want to catch a real superhero." - icon_state = "villain" - item_color = "villain" - can_adjust = FALSE - -/obj/item/clothing/under/sailor - name = "sailor suit" - desc = "Skipper's in the wardroom drinkin gin'." - icon_state = "sailor" - item_state = "b_suit" - item_color = "sailor" - can_adjust = FALSE - -/obj/item/clothing/under/plasmaman - name = "plasma envirosuit" - desc = "A special containment suit that allows plasma-based lifeforms to exist safely in an oxygenated environment, and automatically extinguishes them in a crisis. Despite being airtight, it's not spaceworthy." - icon_state = "plasmaman" - item_state = "plasmaman" - item_color = "plasmaman" - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 0, "fire" = 95, "acid" = 95) - body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS - can_adjust = FALSE - strip_delay = 80 - var/next_extinguish = 0 - var/extinguish_cooldown = 100 - var/extinguishes_left = 5 - - -/obj/item/clothing/under/plasmaman/examine(mob/user) - ..() - to_chat(user, "There are [extinguishes_left] extinguisher charges left in this suit.") - - -/obj/item/clothing/under/plasmaman/proc/Extinguish(mob/living/carbon/human/H) - if(!istype(H)) - return - - if(H.on_fire) - if(extinguishes_left) - if(next_extinguish > world.time) - return - next_extinguish = world.time + extinguish_cooldown - extinguishes_left-- - H.visible_message("[H]'s suit automatically extinguishes [H.p_them()]!","Your suit automatically extinguishes you.") - H.ExtinguishMob() - new /obj/effect/particle_effect/water(get_turf(H)) - return 0 - -/obj/item/clothing/under/plasmaman/attackby(obj/item/E, mob/user, params) - ..() - if (istype(E, /obj/item/extinguisher_refill)) - if (extinguishes_left == 5) - to_chat(user, "The inbuilt extinguisher is full.") - return - else - extinguishes_left = 5 - to_chat(user, "You refill the suit's built-in extinguisher, using up the cartridge.") - qdel(E) - return - return - return - -/obj/item/extinguisher_refill - name = "envirosuit extinguisher cartridge" - desc = "A cartridge loaded with a compressed extinguisher mix, used to refill the automatic extinguisher on plasma envirosuits." - icon_state = "plasmarefill" - icon = 'icons/obj/device.dmi' - -/obj/item/clothing/under/rank/security/navyblue/russian - name = "\improper Russian officer's uniform" - desc = "The latest in fashionable russian outfits." - icon_state = "hostanclothes" - item_state = "hostanclothes" - item_color = "hostanclothes" - -/obj/item/clothing/under/mummy - name = "mummy wrapping" - desc = "Return the slab or suffer my stale references." - icon_state = "mummy" - item_state = "mummy" - item_color = "mummy" - body_parts_covered = CHEST|GROIN|ARMS|LEGS - fitted = NO_FEMALE_UNIFORM - can_adjust = FALSE - resistance_flags = NONE - -/obj/item/clothing/under/scarecrow - name = "scarecrow clothes" - desc = "Perfect camouflage for hiding in botany." - icon_state = "scarecrow" - item_state = "scarecrow" - item_color = "scarecrow" - body_parts_covered = CHEST|GROIN|ARMS|LEGS - fitted = NO_FEMALE_UNIFORM - can_adjust = FALSE - resistance_flags = NONE - -/obj/item/clothing/under/draculass - name = "draculass coat" - desc = "A dress inspired by the ancient \"Victorian\" era." - icon_state = "draculass" - item_state = "draculass" - item_color = "draculass" - body_parts_covered = CHEST|GROIN|ARMS - fitted = FEMALE_UNIFORM_TOP - can_adjust = FALSE - mutantrace_variation = NO_MUTANTRACE_VARIATION - -/obj/item/clothing/under/drfreeze - name = "doctor freeze's jumpsuit" - desc = "A modified scientist jumpsuit to look extra cool." - icon_state = "drfreeze" - item_state = "drfreeze" - item_color = "drfreeze" - can_adjust = FALSE - mutantrace_variation = NO_MUTANTRACE_VARIATION - -/obj/item/clothing/under/lobster - name = "foam lobster suit" - desc = "Who beheaded the college mascot?" - icon_state = "lobster" - item_state = "lobster" - item_color = "lobster" - fitted = NO_FEMALE_UNIFORM - can_adjust = FALSE - mutantrace_variation = NO_MUTANTRACE_VARIATION - -/obj/item/clothing/under/gondola - name = "gondola hide suit" - desc = "Now you're cooking." - icon_state = "gondola" - item_state = "lb_suit" - item_color = "gondola" - can_adjust = FALSE - -/obj/item/clothing/under/skeleton - name = "skeleton jumpsuit" - desc = "A black jumpsuit with a white bone pattern printed on it. Spooky!" - icon_state = "skeleton" - item_state = "skeleton" - item_color = "skeleton" - body_parts_covered = CHEST|GROIN|ARMS|LEGS - fitted = NO_FEMALE_UNIFORM - can_adjust = FALSE - resistance_flags = NONE - -/obj/item/clothing/under/permit - name = "public nudity permit" - desc = "This permit entitles the bearer to conduct their duties without a uniform. Normally issued to furred crewmembers or those with nothing to hide." - icon = 'icons/obj/card.dmi' - icon_state = "fingerprint1" - item_state = "golem" //This is dumb and hacky but was here when I got here.//No, it really isn't. Why make a new blank clothing sprite if we already have one? - body_parts_covered = CHEST|GROIN +/obj/item/clothing/under/pj/red + name = "red pj's" + desc = "Sleepwear." + icon_state = "red_pyjamas" + item_color = "red_pyjamas" + item_state = "w_suit" + can_adjust = FALSE + +/obj/item/clothing/under/pj/blue + name = "blue pj's" + desc = "Sleepwear." + icon_state = "blue_pyjamas" + item_color = "blue_pyjamas" + item_state = "w_suit" + can_adjust = FALSE + +/obj/item/clothing/under/patriotsuit + name = "Patriotic Suit" + desc = "Motorcycle not included." + icon_state = "ek" + item_state = "ek" + item_color = "ek" + can_adjust = FALSE + +/obj/item/clothing/under/scratch + name = "white suit" + desc = "A white suit, suitable for an excellent host." + icon_state = "scratch" + item_state = "scratch" + item_color = "scratch" + can_adjust = FALSE + +/obj/item/clothing/under/sl_suit + desc = "It's a very amish looking suit." + name = "amish suit" + icon_state = "sl_suit" + item_color = "sl_suit" + can_adjust = FALSE + +/obj/item/clothing/under/roman + name = "\improper Roman armor" + desc = "Ancient Roman armor. Made of metallic and leather straps." + icon_state = "roman" + item_color = "roman" + item_state = "armor" + can_adjust = FALSE + strip_delay = 100 + resistance_flags = NONE + +/obj/item/clothing/under/waiter + name = "waiter's outfit" + desc = "It's a very smart uniform with a special pocket for tip." + icon_state = "waiter" + item_state = "waiter" + item_color = "waiter" + can_adjust = FALSE + +/obj/item/clothing/under/rank/prisoner + name = "prison jumpsuit" + desc = "It's standardised Nanotrasen prisoner-wear. Its suit sensors are stuck in the \"Fully On\" position." + icon_state = "prisoner" + item_state = "o_suit" + item_color = "prisoner" + has_sensor = LOCKED_SENSORS + sensor_mode = SENSOR_COORDS + random_sensor = FALSE + +/obj/item/clothing/under/rank/mailman + name = "mailman's jumpsuit" + desc = "'Special delivery!'" + icon_state = "mailman" + item_state = "b_suit" + item_color = "mailman" + +/obj/item/clothing/under/rank/psyche + name = "psychedelic jumpsuit" + desc = "Groovy!" + icon_state = "psyche" + item_state = "p_suit" + item_color = "psyche" + +/obj/item/clothing/under/rank/clown/sexy + name = "sexy-clown suit" + desc = "It makes you look HONKable!" + icon_state = "sexyclown" + item_state = "sexyclown" + item_color = "sexyclown" + can_adjust = FALSE + +/obj/item/clothing/under/jabroni + name = "Jabroni Outfit" + desc = "The leather club is two sectors down." + icon_state = "darkholme" + item_state = "darkholme" + item_color = "darkholme" + can_adjust = FALSE + +/obj/item/clothing/under/rank/vice + name = "vice officer's jumpsuit" + desc = "It's the standard issue pretty-boy outfit, as seen on Holo-Vision." + icon_state = "vice" + item_state = "gy_suit" + item_color = "vice" + can_adjust = FALSE + +/obj/item/clothing/under/rank/centcom_officer + desc = "It's a jumpsuit worn by CentCom Officers." + name = "\improper CentCom officer's jumpsuit" + icon_state = "officer" + item_state = "g_suit" + item_color = "officer" + alt_covers_chest = TRUE + +/obj/item/clothing/under/rank/centcom_commander + desc = "It's a jumpsuit worn by CentCom's highest-tier Commanders." + name = "\improper CentCom officer's jumpsuit" + icon_state = "centcom" + item_state = "dg_suit" + item_color = "centcom" + +/obj/item/clothing/under/space + name = "\improper NASA jumpsuit" + desc = "It has a NASA logo on it and is made of space-proofed materials." + icon_state = "black" + item_state = "bl_suit" + item_color = "black" + w_class = WEIGHT_CLASS_BULKY + gas_transfer_coefficient = 0.01 + permeability_coefficient = 0.02 + body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS + cold_protection = CHEST | GROIN | LEGS | ARMS //Needs gloves and shoes with cold protection to be fully protected. + min_cold_protection_temperature = SPACE_SUIT_MIN_TEMP_PROTECT + heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS + max_heat_protection_temperature = SPACE_SUIT_MAX_TEMP_PROTECT + can_adjust = FALSE + resistance_flags = NONE + +/obj/item/clothing/under/acj + name = "administrative cybernetic jumpsuit" + icon_state = "syndicate" + item_state = "bl_suit" + item_color = "syndicate" + desc = "A cybernetically enhanced jumpsuit used for administrative duties." + gas_transfer_coefficient = 0.01 + permeability_coefficient = 0.01 + body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS + armor = list("melee" = 100, "bullet" = 100, "laser" = 100,"energy" = 100, "bomb" = 100, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100) + cold_protection = CHEST | GROIN | LEGS | FEET | ARMS | HANDS + min_cold_protection_temperature = SPACE_SUIT_MIN_TEMP_PROTECT + heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS + max_heat_protection_temperature = SPACE_SUIT_MAX_TEMP_PROTECT + can_adjust = FALSE + resistance_flags = FIRE_PROOF | ACID_PROOF + +/obj/item/clothing/under/owl + name = "owl uniform" + desc = "A soft brown jumpsuit made of synthetic feathers and strong conviction." + icon_state = "owl" + item_color = "owl" + can_adjust = FALSE + +/obj/item/clothing/under/griffin + name = "griffon uniform" + desc = "A soft brown jumpsuit with a white feather collar made of synthetic feathers and a lust for mayhem." + icon_state = "griffin" + item_color = "griffin" + can_adjust = FALSE + +/obj/item/clothing/under/cloud + name = "cloud" + desc = "cloud" + icon_state = "cloud" + item_color = "cloud" + can_adjust = FALSE + +/obj/item/clothing/under/gimmick/rank/captain/suit + name = "captain's suit" + desc = "A green suit and yellow necktie. Exemplifies authority." + icon_state = "green_suit" + item_state = "dg_suit" + item_color = "green_suit" + can_adjust = FALSE + +/obj/item/clothing/under/gimmick/rank/head_of_personnel/suit + name = "head of personnel's suit" + desc = "A teal suit and yellow necktie. An authoritative yet tacky ensemble." + icon_state = "teal_suit" + item_state = "g_suit" + item_color = "teal_suit" + can_adjust = FALSE + +/obj/item/clothing/under/suit_jacket + name = "black suit" + desc = "A black suit and red tie. Very formal." + icon_state = "black_suit" + item_state = "bl_suit" + item_color = "black_suit" + can_adjust = FALSE + +/obj/item/clothing/under/suit_jacket/really_black + name = "executive suit" + desc = "A formal black suit and red tie, intended for the station's finest." + icon_state = "really_black_suit" + item_state = "bl_suit" + item_color = "black_suit" + +/obj/item/clothing/under/suit_jacket/female + name = "executive suit" + desc = "A formal trouser suit for women, intended for the station's finest." + icon_state = "black_suit_fem" + item_state = "black_suit_fem" + item_color = "black_suit_fem" + +/obj/item/clothing/under/suit_jacket/green + name = "green suit" + desc = "A green suit and yellow necktie. Baller." + icon_state = "green_suit" + item_state = "dg_suit" + item_color = "green_suit" + can_adjust = FALSE + +/obj/item/clothing/under/suit_jacket/red + name = "red suit" + desc = "A red suit and blue tie. Somewhat formal." + icon_state = "red_suit" + item_state = "r_suit" + item_color = "red_suit" + +/obj/item/clothing/under/suit_jacket/charcoal + name = "charcoal suit" + desc = "A charcoal suit and red tie. Very professional." + icon_state = "charcoal_suit" + item_state = "charcoal_suit" + item_color = "charcoal_suit" + +/obj/item/clothing/under/suit_jacket/navy + name = "navy suit" + desc = "A navy suit and red tie, intended for the station's finest." + icon_state = "navy_suit" + item_state = "navy_suit" + item_color = "navy_suit" + +/obj/item/clothing/under/suit_jacket/burgundy + name = "burgundy suit" + desc = "A burgundy suit and black tie. Somewhat formal." + icon_state = "burgundy_suit" + item_state = "burgundy_suit" + item_color = "burgundy_suit" + +/obj/item/clothing/under/suit_jacket/checkered + name = "checkered suit" + desc = "That's a very nice suit you have there. Shame if something were to happen to it, eh?" + icon_state = "checkered_suit" + item_state = "checkered_suit" + item_color = "checkered_suit" + +/obj/item/clothing/under/suit_jacket/tan + name = "tan suit" + desc = "A tan suit with a yellow tie. Smart, but casual." + icon_state = "tan_suit" + item_state = "tan_suit" + item_color = "tan_suit" + +/obj/item/clothing/under/suit_jacket/white + name = "white suit" + desc = "A white suit and jacket with a blue shirt. You wanna play rough? OKAY!" + icon_state = "white_suit" + item_state = "white_suit" + item_color = "white_suit" + +/obj/item/clothing/under/burial + name = "burial garments" + desc = "Traditional burial garments from the early 22nd century." + icon_state = "burial" + item_state = "burial" + item_color = "burial" + has_sensor = NO_SENSORS + +/obj/item/clothing/under/skirt/black + name = "black skirt" + desc = "A black skirt, very fancy!" + icon_state = "blackskirt" + item_color = "blackskirt" + body_parts_covered = CHEST|GROIN|ARMS + fitted = FEMALE_UNIFORM_TOP + can_adjust = FALSE + +/obj/item/clothing/under/skirt/blue + name = "blue skirt" + desc = "A blue, casual skirt." + icon_state = "blueskirt" + item_color = "blueskirt" + item_state = "b_suit" + body_parts_covered = CHEST|GROIN|ARMS + fitted = FEMALE_UNIFORM_TOP + can_adjust = FALSE + +/obj/item/clothing/under/skirt/red + name = "red skirt" + desc = "A red, casual skirt." + icon_state = "redskirt" + item_color = "redskirt" + item_state = "r_suit" + body_parts_covered = CHEST|GROIN|ARMS + fitted = FEMALE_UNIFORM_TOP + can_adjust = FALSE + +/obj/item/clothing/under/skirt/purple + name = "purple skirt" + desc = "A purple, casual skirt." + icon_state = "purpleskirt" + item_color = "purpleskirt" + item_state = "p_suit" + body_parts_covered = CHEST|GROIN|ARMS + fitted = FEMALE_UNIFORM_TOP + can_adjust = FALSE + + +/obj/item/clothing/under/schoolgirl + name = "blue schoolgirl uniform" + desc = "It's just like one of my Japanese animes!" + icon_state = "schoolgirl" + item_state = "schoolgirl" + item_color = "schoolgirl" + body_parts_covered = CHEST|GROIN|ARMS + fitted = FEMALE_UNIFORM_TOP + can_adjust = FALSE + +/obj/item/clothing/under/schoolgirl/red + name = "red schoolgirl uniform" + icon_state = "schoolgirlred" + item_state = "schoolgirlred" + item_color = "schoolgirlred" + +/obj/item/clothing/under/schoolgirl/green + name = "green schoolgirl uniform" + icon_state = "schoolgirlgreen" + item_state = "schoolgirlgreen" + item_color = "schoolgirlgreen" + +/obj/item/clothing/under/schoolgirl/orange + name = "orange schoolgirl uniform" + icon_state = "schoolgirlorange" + item_state = "schoolgirlorange" + item_color = "schoolgirlorange" + +/obj/item/clothing/under/overalls + name = "laborer's overalls" + desc = "A set of durable overalls for getting the job done." + icon_state = "overalls" + item_state = "lb_suit" + item_color = "overalls" + can_adjust = FALSE + +/obj/item/clothing/under/pirate + name = "pirate outfit" + desc = "Yarr." + icon_state = "pirate" + item_state = "pirate" + item_color = "pirate" + can_adjust = FALSE + +/obj/item/clothing/under/soviet + name = "soviet uniform" + desc = "For the Motherland!" + icon_state = "soviet" + item_state = "soviet" + item_color = "soviet" + can_adjust = FALSE + +/obj/item/clothing/under/redcoat + name = "redcoat uniform" + desc = "Looks old." + icon_state = "redcoat" + item_state = "redcoat" + item_color = "redcoat" + can_adjust = FALSE + +/obj/item/clothing/under/kilt + name = "kilt" + desc = "Includes shoes and plaid." + icon_state = "kilt" + item_state = "kilt" + item_color = "kilt" + body_parts_covered = CHEST|GROIN|LEGS|FEET + fitted = FEMALE_UNIFORM_TOP + can_adjust = FALSE + +/obj/item/clothing/under/kilt/highlander + desc = "You're the only one worthy of this kilt." + item_flags = NODROP + +/obj/item/clothing/under/sexymime + name = "sexy mime outfit" + desc = "The only time when you DON'T enjoy looking at someone's rack." + icon_state = "sexymime" + item_state = "sexymime" + item_color = "sexymime" + body_parts_covered = CHEST|GROIN|LEGS + fitted = FEMALE_UNIFORM_TOP + can_adjust = FALSE + +/obj/item/clothing/under/gladiator + name = "gladiator uniform" + desc = "Are you not entertained? Is that not why you are here?" + icon_state = "gladiator" + item_state = "gladiator" + item_color = "gladiator" + body_parts_covered = CHEST|GROIN|ARMS + fitted = NO_FEMALE_UNIFORM + can_adjust = FALSE + resistance_flags = NONE + +/obj/item/clothing/under/gladiator/ash_walker + desc = "This gladiator uniform appears to be covered in ash and fairly dated." + has_sensor = NO_SENSORS + +/obj/item/clothing/under/sundress + name = "sundress" + desc = "Makes you want to frolic in a field of daisies." + icon_state = "sundress" + item_state = "sundress" + item_color = "sundress" + body_parts_covered = CHEST|GROIN + fitted = FEMALE_UNIFORM_TOP + can_adjust = FALSE + +/obj/item/clothing/under/captainparade + name = "captain's parade uniform" + desc = "A captain's luxury-wear, for special occasions." + icon_state = "captain_parade" + item_state = "by_suit" + item_color = "captain_parade" + can_adjust = FALSE + +/obj/item/clothing/under/hosparademale + name = "head of security's parade uniform" + desc = "A male head of security's luxury-wear, for special occasions." + icon_state = "hos_parade_male" + item_state = "r_suit" + item_color = "hos_parade_male" + can_adjust = FALSE + +/obj/item/clothing/under/hosparadefem + name = "head of security's parade uniform" + desc = "A female head of security's luxury-wear, for special occasions." + icon_state = "hos_parade_fem" + item_state = "r_suit" + item_color = "hos_parade_fem" + fitted = FEMALE_UNIFORM_TOP + can_adjust = FALSE + +/obj/item/clothing/under/assistantformal + name = "assistant's formal uniform" + desc = "An assistant's formal-wear. Why an assistant needs formal-wear is still unknown." + icon_state = "assistant_formal" + item_state = "gy_suit" + item_color = "assistant_formal" + can_adjust = FALSE + +/obj/item/clothing/under/blacktango + name = "black tango dress" + desc = "Filled with Latin fire." + icon_state = "black_tango" + item_state = "wcoat" + item_color = "black_tango" + fitted = FEMALE_UNIFORM_TOP + can_adjust = FALSE + body_parts_covered = CHEST|GROIN + +/obj/item/clothing/under/stripeddress + name = "striped dress" + desc = "Fashion in space." + icon_state = "striped_dress" + item_state = "stripeddress" + item_color = "striped_dress" + body_parts_covered = CHEST|GROIN|ARMS + fitted = FEMALE_UNIFORM_FULL + can_adjust = FALSE + +/obj/item/clothing/under/sailordress + name = "sailor dress" + desc = "Formal wear for a leading lady." + icon_state = "sailor_dress" + item_state = "sailordress" + item_color = "sailor_dress" + body_parts_covered = CHEST|GROIN|ARMS + fitted = FEMALE_UNIFORM_TOP + can_adjust = FALSE + +/obj/item/clothing/under/redeveninggown + name = "red evening gown" + desc = "Fancy dress for space bar singers." + icon_state = "red_evening_gown" + item_state = "redeveninggown" + item_color = "red_evening_gown" + fitted = FEMALE_UNIFORM_TOP + can_adjust = FALSE + +/obj/item/clothing/under/maid + name = "maid costume" + desc = "Maid in China." + icon_state = "maid" + item_state = "maid" + item_color = "maid" + body_parts_covered = CHEST|GROIN + fitted = FEMALE_UNIFORM_TOP + can_adjust = FALSE + +/obj/item/clothing/under/maid/Initialize() + . = ..() + var/obj/item/clothing/accessory/maidapron/A = new (src) + attach_accessory(A) + +/obj/item/clothing/under/janimaid + name = "maid uniform" + desc = "A simple maid uniform for housekeeping." + icon_state = "janimaid" + item_state = "janimaid" + item_color = "janimaid" + body_parts_covered = CHEST|GROIN + fitted = FEMALE_UNIFORM_TOP + can_adjust = FALSE + +/obj/item/clothing/under/plaid_skirt + name = "red plaid skirt" + desc = "A preppy red skirt with a white blouse." + icon_state = "plaid_red" + item_state = "plaid_red" + item_color = "plaid_red" + fitted = FEMALE_UNIFORM_TOP + can_adjust = TRUE + alt_covers_chest = TRUE + +/obj/item/clothing/under/plaid_skirt/blue + name = "blue plaid skirt" + desc = "A preppy blue skirt with a white blouse." + icon_state = "plaid_blue" + item_state = "plaid_blue" + item_color = "plaid_blue" + fitted = FEMALE_UNIFORM_TOP + can_adjust = TRUE + alt_covers_chest = TRUE + +/obj/item/clothing/under/plaid_skirt/purple + name = "purple plaid skirt" + desc = "A preppy purple skirt with a white blouse." + icon_state = "plaid_purple" + item_state = "plaid_purple" + item_color = "plaid_purple" + fitted = FEMALE_UNIFORM_TOP + can_adjust = TRUE + alt_covers_chest = TRUE + +/obj/item/clothing/under/singery + name = "yellow performer's outfit" + desc = "Just looking at this makes you want to sing." + icon_state = "ysing" + item_state = "ysing" + item_color = "ysing" + body_parts_covered = CHEST|GROIN|ARMS + fitted = NO_FEMALE_UNIFORM + alternate_worn_layer = ABOVE_SHOES_LAYER + can_adjust = FALSE + +/obj/item/clothing/under/singerb + name = "blue performer's outfit" + desc = "Just looking at this makes you want to sing." + icon_state = "bsing" + item_state = "bsing" + item_color = "bsing" + body_parts_covered = CHEST|GROIN|ARMS + alternate_worn_layer = ABOVE_SHOES_LAYER + fitted = FEMALE_UNIFORM_TOP + can_adjust = FALSE + +/obj/item/clothing/under/plaid_skirt/green + name = "green plaid skirt" + desc = "A preppy green skirt with a white blouse." + icon_state = "plaid_green" + item_state = "plaid_green" + item_color = "plaid_green" + fitted = FEMALE_UNIFORM_TOP + can_adjust = TRUE + alt_covers_chest = TRUE + +/obj/item/clothing/under/jester + name = "jester suit" + desc = "A jolly dress, well suited to entertain your master, nuncle." + icon_state = "jester" + item_color = "jester" + can_adjust = FALSE + +/obj/item/clothing/under/jester/alt + icon_state = "jester2" + +/obj/item/clothing/under/geisha + name = "geisha suit" + desc = "Cute space ninja senpai not included." + icon_state = "geisha" + item_color = "geisha" + body_parts_covered = CHEST|GROIN|ARMS + can_adjust = FALSE + +/obj/item/clothing/under/villain + name = "villain suit" + desc = "A change of wardrobe is necessary if you ever want to catch a real superhero." + icon_state = "villain" + item_color = "villain" + can_adjust = FALSE + +/obj/item/clothing/under/sailor + name = "sailor suit" + desc = "Skipper's in the wardroom drinkin gin'." + icon_state = "sailor" + item_state = "b_suit" + item_color = "sailor" + can_adjust = FALSE + +/obj/item/clothing/under/plasmaman + name = "plasma envirosuit" + desc = "A special containment suit that allows plasma-based lifeforms to exist safely in an oxygenated environment, and automatically extinguishes them in a crisis. Despite being airtight, it's not spaceworthy." + icon_state = "plasmaman" + item_state = "plasmaman" + item_color = "plasmaman" + armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 0, "fire" = 95, "acid" = 95) + body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS + can_adjust = FALSE + strip_delay = 80 + var/next_extinguish = 0 + var/extinguish_cooldown = 100 + var/extinguishes_left = 5 + + +/obj/item/clothing/under/plasmaman/examine(mob/user) + ..() + to_chat(user, "There are [extinguishes_left] extinguisher charges left in this suit.") + + +/obj/item/clothing/under/plasmaman/proc/Extinguish(mob/living/carbon/human/H) + if(!istype(H)) + return + + if(H.on_fire) + if(extinguishes_left) + if(next_extinguish > world.time) + return + next_extinguish = world.time + extinguish_cooldown + extinguishes_left-- + H.visible_message("[H]'s suit automatically extinguishes [H.p_them()]!","Your suit automatically extinguishes you.") + H.ExtinguishMob() + new /obj/effect/particle_effect/water(get_turf(H)) + return 0 + +/obj/item/clothing/under/plasmaman/attackby(obj/item/E, mob/user, params) + ..() + if (istype(E, /obj/item/extinguisher_refill)) + if (extinguishes_left == 5) + to_chat(user, "The inbuilt extinguisher is full.") + return + else + extinguishes_left = 5 + to_chat(user, "You refill the suit's built-in extinguisher, using up the cartridge.") + qdel(E) + return + return + return + +/obj/item/extinguisher_refill + name = "envirosuit extinguisher cartridge" + desc = "A cartridge loaded with a compressed extinguisher mix, used to refill the automatic extinguisher on plasma envirosuits." + icon_state = "plasmarefill" + icon = 'icons/obj/device.dmi' + +/obj/item/clothing/under/rank/security/navyblue/russian + name = "\improper Russian officer's uniform" + desc = "The latest in fashionable russian outfits." + icon_state = "hostanclothes" + item_state = "hostanclothes" + item_color = "hostanclothes" + +/obj/item/clothing/under/mummy + name = "mummy wrapping" + desc = "Return the slab or suffer my stale references." + icon_state = "mummy" + item_state = "mummy" + item_color = "mummy" + body_parts_covered = CHEST|GROIN|ARMS|LEGS + fitted = NO_FEMALE_UNIFORM + can_adjust = FALSE + resistance_flags = NONE + +/obj/item/clothing/under/scarecrow + name = "scarecrow clothes" + desc = "Perfect camouflage for hiding in botany." + icon_state = "scarecrow" + item_state = "scarecrow" + item_color = "scarecrow" + body_parts_covered = CHEST|GROIN|ARMS|LEGS + fitted = NO_FEMALE_UNIFORM + can_adjust = FALSE + resistance_flags = NONE + +/obj/item/clothing/under/draculass + name = "draculass coat" + desc = "A dress inspired by the ancient \"Victorian\" era." + icon_state = "draculass" + item_state = "draculass" + item_color = "draculass" + body_parts_covered = CHEST|GROIN|ARMS + fitted = FEMALE_UNIFORM_TOP + can_adjust = FALSE + mutantrace_variation = NO_MUTANTRACE_VARIATION + +/obj/item/clothing/under/drfreeze + name = "doctor freeze's jumpsuit" + desc = "A modified scientist jumpsuit to look extra cool." + icon_state = "drfreeze" + item_state = "drfreeze" + item_color = "drfreeze" + can_adjust = FALSE + mutantrace_variation = NO_MUTANTRACE_VARIATION + +/obj/item/clothing/under/lobster + name = "foam lobster suit" + desc = "Who beheaded the college mascot?" + icon_state = "lobster" + item_state = "lobster" + item_color = "lobster" + fitted = NO_FEMALE_UNIFORM + can_adjust = FALSE + mutantrace_variation = NO_MUTANTRACE_VARIATION + +/obj/item/clothing/under/gondola + name = "gondola hide suit" + desc = "Now you're cooking." + icon_state = "gondola" + item_state = "lb_suit" + item_color = "gondola" + can_adjust = FALSE + +/obj/item/clothing/under/skeleton + name = "skeleton jumpsuit" + desc = "A black jumpsuit with a white bone pattern printed on it. Spooky!" + icon_state = "skeleton" + item_state = "skeleton" + item_color = "skeleton" + body_parts_covered = CHEST|GROIN|ARMS|LEGS + fitted = NO_FEMALE_UNIFORM + can_adjust = FALSE + resistance_flags = NONE + +/obj/item/clothing/under/gear_harness + name = "gear harness" + desc = "A simple, inconspicuous harness replacement for a jumpsuit." + icon_state = "gear_harness" + item_state = "gear_harness" //We dont use golem do to being a item, item without faces making it default to error suit sprites. + body_parts_covered = CHEST|GROIN \ No newline at end of file diff --git a/code/modules/crafting/craft.dm b/code/modules/crafting/craft.dm index ba2a27af77..3e96512bb8 100644 --- a/code/modules/crafting/craft.dm +++ b/code/modules/crafting/craft.dm @@ -21,7 +21,7 @@ CAT_BURGER, CAT_CAKE, CAT_EGG, - CAT_SUSHI, //Called Fish + CAT_FISH, CAT_ICE, //Called Frozen CAT_MEAT, CAT_MISCFOOD, diff --git a/code/modules/crafting/recipes.dm b/code/modules/crafting/recipes.dm index dbff7988c1..a76be1ff45 100644 --- a/code/modules/crafting/recipes.dm +++ b/code/modules/crafting/recipes.dm @@ -365,28 +365,6 @@ parts = list(/obj/item/camera = 1) category = CAT_MISC -/datum/crafting_recipe/lizardhat - name = "Lizard Cloche Hat" - result = /obj/item/clothing/head/lizard - time = 10 - reqs = list(/obj/item/organ/tail/lizard = 1) - category = CAT_MISC - -/datum/crafting_recipe/lizardhat_alternate - name = "Lizard Cloche Hat" - result = /obj/item/clothing/head/lizard - time = 10 - reqs = list(/obj/item/stack/sheet/animalhide/lizard = 1) - category = CAT_MISC - -/datum/crafting_recipe/kittyears - name = "Kitty Ears" - result = /obj/item/clothing/head/kitty/genuine - time = 10 - reqs = list(/obj/item/organ/tail/cat = 1, - /obj/item/organ/ears/cat = 1) - category = CAT_MISC - /datum/crafting_recipe/skateboard name = "Skateboard" result = /obj/vehicle/ridden/scooter/skateboard @@ -641,6 +619,15 @@ /obj/item/assembly/igniter = 1) category = CAT_MISC + +/datum/crafting_recipe/wheelchair + name = "Wheelchair" + result = /obj/vehicle/ridden/wheelchair + reqs = list(/obj/item/stack/sheet/plasteel = 2, + /obj/item/stack/rods = 8) + time = 100 + category = CAT_MISC + /datum/crafting_recipe/rcl name = "Makeshift Rapid Cable Layer" result = /obj/item/twohanded/rcl/ghetto @@ -672,6 +659,28 @@ tools = list(TOOL_SCREWDRIVER, TOOL_WRENCH, TOOL_WELDER) category = CAT_MISC +/datum/crafting_recipe/lizardhat + name = "Lizard Cloche Hat" + result = /obj/item/clothing/head/lizard + time = 10 + reqs = list(/obj/item/organ/tail/lizard = 1) + category = CAT_CLOTHING + +/datum/crafting_recipe/lizardhat_alternate + name = "Lizard Cloche Hat" + result = /obj/item/clothing/head/lizard + time = 10 + reqs = list(/obj/item/stack/sheet/animalhide/lizard = 1) + category = CAT_CLOTHING + +/datum/crafting_recipe/kittyears + name = "Kitty Ears" + result = /obj/item/clothing/head/kitty/genuine + time = 10 + reqs = list(/obj/item/organ/tail/cat = 1, + /obj/item/organ/ears/cat = 1) + category = CAT_CLOTHING + /datum/crafting_recipe/hudsunsec name = "Security HUDsunglasses" result = /obj/item/clothing/glasses/hud/security/sunglasses @@ -781,3 +790,36 @@ /datum/reagent/water = 15) time = 40 category = CAT_MISC + +/datum/crafting_recipe/smartdart + name = "Medical smartdart" + result = /obj/item/reagent_containers/syringe/dart + reqs = list(/obj/item/stack/sheet/metal = 1, + /obj/item/stack/sheet/glass = 1, + /obj/item/stack/sheet/plastic = 1) + time = 10 + category = CAT_WEAPONRY + subcategory = CAT_AMMO + +/datum/crafting_recipe/medolier + name = "Medolier" + result = /obj/item/storage/belt/medolier + reqs = list(/obj/item/stack/sheet/metal = 2, + /obj/item/stack/sheet/cloth = 3, + /obj/item/stack/sheet/plastic = 4) + time = 30 + category = CAT_WEAPONRY + subcategory = CAT_AMMO + +/datum/crafting_recipe/smartdartgun + name = "Smart dartgun" + result = /obj/item/gun/syringe/dart + reqs = list(/obj/item/stack/sheet/metal = 15, + /obj/item/stack/sheet/glass = 10, + /obj/item/tank/internals = 1, + /obj/item/reagent_containers/glass/beaker = 1, + /obj/item/stack/sheet/plastic = 10, + /obj/item/stack/cable_coil = 2) + time = 150 //It's a gun + category = CAT_WEAPONRY + subcategory = CAT_WEAPON diff --git a/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm b/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm index deba080ca2..483055cb0d 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm @@ -15,6 +15,7 @@ var/max_n_of_items = 1500 var/allow_ai_retrieve = FALSE var/list/initial_contents + var/visible_contents = TRUE /obj/machinery/smartfridge/Initialize() . = ..() @@ -37,11 +38,21 @@ update_icon() /obj/machinery/smartfridge/update_icon() - var/startstate = initial(icon_state) if(!stat) - icon_state = startstate + if(visible_contents) + switch(contents.len) + if(0) + icon_state = "[initial(icon_state)]" + if(1 to 25) + icon_state = "[initial(icon_state)]1" + if(26 to 75) + icon_state = "[initial(icon_state)]2" + if(76 to INFINITY) + icon_state = "[initial(icon_state)]3" + else + icon_state = "[initial(icon_state)]" else - icon_state = "[startstate]-off" + icon_state = "[initial(icon_state)]-off" @@ -50,7 +61,14 @@ ********************/ /obj/machinery/smartfridge/attackby(obj/item/O, mob/user, params) - if(default_deconstruction_screwdriver(user, "smartfridge_open", "smartfridge", O)) + if(user.a_intent == INTENT_HARM) + return ..() + + if(default_deconstruction_screwdriver(user, icon_state, icon_state, O)) + cut_overlays() + if(panel_open) + add_overlay("[initial(icon_state)]-panel") + updateUsrDialog() return if(default_pry_open(O)) @@ -64,49 +82,46 @@ updateUsrDialog() return - if(!stat) - - if(contents.len >= max_n_of_items) - to_chat(user, "\The [src] is full!") - return FALSE - - if(accept_check(O)) - load(O) - user.visible_message("[user] has added \the [O] to \the [src].", "You add \the [O] to \the [src].") - updateUsrDialog() - return TRUE - - if(istype(O, /obj/item/storage/bag)) - var/obj/item/storage/P = O - var/loaded = 0 - for(var/obj/G in P.contents) - if(contents.len >= max_n_of_items) - break - if(accept_check(G)) - load(G) - loaded++ - updateUsrDialog() - - if(loaded) - if(contents.len >= max_n_of_items) - user.visible_message("[user] loads \the [src] with \the [O].", \ - "You fill \the [src] with \the [O].") - else - user.visible_message("[user] loads \the [src] with \the [O].", \ - "You load \the [src] with \the [O].") - if(O.contents.len > 0) - to_chat(user, "Some items are refused.") - return TRUE - else - to_chat(user, "There is nothing in [O] to put in [src]!") - return FALSE - - if(user.a_intent != INTENT_HARM) - to_chat(user, "\The [src] smartly refuses [O].") + if(stat) updateUsrDialog() return FALSE - else - return ..() + + if(contents.len >= max_n_of_items) + to_chat(user, "\The [src] is full!") + return FALSE + + if(accept_check(O)) + load(O) + user.visible_message("[user] has added \the [O] to \the [src].", "You add \the [O] to \the [src].") + updateUsrDialog() + if (visible_contents) + update_icon() + return TRUE + + if(istype(O, /obj/item/storage/bag)) + var/obj/item/storage/P = O + var/loaded = 0 + for(var/obj/G in P.contents) + if(contents.len >= max_n_of_items) + break + if(accept_check(G)) + load(G) + loaded++ + updateUsrDialog() + + if(loaded) + user.visible_message("[user] loads \the [src] with \the [O].", \ + "You [contents.len >= max_n_of_items ? "fill" : "load"] \the [src] with \the [O].") + if(O.contents.len > 0) + to_chat(user, "Some items are refused.") + return TRUE + else + to_chat(user, "There is nothing in [O] to put in [src]!") + return FALSE + + to_chat(user, "\The [src] smartly refuses [O].") + updateUsrDialog() + return FALSE @@ -186,6 +201,8 @@ O.forceMove(drop_location()) adjust_item_drop_location(O) break + if (visible_contents) + update_icon() return TRUE for(var/obj/item/O in src) @@ -195,6 +212,8 @@ O.forceMove(drop_location()) adjust_item_drop_location(O) desired-- + if (visible_contents) + update_icon() return TRUE return FALSE @@ -210,6 +229,7 @@ use_power = IDLE_POWER_USE idle_power_usage = 5 active_power_usage = 200 + visible_contents = FALSE var/drying = FALSE /obj/machinery/smartfridge/drying_rack/Initialize() @@ -414,6 +434,7 @@ name = "disk compartmentalizer" desc = "A machine capable of storing a variety of disks. Denoted by most as the DSU (disk storage unit)." icon_state = "disktoaster" + visible_contents = FALSE pass_flags = PASSTABLE /obj/machinery/smartfridge/disks/accept_check(obj/item/O) diff --git a/code/modules/food_and_drinks/recipes/tablecraft/recipes_meat.dm b/code/modules/food_and_drinks/recipes/tablecraft/recipes_meat.dm index c16c7268b9..7eff2820c5 100644 --- a/code/modules/food_and_drinks/recipes/tablecraft/recipes_meat.dm +++ b/code/modules/food_and_drinks/recipes/tablecraft/recipes_meat.dm @@ -38,37 +38,6 @@ // see code/module/crafting/table.dm -////////////////////////////////////////////////FISH//////////////////////////////////////////////// - -/datum/crafting_recipe/food/cubancarp - name = "Cuban carp" - reqs = list( - /datum/reagent/consumable/flour = 5, - /obj/item/reagent_containers/food/snacks/grown/chili = 1, - /obj/item/reagent_containers/food/snacks/carpmeat = 1 - ) - result = /obj/item/reagent_containers/food/snacks/cubancarp - subcategory = CAT_MEAT - -/datum/crafting_recipe/food/fishandchips - name = "Fish and chips" - reqs = list( - /obj/item/reagent_containers/food/snacks/fries = 1, - /obj/item/reagent_containers/food/snacks/carpmeat = 1 - ) - result = /obj/item/reagent_containers/food/snacks/fishandchips - subcategory = CAT_MEAT - -/datum/crafting_recipe/food/fishfingers - name = "Fish fingers" - reqs = list( - /datum/reagent/consumable/flour = 5, - /obj/item/reagent_containers/food/snacks/bun = 1, - /obj/item/reagent_containers/food/snacks/carpmeat = 1 - ) - result = /obj/item/reagent_containers/food/snacks/fishfingers - subcategory = CAT_MEAT - ////////////////////////////////////////////////MR SPIDER//////////////////////////////////////////////// /datum/crafting_recipe/food/spidereggsham diff --git a/code/modules/food_and_drinks/recipes/tablecraft/recipes_pastry.dm b/code/modules/food_and_drinks/recipes/tablecraft/recipes_pastry.dm index 4b76ca120b..2246d12df4 100644 --- a/code/modules/food_and_drinks/recipes/tablecraft/recipes_pastry.dm +++ b/code/modules/food_and_drinks/recipes/tablecraft/recipes_pastry.dm @@ -22,7 +22,7 @@ ) result = /obj/item/reagent_containers/food/snacks/donut subcategory = CAT_PASTRY - + /datum/crafting_recipe/food/donut time = 15 name = "Semen donut" @@ -104,7 +104,7 @@ datum/crafting_recipe/food/donut/meat /datum/crafting_recipe/food/rofflewaffles name = "Roffle waffles" reqs = list( - /datum/reagent/mushroomhallucinogen = 5, + /datum/reagent/drug/mushroomhallucinogen = 5, /obj/item/reagent_containers/food/snacks/pastrybase = 2 ) result = /obj/item/reagent_containers/food/snacks/rofflewaffles @@ -205,16 +205,6 @@ datum/crafting_recipe/food/donut/meat ////////////////////////////////////////////OTHER//////////////////////////////////////////// -/datum/crafting_recipe/food/hotdog - name = "Hot dog" - reqs = list( - /datum/reagent/consumable/ketchup = 5, - /obj/item/reagent_containers/food/snacks/bun = 1, - /obj/item/reagent_containers/food/snacks/sausage = 1 - ) - result = /obj/item/reagent_containers/food/snacks/hotdog - subcategory = CAT_PASTRY - /datum/crafting_recipe/food/meatbun name = "Meat bun" reqs = list( diff --git a/code/modules/food_and_drinks/recipes/tablecraft/recipes_sandwich.dm b/code/modules/food_and_drinks/recipes/tablecraft/recipes_sandwich.dm index 0f1c40da3f..133713ac75 100644 --- a/code/modules/food_and_drinks/recipes/tablecraft/recipes_sandwich.dm +++ b/code/modules/food_and_drinks/recipes/tablecraft/recipes_sandwich.dm @@ -52,7 +52,7 @@ result = /obj/item/reagent_containers/food/snacks/notasandwich subcategory = CAT_SANDWICH -/datum/crafting_recipe/food/notasandwich +/datum/crafting_recipe/food/tunasandwich name = "Tuna sandwich" reqs = list( /obj/item/reagent_containers/food/snacks/breadslice/plain = 2, @@ -62,3 +62,13 @@ ) result = /obj/item/reagent_containers/food/snacks/tuna_sandwich subcategory = CAT_SANDWICH + +/datum/crafting_recipe/food/hotdog + name = "Hot dog" + reqs = list( + /datum/reagent/consumable/ketchup = 5, + /obj/item/reagent_containers/food/snacks/bun = 1, + /obj/item/reagent_containers/food/snacks/sausage = 1 + ) + result = /obj/item/reagent_containers/food/snacks/hotdog + subcategory = CAT_SANDWICH diff --git a/code/modules/food_and_drinks/recipes/tablecraft/recipes_sushi.dm b/code/modules/food_and_drinks/recipes/tablecraft/recipes_sushi.dm index 99d48cf69d..9dbf1d684b 100644 --- a/code/modules/food_and_drinks/recipes/tablecraft/recipes_sushi.dm +++ b/code/modules/food_and_drinks/recipes/tablecraft/recipes_sushi.dm @@ -7,7 +7,7 @@ /datum/reagent/consumable/rice = 10 ) result = /obj/item/reagent_containers/food/snacks/sushi_rice - subcategory = CAT_SUSHI + subcategory = CAT_FISH /datum/crafting_recipe/food/sea_weed name = "Sea Weed Sheet" @@ -17,7 +17,7 @@ /obj/item/reagent_containers/food/snacks/grown/kudzupod = 1, ) result = /obj/item/reagent_containers/food/snacks/sea_weed - subcategory = CAT_SUSHI + subcategory = CAT_FISH /datum/crafting_recipe/food/tuna_can name = "Can of Tuna" @@ -27,7 +27,7 @@ /obj/item/reagent_containers/food/snacks/carpmeat = 1, ) result = /obj/item/reagent_containers/food/snacks/tuna - subcategory = CAT_SUSHI + subcategory = CAT_FISH //////////////////////////Sushi///////////////////////////////// @@ -39,7 +39,7 @@ /obj/item/reagent_containers/food/snacks/carpmeat = 1 ) result = /obj/item/reagent_containers/food/snacks/sashimi - subcategory = CAT_SUSHI + subcategory = CAT_FISH /datum/crafting_recipe/food/riceball name = "Onigiri" @@ -49,7 +49,7 @@ /obj/item/reagent_containers/food/snacks/sushi_rice = 1 ) result = /obj/item/reagent_containers/food/snacks/riceball - subcategory = CAT_SUSHI + subcategory = CAT_FISH /datum/crafting_recipe/food/sushie_egg name = "Tobiko" @@ -59,7 +59,7 @@ /obj/item/reagent_containers/food/snacks/sea_weed = 2, ) result = /obj/item/reagent_containers/food/snacks/tobiko - subcategory = CAT_SUSHI + subcategory = CAT_FISH /datum/crafting_recipe/food/sushie_basic name = "Funa Hosomaki" @@ -70,7 +70,7 @@ /obj/item/reagent_containers/food/snacks/sea_weed = 3, ) result = /obj/item/reagent_containers/food/snacks/sushie_basic - subcategory = CAT_SUSHI + subcategory = CAT_FISH /datum/crafting_recipe/food/sushie_adv name = "Funa Nigiri" @@ -80,7 +80,7 @@ /obj/item/reagent_containers/food/snacks/carpmeat = 1 ) result = /obj/item/reagent_containers/food/snacks/sushie_adv - subcategory = CAT_SUSHI + subcategory = CAT_FISH /datum/crafting_recipe/food/sushie_pro name = "Well made Funa Nigiri" @@ -91,4 +91,35 @@ /obj/item/reagent_containers/food/snacks/sea_weed = 1 ) result = /obj/item/reagent_containers/food/snacks/sushie_pro - subcategory = CAT_SUSHI + subcategory = CAT_FISH + +///////////////Gaijin junk///////////////////////////////////// + +/datum/crafting_recipe/food/fishfingers + name = "Fish fingers" + reqs = list( + /datum/reagent/consumable/flour = 5, + /obj/item/reagent_containers/food/snacks/bun = 1, + /obj/item/reagent_containers/food/snacks/carpmeat = 1 + ) + result = /obj/item/reagent_containers/food/snacks/fishfingers + subcategory = CAT_FISH + +/datum/crafting_recipe/food/cubancarp + name = "Cuban carp" + reqs = list( + /datum/reagent/consumable/flour = 5, + /obj/item/reagent_containers/food/snacks/grown/chili = 1, + /obj/item/reagent_containers/food/snacks/carpmeat = 1 + ) + result = /obj/item/reagent_containers/food/snacks/cubancarp + subcategory = CAT_FISH + +/datum/crafting_recipe/food/fishandchips + name = "Fish and chips" + reqs = list( + /obj/item/reagent_containers/food/snacks/fries = 1, + /obj/item/reagent_containers/food/snacks/carpmeat = 1 + ) + result = /obj/item/reagent_containers/food/snacks/fishandchips + subcategory = CAT_FISH \ No newline at end of file diff --git a/code/modules/goonchat/browserassets/js/browserOutput.js b/code/modules/goonchat/browserassets/js/browserOutput.js index 64b41a5921..33553d765e 100644 --- a/code/modules/goonchat/browserassets/js/browserOutput.js +++ b/code/modules/goonchat/browserassets/js/browserOutput.js @@ -471,15 +471,6 @@ function ehjaxCallback(data) { handleClientData(data.clientData.ckey, data.clientData.ip, data.clientData.compid); } sendVolumeUpdate(); - } else if (data.firebug) { - if (data.trigger) { - internalOutput('Loading firebug console, triggered by '+data.trigger+'...', 'internal'); - } else { - internalOutput('Loading firebug console...', 'internal'); - } - var firebugEl = document.createElement('script'); - firebugEl.src = 'https://getfirebug.com/firebug-lite-debug.js'; - document.body.appendChild(firebugEl); } else if (data.adminMusic) { if (typeof data.adminMusic === 'string') { var adminMusic = byondDecode(data.adminMusic); diff --git a/code/modules/mapping/map_template.dm b/code/modules/mapping/map_template.dm index ceba29baec..1f55f18823 100644 --- a/code/modules/mapping/map_template.dm +++ b/code/modules/mapping/map_template.dm @@ -29,6 +29,7 @@ var/list/obj/machinery/atmospherics/atmos_machines = list() var/list/obj/structure/cable/cables = list() var/list/atom/atoms = list() + var/list/area/areas = list() var/list/turfs = block( locate(bounds[MAP_MINX], bounds[MAP_MINY], bounds[MAP_MINZ]), locate(bounds[MAP_MAXX], bounds[MAP_MAXY], bounds[MAP_MAXZ])) @@ -37,6 +38,7 @@ for(var/L in turfs) var/turf/B = L atoms += B + areas |= B.loc for(var/A in B) atoms += A if(istype(A, /obj/structure/cable)) @@ -48,6 +50,7 @@ var/turf/T = L T.air_update_turf(TRUE) //calculate adjacent turfs along the border to prevent runtimes + SSmapping.reg_in_areas_in_z(areas) SSatoms.InitializeAtoms(atoms) SSmachines.setup_template_powernets(cables) SSair.setup_template_machinery(atmos_machines) diff --git a/code/modules/mining/lavaland/necropolis_chests.dm b/code/modules/mining/lavaland/necropolis_chests.dm index 0990ca961a..eaac1984e3 100644 --- a/code/modules/mining/lavaland/necropolis_chests.dm +++ b/code/modules/mining/lavaland/necropolis_chests.dm @@ -273,23 +273,12 @@ to_chat(user, "You release the wisp. It begins to bob around your head.") icon_state = "lantern" wisp.orbit(user, 20) - user.update_sight() SSblackbox.record_feedback("tally", "wisp_lantern", 1, "Freed") else to_chat(user, "You return the wisp to the lantern.") - - var/mob/target - if(wisp.orbiting) - target = wisp.orbiting.orbiting - wisp.stop_orbit() - wisp.forceMove(src) - - if (istype(target)) - target.update_sight() - to_chat(target, "Your vision returns to normal.") - icon_state = "lantern-blue" + wisp.forceMove(src) SSblackbox.record_feedback("tally", "wisp_lantern", 1, "Returned") /obj/item/wisp_lantern/Initialize() @@ -302,7 +291,7 @@ qdel(wisp) else wisp.visible_message("[wisp] has a sad feeling for a moment, then it passes.") - ..() + return ..() /obj/effect/wisp name = "friendly wisp" @@ -314,6 +303,25 @@ var/sight_flags = SEE_MOBS var/lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE +/obj/effect/wisp/orbit(atom/thing, radius, clockwise, rotation_speed, rotation_segments, pre_rotation, lockinorbit) + . = ..() + if(ismob(thing)) + RegisterSignal(thing, COMSIG_MOB_UPDATE_SIGHT, .proc/update_user_sight) + var/mob/being = thing + being.update_sight() + to_chat(thing, "The wisp enhances your vision.") + +/obj/effect/wisp/stop_orbit(datum/component/orbiter/orbits) + . = ..() + if(ismob(orbits.parent)) + UnregisterSignal(orbits.parent, COMSIG_MOB_UPDATE_SIGHT) + to_chat(orbits.parent, "Your vision returns to normal.") + +/obj/effect/wisp/proc/update_user_sight(mob/user) + user.sight |= sight_flags + if(!isnull(lighting_alpha)) + user.lighting_alpha = min(user.lighting_alpha, lighting_alpha) + //Red/Blue Cubes /obj/item/warp_cube name = "blue cube" @@ -781,19 +789,17 @@ var/turf/T = get_turf(src) var/list/contents = T.GetAllContents() var/mob/dead/observer/current_spirits = list() - var/list/orbiters = list() for(var/thing in contents) var/atom/A = thing - if (A.orbiters) - orbiters += A.orbiters + A.transfer_observers_to(src) - for(var/thing in orbiters) - var/datum/orbit/O = thing - if (isobserver(O.orbiter)) - var/mob/dead/observer/G = O.orbiter - ghost_counter++ - G.invisibility = 0 - current_spirits |= G + for(var/i in orbiters?.orbiters) + if(!isobserver(i)) + continue + var/mob/dead/observer/G = i + ghost_counter++ + G.invisibility = 0 + current_spirits |= G for(var/mob/dead/observer/G in spirits - current_spirits) G.invisibility = GLOB.observer_default_invisibility diff --git a/code/modules/mob/camera/camera.dm b/code/modules/mob/camera/camera.dm index 883f5a034f..c780d57810 100644 --- a/code/modules/mob/camera/camera.dm +++ b/code/modules/mob/camera/camera.dm @@ -26,7 +26,9 @@ return /mob/camera/forceMove(atom/destination) + var/oldloc = loc loc = destination + Moved(oldloc, NONE, TRUE) /mob/camera/emote(act, m_type=1, message = null, intentional = FALSE) return diff --git a/code/modules/mob/dead/dead.dm b/code/modules/mob/dead/dead.dm index d886a41b0f..381dc131e7 100644 --- a/code/modules/mob/dead/dead.dm +++ b/code/modules/mob/dead/dead.dm @@ -34,7 +34,9 @@ INITIALIZE_IMMEDIATE(/mob/dead) var/turf/new_turf = get_turf(destination) if (old_turf?.z != new_turf?.z) onTransitZ(old_turf?.z, new_turf?.z) + var/oldloc = loc loc = destination + Moved(oldloc, NONE, TRUE) /mob/dead/Stat() ..() diff --git a/code/modules/mob/dead/new_player/sprite_accessories/socks.dm b/code/modules/mob/dead/new_player/sprite_accessories/socks.dm index 5a5d37d4e7..01a83dcc9f 100644 --- a/code/modules/mob/dead/new_player/sprite_accessories/socks.dm +++ b/code/modules/mob/dead/new_player/sprite_accessories/socks.dm @@ -11,6 +11,10 @@ // please make sure they're sorted alphabetically and categorized +/datum/sprite_accessory/socks/bee_knee + name = "Knee-high (Bee)" + icon_state = "bee_knee" + /datum/sprite_accessory/socks/black_knee name = "Knee-high (Black)" icon_state = "black_knee" @@ -63,6 +67,10 @@ name = "Short (White)" icon_state = "white_short" +/datum/sprite_accessory/socks/bee_thigh + name = "Thigh-high (Bee)" + icon_state = "bee_thigh" + /datum/sprite_accessory/socks/black_thigh name = "Thigh-high (Black)" icon_state = "black_thigh" @@ -93,4 +101,4 @@ /datum/sprite_accessory/socks/white_thigh name = "Thigh-high (White)" - icon_state = "white_thigh" \ No newline at end of file + icon_state = "white_thigh" diff --git a/code/modules/mob/dead/new_player/sprite_accessories/undershirt.dm b/code/modules/mob/dead/new_player/sprite_accessories/undershirt.dm index 7c66ef51e3..f5af9a3849 100644 --- a/code/modules/mob/dead/new_player/sprite_accessories/undershirt.dm +++ b/code/modules/mob/dead/new_player/sprite_accessories/undershirt.dm @@ -248,9 +248,13 @@ icon_state = "bra_commie" /datum/sprite_accessory/undershirt/female_babyblue - name = "Bra, Baby Blue" + name = "Bra - Baby Blue" icon_state = "bra_babyblue" +/datum/sprite_accessory/undershirt/female_beekini + name = "Bra - Bee-kini" + icon_state = "bra_bee-kini" + /datum/sprite_accessory/undershirt/female_black name = "Bra - Black" icon_state = "bra_black" diff --git a/code/modules/mob/dead/new_player/sprite_accessories/underwear.dm b/code/modules/mob/dead/new_player/sprite_accessories/underwear.dm index 6beed231aa..e7179eeb87 100644 --- a/code/modules/mob/dead/new_player/sprite_accessories/underwear.dm +++ b/code/modules/mob/dead/new_player/sprite_accessories/underwear.dm @@ -90,6 +90,9 @@ name = "Boxer Briefs - Yellow" icon_state = "boxer_briefs_yellow" +/datum/sprite_accessory/underwear/female_beekini + name = "Panties - Bee-kini" + icon_state = "panties_bee-kini" /datum/sprite_accessory/underwear/female_black name = "Panties - Black" diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index 55b8891534..fefa032e4f 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -429,9 +429,6 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp var/orbitsize = (I.Width()+I.Height())*0.5 orbitsize -= (orbitsize/world.icon_size)*(world.icon_size*0.25) - if(orbiting && orbiting.orbiting != target) - to_chat(src, "Now orbiting [target].") - var/rot_seg switch(ghost_orbit) @@ -450,10 +447,10 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp /mob/dead/observer/orbit() setDir(2)//reset dir so the right directional sprites show up - ..() + return ..() -/mob/dead/observer/stop_orbit() - ..() +/mob/dead/observer/stop_orbit(datum/component/orbiter/orbits) + . = ..() //restart our floating animation after orbit is done. pixel_y = 0 animate(src, pixel_y = 2, time = 10, loop = -1) @@ -753,7 +750,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp update_icon() -/mob/dead/observer/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE) +/mob/dead/observer/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE, no_tk=FALSE) return IsAdminGhost(usr) /mob/dead/observer/is_literate() diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index fb09de7ec2..51ee5b372b 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -895,6 +895,11 @@ var/obj/item/organ/I = X I.Insert(src) +/mob/living/carbon/proc/update_disabled_bodyparts() + for(var/B in bodyparts) + var/obj/item/bodypart/BP = B + BP.update_disabled() + /mob/living/carbon/vv_get_dropdown() . = ..() . += "---" diff --git a/code/modules/mob/living/carbon/carbon_defense.dm b/code/modules/mob/living/carbon/carbon_defense.dm index e96bb7f121..57483f64e7 100644 --- a/code/modules/mob/living/carbon/carbon_defense.dm +++ b/code/modules/mob/living/carbon/carbon_defense.dm @@ -48,18 +48,27 @@ if(affecting && affecting.dismemberable && affecting.get_damage() >= (affecting.max_damage - P.dismemberment)) affecting.dismember(P.damtype) +/mob/living/carbon/proc/can_catch_item(skip_throw_mode_check) + . = FALSE + if(!skip_throw_mode_check && !in_throw_mode) + return + if(get_active_held_item()) + return + if(restrained()) + return + return TRUE + /mob/living/carbon/hitby(atom/movable/AM, skipcatch, hitpush = TRUE, blocked = FALSE) if(!skipcatch) //ugly, but easy - if(in_throw_mode && !get_active_held_item()) //empty active hand and we're in throw mode - if(canmove && !restrained()) - if(istype(AM, /obj/item)) - var/obj/item/I = AM - if(isturf(I.loc)) - I.attack_hand(src) - if(get_active_held_item() == I) //if our attack_hand() picks up the item... - visible_message("[src] catches [I]!") //catch that sucker! - throw_mode_off() - return 1 + if(can_catch_item()) + if(istype(AM, /obj/item)) + var/obj/item/I = AM + if(isturf(I.loc)) + I.attack_hand(src) + if(get_active_held_item() == I) //if our attack_hand() picks up the item... + visible_message("[src] catches [I]!") //catch that sucker! + throw_mode_off() + return 1 ..() diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm index d814893053..8550a0887f 100644 --- a/code/modules/mob/living/carbon/human/examine.dm +++ b/code/modules/mob/living/carbon/human/examine.dm @@ -294,7 +294,7 @@ if(mood.sanity <= SANITY_DISTURBED) msg += "[t_He] seem[p_s()] distressed.\n" SEND_SIGNAL(user, COMSIG_ADD_MOOD_EVENT, "empath", /datum/mood_event/sad_empath, src) - if(mood.mood >= 5) //So roundstart people aren't all "happy" + if(mood.shown_mood >= 6) //So roundstart people aren't all "happy" and that antags don't show their true happiness. msg += "[t_He] seem[p_s()] to have had something nice happen to them recently.\n" SEND_SIGNAL(user, COMSIG_ADD_MOOD_EVENT, "empathH", /datum/mood_event/happy_empath, src) if (HAS_TRAIT(src, TRAIT_BLIND)) diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 0f962d7b0f..a4fca9dd78 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -8,6 +8,7 @@ /mob/living/carbon/human/Initialize() verbs += /mob/living/proc/mob_sleep verbs += /mob/living/proc/lay_down + verbs += /mob/living/carbon/human/proc/underwear_toggle //fwee //initialize limbs first create_bodyparts() @@ -724,12 +725,12 @@ remove_atom_colour(TEMPORARY_COLOUR_PRIORITY, "#000000") cut_overlay(MA) -/mob/living/carbon/human/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE) +/mob/living/carbon/human/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE, no_tk=FALSE) if(incapacitated() || lying ) to_chat(src, "You can't do that right now!") return FALSE if(!Adjacent(M) && (M.loc != src)) - if((be_close == 0) || (dna.check_mutation(TK) && tkMaxRangeCheck(src, M))) + if((be_close == 0) || (!no_tk && (dna.check_mutation(TK) && tkMaxRangeCheck(src, M)))) return TRUE to_chat(src, "You are too far away!") return FALSE @@ -851,19 +852,24 @@ /mob/living/carbon/human/MouseDrop_T(mob/living/target, mob/living/user) //If they dragged themselves and we're currently aggressively grabbing them try to piggyback - if(user == target && can_piggyback(target) && pulling == target && grab_state >= GRAB_AGGRESSIVE && stat == CONSCIOUS) + if(user == target && can_piggyback(target) && pulling == target && (HAS_TRAIT(src, TRAIT_PACIFISM) || grab_state >= GRAB_AGGRESSIVE) && stat == CONSCIOUS) buckle_mob(target,TRUE,TRUE) . = ..() +/mob/living/carbon/human/proc/piggyback_instant(mob/living/M) + return buckle_mob(M, TRUE, TRUE, FALSE, TRUE) + //Can C try to piggyback at all. /mob/living/carbon/human/proc/can_piggyback(mob/living/carbon/C) if(istype(C) && C.stat == CONSCIOUS) return TRUE return FALSE -/mob/living/carbon/human/buckle_mob(mob/living/M, force = FALSE, check_loc = TRUE) +/mob/living/carbon/human/buckle_mob(mob/living/M, force = FALSE, check_loc = TRUE, bypass_piggybacking = FALSE, no_delay = FALSE) if(!force)//humans are only meant to be ridden through piggybacking and special cases return + if(bypass_piggybacking) + return ..() if(!is_type_in_typecache(M, can_ride_typecache)) M.visible_message("[M] really can't seem to mount [src]...") return @@ -876,7 +882,7 @@ if(can_piggyback(M)) riding_datum.ride_check_ridden_incapacitated = TRUE visible_message("[M] starts to climb onto [src]...") - if(do_after(M, 15, target = src)) + if(no_delay || do_after(M, 15, target = src)) if(can_piggyback(M)) if(M.incapacitated(FALSE, TRUE) || incapacitated(FALSE, TRUE)) M.visible_message("[M] can't hang onto [src]!") diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm index 62a4d42672..4fb3fb0243 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -490,11 +490,19 @@ GLOBAL_LIST_EMPTY(roundstart_races) //Underwear, Undershirts & Socks if(!(NO_UNDERWEAR in species_traits)) if(H.underwear) + if(H.hidden_underwear) + H.underwear = "Nude" + else + H.underwear = H.saved_underwear var/datum/sprite_accessory/underwear/underwear = GLOB.underwear_list[H.underwear] if(underwear) standing += mutable_appearance(underwear.icon, underwear.icon_state, -BODY_LAYER) if(H.undershirt) + if(H.hidden_undershirt) + H.undershirt = "Nude" + else + H.undershirt = H.saved_undershirt var/datum/sprite_accessory/undershirt/undershirt = GLOB.undershirt_list[H.undershirt] if(undershirt) if(H.dna.species.sexes && H.gender == FEMALE) @@ -503,6 +511,10 @@ GLOBAL_LIST_EMPTY(roundstart_races) standing += mutable_appearance(undershirt.icon, undershirt.icon_state, -BODY_LAYER) if(H.socks && H.get_num_legs(FALSE) >= 2) + if(H.hidden_socks) + H.socks = "Nude" + else + H.socks = H.saved_socks var/datum/sprite_accessory/socks/socks = GLOB.socks_list[H.socks] if(socks) if(DIGITIGRADE in species_traits) @@ -1288,7 +1300,7 @@ GLOBAL_LIST_EMPTY(roundstart_races) . += H.physiology.speed_mod if (H.m_intent == MOVE_INTENT_WALK && HAS_TRAIT(H, TRAIT_SPEEDY_STEP)) - . -= 1 + . -= 1.5 if(HAS_TRAIT(H, TRAIT_IGNORESLOWDOWN)) ignoreslow = 1 diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm index 571775d541..b2eb83d668 100644 --- a/code/modules/mob/living/carbon/life.dm +++ b/code/modules/mob/living/carbon/life.dm @@ -654,6 +654,7 @@ GLOBAL_LIST_INIT(ballmer_windows_me_msg, list("Yo man, what if, we like, uh, put L.damage += d /mob/living/carbon/proc/liver_failure() + reagents.end_metabolization(src, keep_liverless = TRUE) //Stops trait-based effects on reagents, to prevent permanent buffs reagents.metabolize(src, can_overdose=FALSE, liverless = TRUE) if(HAS_TRAIT(src, TRAIT_STABLEHEART)) return diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 65ed57a6f1..b253e27e8d 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -814,7 +814,7 @@ /mob/living/proc/harvest(mob/living/user) //used for extra objects etc. in butchering return -/mob/living/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE) +/mob/living/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE, no_tk=FALSE) if(incapacitated()) to_chat(src, "You can't do that right now!") return FALSE @@ -1189,9 +1189,13 @@ clamp_unconscious_to = 0, clamp_immobility_to = 0, reset_misc = TRUE, - healing_chems = list("inaprovaline" = 3, "synaptizine" = 10, "omnizine" = 10, "stimulants" = 10), - message = "You feel a surge of energy!" + healing_chems = list("inaprovaline" = 3, "synaptizine" = 10, "regen_jelly" = 10, "stimulants" = 10), + message = "You feel a surge of energy!", + stamina_buffer_boost = 0, //restores stamina buffer rather than just health + scale_stamina_loss_recovery, //defaults to null. if this is set, restores loss * this stamina. make sure it's a fraction. + stamina_loss_recovery_bypass = 0 //amount of stamina loss to ignore during calculation ) + to_chat(src, message) if(AmountSleeping() > clamp_unconscious_to) SetSleeping(clamp_unconscious_to) if(AmountUnconscious() > clamp_unconscious_to) @@ -1200,7 +1204,10 @@ SetStun(clamp_immobility_to) if(AmountKnockdown() > clamp_immobility_to) SetKnockdown(clamp_immobility_to) - adjustStaminaLoss(max(0, -stamina_boost)) + adjustStaminaLoss(min(0, -stamina_boost)) + adjustStaminaLossBuffered(min(0, -stamina_buffer_boost)) + if(scale_stamina_loss_recovery) + adjustStaminaLoss(min(-((getStaminaLoss() - stamina_loss_recovery_bypass) * scale_stamina_loss_recovery), 0)) if(put_on_feet) resting = FALSE lying = FALSE diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index 46576a357f..6d225d3913 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -779,7 +779,7 @@ return TRUE return ..() -/mob/living/silicon/ai/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE) +/mob/living/silicon/ai/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE, no_tk=FALSE) if(control_disabled || incapacitated()) to_chat(src, "You can't do that right now!") return FALSE diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm index 896d8674be..7fd861bfeb 100644 --- a/code/modules/mob/living/silicon/pai/pai.dm +++ b/code/modules/mob/living/silicon/pai/pai.dm @@ -183,7 +183,7 @@ // See software.dm for Topic() -/mob/living/silicon/pai/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE) +/mob/living/silicon/pai/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE, no_tk=FALSE) if(be_close && !in_range(M, src)) to_chat(src, "You are too far away!") return FALSE diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 335645b17e..e71e269222 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -910,7 +910,7 @@ if(DISCONNECT) //Tampering with the wires to_chat(connected_ai, "

NOTICE - Remote telemetry lost with [name].
") -/mob/living/silicon/robot/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE) +/mob/living/silicon/robot/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE, no_tk=FALSE) if(stat || lockcharge || low_power_mode) to_chat(src, "You can't do that right now!") return FALSE diff --git a/code/modules/mob/living/simple_animal/friendly/panda.dm b/code/modules/mob/living/simple_animal/friendly/panda.dm new file mode 100644 index 0000000000..a7b6143ef5 --- /dev/null +++ b/code/modules/mob/living/simple_animal/friendly/panda.dm @@ -0,0 +1,20 @@ +/mob/living/simple_animal/pet/redpanda + name = "Red panda" + desc = "Wah't a dork." + icon = 'icons/mob/pets.dmi' + icon_state = "red_panda" + icon_living = "red_panda" + icon_dead = "dead_panda" + speak = list("Churip","Chuuriip","Cheep-cheep","Chiteurp","squueeaacipt") + speak_emote = list("chirps", "huff-quacks") + emote_hear = list("squeak-chrips.", "huff-squacks.") + emote_see = list("shakes its head.", "rolls about.") + speak_chance = 1 + turns_per_move = 5 + see_in_dark = 6 + butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab = 3) + response_help = "pets" + response_disarm = "gently pushes aside" + response_harm = "kicks" + gold_core_spawnable = FRIENDLY_SPAWN + do_footstep = TRUE diff --git a/code/modules/mob/living/simple_animal/guardian/guardian.dm b/code/modules/mob/living/simple_animal/guardian/guardian.dm index 701e244f89..1a918766b6 100644 --- a/code/modules/mob/living/simple_animal/guardian/guardian.dm +++ b/code/modules/mob/living/simple_animal/guardian/guardian.dm @@ -596,6 +596,9 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians /obj/item/guardiancreator/tech/choose/traitor possible_guardians = list("Assassin", "Chaos", "Charger", "Explosive", "Lightning", "Protector", "Ranged", "Standard", "Support") +/obj/item/guardiancreator/tech/choose/traitor/check_uplink_validity() + return !used + /obj/item/guardiancreator/tech/choose random = FALSE diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index 2517d2438d..1f81899d8a 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -392,7 +392,7 @@ if(target) return new childspawn(target) -/mob/living/simple_animal/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE) +/mob/living/simple_animal/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE, no_tk=FALSE) if(incapacitated()) to_chat(src, "You can't do that right now!") return FALSE diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 7ff8fbc0b1..b098801da8 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -784,7 +784,7 @@ return 0 //Can the mob use Topic to interact with machines -/mob/proc/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE) +/mob/proc/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE, no_tk=FALSE) return /mob/proc/faction_check_mob(mob/target, exact_match) @@ -871,13 +871,7 @@ return /mob/proc/update_sight() - for(var/O in orbiters) - var/datum/orbit/orbit = O - var/obj/effect/wisp/wisp = orbit.orbiter - if (istype(wisp)) - sight |= wisp.sight_flags - if(!isnull(wisp.lighting_alpha)) - lighting_alpha = min(lighting_alpha, wisp.lighting_alpha) + SEND_SIGNAL(src, COMSIG_MOB_UPDATE_SIGHT) sync_lighting_plane_alpha() diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm index 33f1ec81c1..82e2b11f8e 100644 --- a/code/modules/mob/mob_movement.dm +++ b/code/modules/mob/mob_movement.dm @@ -148,7 +148,7 @@ if(INCORPOREAL_MOVE_BASIC) var/T = get_step(L,direct) if(T) - L.loc = T + L.forceMove(T) L.setDir(direct) if(INCORPOREAL_MOVE_SHADOW) if(prob(50)) @@ -190,7 +190,7 @@ new /obj/effect/temp_visual/dir_setting/ninja/shadow(mobloc, L.dir) var/T = get_step(L,direct) if(T) - L.loc = T + L.forceMove(T) L.setDir(direct) if(INCORPOREAL_MOVE_JAUNT) //Incorporeal move, but blocked by holy-watered tiles and salt piles. var/turf/open/floor/stepTurf = get_step(L, direct) @@ -209,7 +209,7 @@ to_chat(L, "Holy energies block your path!") return - L.loc = get_step(L, direct) + L.forceMove(stepTurf) L.setDir(direct) return TRUE diff --git a/code/modules/modular_computers/computers/item/processor.dm b/code/modules/modular_computers/computers/item/processor.dm index 20ad2214cf..99d648d02b 100644 --- a/code/modules/modular_computers/computers/item/processor.dm +++ b/code/modules/modular_computers/computers/item/processor.dm @@ -44,7 +44,7 @@ return machinery_computer.update_icon() // This thing is not meant to be used on it's own, get topic data from our machinery owner. -//obj/item/modular_computer/processor/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE) +//obj/item/modular_computer/processor/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE, no_tk=FALSE) // if(!machinery_computer) // return 0 diff --git a/code/modules/orbit/orbit.dm b/code/modules/orbit/orbit.dm deleted file mode 100644 index 79685b9104..0000000000 --- a/code/modules/orbit/orbit.dm +++ /dev/null @@ -1,135 +0,0 @@ -/datum/orbit - var/atom/movable/orbiter - var/atom/orbiting - var/lock = TRUE - var/turf/lastloc - var/lastprocess - -/datum/orbit/New(_orbiter, _orbiting, _lock) - orbiter = _orbiter - orbiting = _orbiting - SSorbit.processing += src - if (!orbiting.orbiters) - orbiting.orbiters = list() - orbiting.orbiters += src - - if (orbiter.orbiting) - orbiter.stop_orbit() - orbiter.orbiting = src - Check() - lock = _lock - -//do not qdel directly, use stop_orbit on the orbiter. (This way the orbiter can bind to the orbit stopping) -/datum/orbit/Destroy(force = FALSE) - SSorbit.processing -= src - if (orbiter) - orbiter.orbiting = null - orbiter = null - if (orbiting) - if (orbiting.orbiters) - orbiting.orbiters -= src - if (!orbiting.orbiters.len)//we are the last orbit, delete the list - orbiting.orbiters = null - orbiting = null - return ..() - -/datum/orbit/proc/Check(turf/targetloc, list/checked_already = list()) - //Avoid infinite loops for people who end up orbiting themself through another orbiter - checked_already[src] = TRUE - if (!orbiter) - qdel(src) - return - if (!orbiting) - orbiter.stop_orbit() - return - if (!orbiter.orbiting) //admin wants to stop the orbit. - orbiter.orbiting = src //set it back to us first - orbiter.stop_orbit() - var/atom/movable/AM = orbiting - if(istype(AM) && AM.orbiting && AM.orbiting.orbiting == orbiter) - orbiter.stop_orbit() - return - lastprocess = world.time - if (!targetloc) - targetloc = get_turf(orbiting) - if (!targetloc || (!lock && orbiter.loc != lastloc && orbiter.loc != targetloc)) - orbiter.stop_orbit() - return - var/turf/old_turf = get_turf(orbiter) - var/turf/new_turf = get_turf(targetloc) - if (old_turf?.z != new_turf?.z) - orbiter.onTransitZ(old_turf?.z, new_turf?.z) - // DO NOT PORT TO FORCEMOVE - MEMECODE WILL KILL MC - orbiter.loc = targetloc - orbiter.update_parallax_contents() - orbiter.update_light() - lastloc = orbiter.loc - for(var/other_orbit in orbiter.orbiters) - var/datum/orbit/OO = other_orbit - //Skip if checked already - if(checked_already[OO]) - continue - OO.Check(targetloc, checked_already) - -/atom/movable/var/datum/orbit/orbiting = null -/atom/var/list/orbiters = null - -//A: atom to orbit -//radius: range to orbit at, radius of the circle formed by orbiting (in pixels) -//clockwise: whether you orbit clockwise or anti clockwise -//rotation_speed: how fast to rotate (how many ds should it take for a rotation to complete) -//rotation_segments: the resolution of the orbit circle, less = a more block circle, this can be used to produce hexagons (6 segments) triangles (3 segments), and so on, 36 is the best default. -//pre_rotation: Chooses to rotate src 90 degress towards the orbit dir (clockwise/anticlockwise), useful for things to go "head first" like ghosts -//lockinorbit: Forces src to always be on A's turf, otherwise the orbit cancels when src gets too far away (eg: ghosts) - -/atom/movable/proc/orbit(atom/A, radius = 10, clockwise = FALSE, rotation_speed = 20, rotation_segments = 36, pre_rotation = TRUE, lockinorbit = FALSE) - if (!istype(A)) - return - - new/datum/orbit(src, A, lockinorbit) - if (!orbiting) //something failed, and our orbit datum deleted itself - return - var/matrix/initial_transform = matrix(transform) - - //Head first! - if (pre_rotation) - var/matrix/M = matrix(transform) - var/pre_rot = 90 - if(!clockwise) - pre_rot = -90 - M.Turn(pre_rot) - transform = M - - var/matrix/shift = matrix(transform) - shift.Translate(0,radius) - transform = shift - - SpinAnimation(rotation_speed, -1, clockwise, rotation_segments) - - //we stack the orbits up client side, so we can assign this back to normal server side without it breaking the orbit - transform = initial_transform - -/atom/movable/proc/stop_orbit() - SpinAnimation(0,0) - qdel(orbiting) - -/atom/Destroy(force = FALSE) - . = ..() - if (orbiters) - for (var/thing in orbiters) - var/datum/orbit/O = thing - if (O.orbiter) - O.orbiter.stop_orbit() - -/atom/movable/Destroy(force = FALSE) - . = ..() - if (orbiting) - stop_orbit() - -/atom/movable/proc/transfer_observers_to(atom/movable/target) - if(orbiters) - for(var/thing in orbiters) - var/datum/orbit/O = thing - if(O.orbiter && isobserver(O.orbiter)) - var/mob/dead/observer/D = O.orbiter - D.ManualFollow(target) diff --git a/code/modules/paperwork/paperplane.dm b/code/modules/paperwork/paperplane.dm index e3ce30066a..2a298d39b1 100644 --- a/code/modules/paperwork/paperplane.dm +++ b/code/modules/paperwork/paperplane.dm @@ -1,3 +1,4 @@ + /obj/item/paperplane name = "paper plane" desc = "Paper, folded in the shape of a plane." @@ -10,8 +11,14 @@ resistance_flags = FLAMMABLE max_integrity = 50 + var/hit_probability = 2//% var/obj/item/paper/internalPaper +/obj/item/paperplane/origami + desc = "Paper, masterfully folded in the shape of a plane." + throwforce = 20 //same as throwing stars, but no chance of embedding. + hit_probability = 100 //guaranteed to cause eye damage when it hits a mob. + /obj/item/paperplane/Initialize(mapload, obj/item/paper/newPaper) . = ..() pixel_y = rand(-8, 8) @@ -22,13 +29,18 @@ color = newPaper.color newPaper.forceMove(src) else - internalPaper = new /obj/item/paper(src) + internalPaper = new(src) update_icon() -/obj/item/paperplane/Destroy() - if(internalPaper) - qdel(internalPaper) +/obj/item/paperplane/handle_atom_del(atom/A) + if(A == internalPaper) internalPaper = null + if(!QDELETED(src)) + qdel(src) + return ..() + +/obj/item/paperplane/Destroy() + QDEL_NULL(internalPaper) return ..() /obj/item/paperplane/suicide_act(mob/living/user) @@ -48,7 +60,7 @@ /obj/item/paperplane/attack_self(mob/user) to_chat(user, "You unfold [src].") - var/atom/movable/internal_paper_tmp = internalPaper + var/obj/item/paper/internal_paper_tmp = internalPaper internal_paper_tmp.forceMove(loc) internalPaper = null qdel(src) @@ -86,11 +98,18 @@ . = ..(target, range, speed, thrower, FALSE, diagonals_first, callback) /obj/item/paperplane/throw_impact(atom/hit_atom) + if(iscarbon(hit_atom)) + var/mob/living/carbon/C = hit_atom + if(C.can_catch_item(TRUE)) + var/datum/action/innate/origami/origami_action = locate() in C.actions + if(origami_action?.active) //if they're a master of origami and have the ability turned on, force throwmode on so they'll automatically catch the plane. + C.throw_mode_on() + 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(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)) + if(prob(hit_probability)) + if(H.is_eyes_covered()) return visible_message("\The [src] hits [H] in the eye!") H.adjust_blurriness(6) @@ -107,5 +126,11 @@ return to_chat(user, "You fold [src] into the shape of a plane!") user.temporarilyRemoveItemFromInventory(src) - I = new /obj/item/paperplane(user, src) + var/obj/item/paperplane/plane_type = /obj/item/paperplane + //Origami Master + var/datum/action/innate/origami/origami_action = locate() in user.actions + if(origami_action?.active) + plane_type = /obj/item/paperplane/origami + + I = new plane_type(user, src) user.put_in_hands(I) diff --git a/code/modules/power/tesla/energy_ball.dm b/code/modules/power/tesla/energy_ball.dm index 0a54bcab33..bbad3e08b0 100644 --- a/code/modules/power/tesla/energy_ball.dm +++ b/code/modules/power/tesla/energy_ball.dm @@ -33,8 +33,8 @@ return /obj/singularity/energy_ball/Destroy() - if(orbiting && istype(orbiting.orbiting, /obj/singularity/energy_ball)) - var/obj/singularity/energy_ball/EB = orbiting.orbiting + if(orbiting && istype(orbiting.parent, /obj/singularity/energy_ball)) + var/obj/singularity/energy_ball/EB = orbiting.parent EB.orbiting_balls -= src for(var/ball in orbiting_balls) @@ -146,12 +146,12 @@ . = ..() /obj/singularity/energy_ball/stop_orbit() - if (orbiting && istype(orbiting.orbiting, /obj/singularity/energy_ball)) - var/obj/singularity/energy_ball/orbitingball = orbiting.orbiting + if (orbiting && istype(orbiting.parent, /obj/singularity/energy_ball)) + var/obj/singularity/energy_ball/orbitingball = orbiting.parent orbitingball.orbiting_balls -= src orbitingball.dissipate_strength = orbitingball.orbiting_balls.len - ..() - if (!loc && !QDELETED(src)) + . = ..() + if (!QDELETED(src)) qdel(src) diff --git a/code/modules/projectiles/ammunition/energy/stun.dm b/code/modules/projectiles/ammunition/energy/stun.dm index 3f033ac904..c9e60ddc1d 100644 --- a/code/modules/projectiles/ammunition/energy/stun.dm +++ b/code/modules/projectiles/ammunition/energy/stun.dm @@ -24,4 +24,4 @@ e_cost = 40 fire_sound = 'sound/weapons/taser2.ogg' harmful = FALSE - click_cooldown_override = 3 + click_cooldown_override = 3.5 diff --git a/code/modules/projectiles/ammunition/special/syringe.dm b/code/modules/projectiles/ammunition/special/syringe.dm index 4a2a354ca6..d5cba6936f 100644 --- a/code/modules/projectiles/ammunition/special/syringe.dm +++ b/code/modules/projectiles/ammunition/special/syringe.dm @@ -59,3 +59,20 @@ S.forceMove(D) D.injector = S ..() + +/obj/item/ammo_casing/syringegun/dart + name = "used air canister" + desc = "A small canister of compressed gas." + projectile_type = /obj/item/projectile/bullet/dart/syringe/dart + firing_effect_type = null + harmful = FALSE + +/obj/item/ammo_casing/syringegun/dart/ready_proj(atom/target, mob/living/user, quiet, zone_override = "") + ..() + var/obj/item/gun/syringe/SG = loc + if(!SG.syringes.len) + return + var/obj/item/reagent_containers/syringe/dart/S = SG.syringes[1] + if(S.emptrig == TRUE) + var/obj/item/projectile/bullet/dart/syringe/dart/D = BB + D.emptrig = TRUE diff --git a/code/modules/projectiles/guns/misc/medbeam.dm b/code/modules/projectiles/guns/misc/medbeam.dm index 17c0f63955..7bdefe5e91 100644 --- a/code/modules/projectiles/guns/misc/medbeam.dm +++ b/code/modules/projectiles/guns/misc/medbeam.dm @@ -116,7 +116,7 @@ new /obj/effect/temp_visual/heal(get_turf(target), "#80F5FF") target.adjustBruteLoss(-4) target.adjustFireLoss(-4) - target.adjustToxLoss(-1) + target.adjustToxLoss(-1, forced = TRUE) target.adjustOxyLoss(-1) return diff --git a/code/modules/projectiles/guns/misc/syringe_gun.dm b/code/modules/projectiles/guns/misc/syringe_gun.dm index cc1b321e3a..26e66b1987 100644 --- a/code/modules/projectiles/guns/misc/syringe_gun.dm +++ b/code/modules/projectiles/guns/misc/syringe_gun.dm @@ -102,3 +102,23 @@ else to_chat(user, "[src] cannot hold more syringes!") return FALSE + +/obj/item/gun/syringe/dart + name = "dart gun" + desc = "A compressed air gun, designed to fit medicinal darts for application of medicine for those patients just out of reach." + icon_state = "dartgun" + item_state = "dartgun" + materials = list(MAT_METAL=2000, MAT_GLASS=500) + suppressed = TRUE //Softer fire sound + can_unsuppress = FALSE + +/obj/item/gun/syringe/dart/Initialize() + ..() + chambered = new /obj/item/ammo_casing/syringegun/dart(src) + +/obj/item/gun/syringe/dart/attackby(obj/item/A, mob/user, params, show_msg = TRUE) + if(istype(A, /obj/item/reagent_containers/syringe/dart)) + ..() + else + to_chat(user, "You can't put the [A] into \the [src]!") + return FALSE diff --git a/code/modules/projectiles/projectile/bullets/dart_syringe.dm b/code/modules/projectiles/projectile/bullets/dart_syringe.dm index 94d075c789..bdbf706448 100644 --- a/code/modules/projectiles/projectile/bullets/dart_syringe.dm +++ b/code/modules/projectiles/projectile/bullets/dart_syringe.dm @@ -8,12 +8,14 @@ . = ..() create_reagents(50, NO_REACT) -/obj/item/projectile/bullet/dart/on_hit(atom/target, blocked = FALSE) +/obj/item/projectile/bullet/dart/on_hit(atom/target, blocked = FALSE, skip = FALSE) if(iscarbon(target)) var/mob/living/carbon/M = target if(blocked != 100) // not completely blocked if(M.can_inject(null, FALSE, def_zone, piercing)) // Pass the hit zone to see if it can inject by whether it hit the head or the body. ..() + if(skip == TRUE) + return reagents.reaction(M, INJECT) reagents.trans_to(M, reagents.total_volume) return TRUE @@ -36,3 +38,44 @@ /obj/item/projectile/bullet/dart/syringe name = "syringe" icon_state = "syringeproj" + +//I am in a mess of my own making +/obj/item/projectile/bullet/dart/syringe/dart + name = "Smartdart" + icon_state = "dartproj" + damage = 0 + var/emptrig = FALSE + +/obj/item/projectile/bullet/dart/syringe/dart/on_hit(atom/target, blocked = FALSE) + if(iscarbon(target)) + var/mob/living/carbon/M = target + if(blocked != 100) + if(M.can_inject(null, FALSE, def_zone, piercing)) // Pass the hit zone to see if it can inject by whether it hit the head or the body. + ..(target, blocked, TRUE) + for(var/datum/reagent/R in reagents.reagent_list) //OD prevention time! + if(istype(R, /datum/reagent/medicine)) //Is this a medicine? + if(M.reagents.has_reagent(R.id)) + if(R.overdose_threshold == 0 || emptrig == TRUE) //Is there a possible OD? + M.reagents.add_reagent(R.id, R.volume) + else + var/transVol = CLAMP(R.volume, 0, (R.overdose_threshold - M.reagents.get_reagent_amount(R.id)) -1) + M.reagents.add_reagent(R.id, transVol) + else + if(!R.overdose_threshold == 0) + var/transVol = CLAMP(R.volume, 0, R.overdose_threshold-1) + M.reagents.add_reagent(R.id, transVol) + else + M.reagents.add_reagent(R.id, R.volume) + + + + target.visible_message("\The [src] beeps!") + to_chat("You feel a tiny prick as a smartdart embeds itself in you with a beep.") + return TRUE + else + blocked = 100 + target.visible_message("\The [src] was deflected!", \ + "You see a [src] bounce off you, booping sadly!") + + target.visible_message("\The [src] fails to land on target!") + return TRUE diff --git a/code/modules/reagents/chemistry/holder.dm b/code/modules/reagents/chemistry/holder.dm index 58c29f351b..dc86ab4e6c 100644 --- a/code/modules/reagents/chemistry/holder.dm +++ b/code/modules/reagents/chemistry/holder.dm @@ -21,7 +21,9 @@ if(GLOB.chemical_reactions_list) return - var/paths = subtypesof(/datum/chemical_reaction) + + //Randomized need to go last since they need to check against conflicts with normal recipes + var/paths = subtypesof(/datum/chemical_reaction) - typesof(/datum/chemical_reaction/randomized) + subtypesof(/datum/chemical_reaction/randomized) GLOB.chemical_reactions_list = list() for(var/path in paths) @@ -29,6 +31,9 @@ var/datum/chemical_reaction/D = new path() var/list/reaction_ids = list() + if(!D.id) + continue + if(D.required_reagents && D.required_reagents.len) for(var/reaction in D.required_reagents) reaction_ids += reaction @@ -267,6 +272,9 @@ continue if(!C) C = R.holder.my_atom + if(!R.metabolizing) + R.metabolizing = TRUE + R.on_mob_metabolize(C) if(C && R) if(C.reagent_check(R) != 1) if(can_overdose) @@ -313,6 +321,21 @@ C.update_stamina() update_total() +//Signals that metabolization has stopped, triggering the end of trait-based effects +/datum/reagents/proc/end_metabolization(mob/living/carbon/C, keep_liverless = TRUE) + var/list/cached_reagents = reagent_list + for(var/reagent in cached_reagents) + var/datum/reagent/R = reagent + if(QDELETED(R.holder)) + continue + if(keep_liverless && R.self_consuming) //Will keep working without a liver + continue + if(!C) + C = R.holder.my_atom + if(R.metabolizing) + R.metabolizing = FALSE + R.on_mob_end_metabolize(C) + /datum/reagents/proc/conditional_update_move(atom/A, Running = 0) var/list/cached_reagents = reagent_list for(var/reagent in cached_reagents) @@ -466,6 +489,9 @@ if(R.id == reagent) if(my_atom && isliving(my_atom)) var/mob/living/M = my_atom + if(R.metabolizing) + R.metabolizing = FALSE + R.on_mob_end_metabolize(M) R.on_mob_delete(M) qdel(R) reagent_list -= R diff --git a/code/modules/reagents/chemistry/machinery/chem_dispenser.dm b/code/modules/reagents/chemistry/machinery/chem_dispenser.dm index 10282e5e0a..d10e57783d 100644 --- a/code/modules/reagents/chemistry/machinery/chem_dispenser.dm +++ b/code/modules/reagents/chemistry/machinery/chem_dispenser.dm @@ -9,7 +9,6 @@ interaction_flags_machine = INTERACT_MACHINE_OPEN | INTERACT_MACHINE_ALLOW_SILICON | INTERACT_MACHINE_OFFLINE resistance_flags = FIRE_PROOF | ACID_PROOF circuit = /obj/item/circuitboard/machine/chem_dispenser - var/cell_type = /obj/item/stock_parts/cell/high var/obj/item/stock_parts/cell/cell var/powerefficiency = 0.1 var/amount = 30 @@ -79,7 +78,6 @@ /obj/machinery/chem_dispenser/Initialize() . = ..() - cell = new cell_type dispensable_reagents = sortList(dispensable_reagents) update_icon() diff --git a/code/modules/reagents/chemistry/reagents.dm b/code/modules/reagents/chemistry/reagents.dm index a52bb1ecfe..9bfbffd330 100644 --- a/code/modules/reagents/chemistry/reagents.dm +++ b/code/modules/reagents/chemistry/reagents.dm @@ -33,6 +33,10 @@ var/addiction_stage4_end = 40 var/overdosed = 0 // You fucked up and this is now triggering its overdose effects, purge that shit quick. var/self_consuming = FALSE + var/metabolizing = FALSE + + + /datum/reagent/Destroy() // This should only be called by the holder, so it's already handled clearing its references . = ..() @@ -68,6 +72,14 @@ /datum/reagent/proc/on_mob_delete(mob/living/L) return +// Called when this reagent first starts being metabolized by a liver +/datum/reagent/proc/on_mob_metabolize(mob/living/L) + return + +// Called when this reagent stops being metabolized by a liver +/datum/reagent/proc/on_mob_end_metabolize(mob/living/L) + return + /datum/reagent/proc/on_move(mob/M) return diff --git a/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm b/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm index 14963a6689..80e195d5ac 100644 --- a/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm @@ -111,7 +111,7 @@ All effects don't start immediately, but rather get worse over time; the rate is M.add_atom_colour(color, TEMPORARY_COLOUR_PRIORITY) return ..() -/datum/reagent/consumable/ethanol/beer/green/on_mob_delete(mob/living/M) +/datum/reagent/consumable/ethanol/beer/green/on_mob_end_metabolize(mob/living/M) M.remove_atom_colour(TEMPORARY_COLOUR_PRIORITY, color) /datum/reagent/consumable/ethanol/kahlua @@ -569,13 +569,13 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_desc = "Tequila and Coffee liqueur, brought together in a mouthwatering mixture. Drink up." var/tough_text -/datum/reagent/consumable/ethanol/brave_bull/on_mob_add(mob/living/M) +/datum/reagent/consumable/ethanol/brave_bull/on_mob_metabolize(mob/living/M) tough_text = pick("brawny", "tenacious", "tough", "hardy", "sturdy") //Tuff stuff to_chat(M, "You feel [tough_text]!") M.maxHealth += 10 //Brave Bull makes you sturdier, and thus capable of withstanding a tiny bit more punishment. M.health += 10 -/datum/reagent/consumable/ethanol/brave_bull/on_mob_delete(mob/living/M) +/datum/reagent/consumable/ethanol/brave_bull/on_mob_end_metabolize(mob/living/M) to_chat(M, "You no longer feel [tough_text].") M.maxHealth -= 10 M.health = min(M.health - 10, M.maxHealth) //This can indeed crit you if you're alive solely based on alchol ingestion @@ -593,7 +593,7 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_desc = "Oh great, now you feel nostalgic about sunrises back on Terra..." var/obj/effect/light_holder -/datum/reagent/consumable/ethanol/tequila_sunrise/on_mob_add(mob/living/M) +/datum/reagent/consumable/ethanol/tequila_sunrise/on_mob_metabolize(mob/living/M) to_chat(M, "You feel gentle warmth spread through your body!") light_holder = new(M) light_holder.set_light(3, 0.7, "#FFCC00") //Tequila Sunrise makes you radiate dim light, like a sunrise! @@ -605,7 +605,7 @@ All effects don't start immediately, but rather get worse over time; the rate is light_holder.forceMove(M) return ..() -/datum/reagent/consumable/ethanol/tequila_sunrise/on_mob_delete(mob/living/M) +/datum/reagent/consumable/ethanol/tequila_sunrise/on_mob_end_metabolize(mob/living/M) to_chat(M, "The warmth in your body fades.") QDEL_NULL(light_holder) @@ -671,7 +671,7 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_desc = "A manly concoction made from Ale and Beer. Intended for true men only." var/dorf_mode -/datum/reagent/consumable/ethanol/manly_dorf/on_mob_add(mob/living/M) +/datum/reagent/consumable/ethanol/manly_dorf/on_mob_metabolize(mob/living/M) if(ishuman(M)) var/mob/living/carbon/human/H = M if(H.dna.check_mutation(DWARFISM) || HAS_TRAIT(H, TRAIT_ALCOHOL_TOLERANCE)) @@ -722,7 +722,7 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_desc = "Kahlua, Irish Cream, and cognac. You will get bombed." shot_glass_icon_state = "b52glass" -/datum/reagent/consumable/ethanol/b52/on_mob_add(mob/living/M) +/datum/reagent/consumable/ethanol/b52/on_mob_metabolize(mob/living/M) playsound(M, 'sound/effects/explosion_distant.ogg', 100, FALSE) /datum/reagent/consumable/ethanol/irishcoffee @@ -1534,7 +1534,7 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_desc = "If you're feeling low, count on the buttery flavor of our own bastion bourbon." shot_glass_icon_state = "shotglassgreen" -/datum/reagent/consumable/ethanol/bastion_bourbon/on_mob_add(mob/living/L) +/datum/reagent/consumable/ethanol/bastion_bourbon/on_mob_metabolize(mob/living/L) var/heal_points = 10 if(L.health <= 0) heal_points = 20 //heal more if we're in softcrit @@ -1618,7 +1618,7 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_name = "Crevice Spike" glass_desc = "It'll either knock the drunkenness out of you or knock you out cold. Both, probably." -/datum/reagent/consumable/ethanol/crevice_spike/on_mob_add(mob/living/L) //damage only applies when drink first enters system and won't again until drink metabolizes out +/datum/reagent/consumable/ethanol/crevice_spike/on_mob_metabolize(mob/living/L) //damage only applies when drink first enters system and won't again until drink metabolizes out L.adjustBruteLoss(3 * min(5,volume)) //minimum 3 brute damage on ingestion to limit non-drink means of injury - a full 5 unit gulp of the drink trucks you for the full 15 /datum/reagent/consumable/ethanol/sake @@ -1661,7 +1661,7 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_desc = "A creamy, indulgent delight that is stronger than it seems." var/obj/item/shield/mighty_shield -/datum/reagent/consumable/ethanol/alexander/on_mob_add(mob/living/L) +/datum/reagent/consumable/ethanol/alexander/on_mob_metabolize(mob/living/L) if(ishuman(L)) var/mob/living/carbon/human/thehuman = L for(var/obj/item/shield/theshield in thehuman.contents) @@ -1675,7 +1675,7 @@ All effects don't start immediately, but rather get worse over time; the rate is if(mighty_shield && !(mighty_shield in L.contents)) //If you had a shield and lose it, you lose the reagent as well. Otherwise this is just a normal drink. L.reagents.del_reagent("alexander") -/datum/reagent/consumable/ethanol/alexander/on_mob_delete(mob/living/L) +/datum/reagent/consumable/ethanol/alexander/on_mob_end_metabolize(mob/living/L) if(mighty_shield) mighty_shield.block_chance -= 10 to_chat(L,"You notice [mighty_shield] looks worn again. Weird.") @@ -1796,7 +1796,7 @@ All effects don't start immediately, but rather get worse over time; the rate is M.overeatduration = 0 return ..() -/datum/reagent/consumable/ethanol/fanciulli/on_mob_add(mob/living/M) +/datum/reagent/consumable/ethanol/fanciulli/on_mob_metabolize(mob/living/M) if(M.health > 0) M.adjustStaminaLoss(20) . = TRUE @@ -1820,7 +1820,7 @@ All effects don't start immediately, but rather get worse over time; the rate is M.adjust_bodytemperature(-20 * TEMPERATURE_DAMAGE_COEFFICIENT, T0C) return ..() -/datum/reagent/consumable/ethanol/branca_menta/on_mob_add(mob/living/M) +/datum/reagent/consumable/ethanol/branca_menta/on_mob_metabolize(mob/living/M) if(M.health > 0) M.adjustStaminaLoss(35) . = TRUE diff --git a/code/modules/reagents/chemistry/reagents/blob_reagents.dm b/code/modules/reagents/chemistry/reagents/blob_reagents.dm index 8ee9449468..af85b6b35f 100644 --- a/code/modules/reagents/chemistry/reagents/blob_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/blob_reagents.dm @@ -204,7 +204,7 @@ C.hal_screwyhud = SCREWYHUD_HEALTHY //fully healed, honest ..() -/datum/reagent/blob/regenerative_materia/on_mob_delete(mob/living/M) +/datum/reagent/blob/regenerative_materia/on_mob_end_metabolize(mob/living/M) if(iscarbon(M)) var/mob/living/carbon/N = M N.hal_screwyhud = 0 diff --git a/code/modules/reagents/chemistry/reagents/drink_reagents.dm b/code/modules/reagents/chemistry/reagents/drink_reagents.dm index ac15eb6b01..6d0d1e13c6 100644 --- a/code/modules/reagents/chemistry/reagents/drink_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/drink_reagents.dm @@ -390,11 +390,11 @@ glass_name = "glass of Nuka Cola" glass_desc = "Don't cry, Don't raise your eye, It's only nuclear wasteland." -/datum/reagent/consumable/nuka_cola/on_mob_add(mob/living/L) +/datum/reagent/consumable/nuka_cola/on_mob_metabolize(mob/living/L) ..() ADD_TRAIT(L, TRAIT_GOTTAGOFAST, id) -/datum/reagent/consumable/nuka_cola/on_mob_delete(mob/living/L) +/datum/reagent/consumable/nuka_cola/on_mob_end_metabolize(mob/living/L) REMOVE_TRAIT(L, TRAIT_GOTTAGOFAST, id) ..() diff --git a/code/modules/reagents/chemistry/reagents/drug_reagents.dm b/code/modules/reagents/chemistry/reagents/drug_reagents.dm index 04dad3a065..a4586dd997 100644 --- a/code/modules/reagents/chemistry/reagents/drug_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/drug_reagents.dm @@ -5,7 +5,7 @@ taste_description = "bitterness" var/trippy = TRUE //Does this drug make you trip? -/datum/reagent/drug/on_mob_delete(mob/living/M) +/datum/reagent/drug/on_mob_end_metabolize(mob/living/M) if(trippy) SEND_SIGNAL(M, COMSIG_CLEAR_MOOD_EVENT, "[id]_high") @@ -168,11 +168,11 @@ var/jitter = TRUE var/confusion = TRUE -/datum/reagent/drug/methamphetamine/on_mob_add(mob/living/L) +/datum/reagent/drug/methamphetamine/on_mob_metabolize(mob/living/L) ..() L.ignore_slowdown(id) -/datum/reagent/drug/methamphetamine/on_mob_delete(mob/living/L) +/datum/reagent/drug/methamphetamine/on_mob_end_metabolize(mob/living/L) L.unignore_slowdown(id) ..() @@ -262,7 +262,7 @@ taste_description = "salt" // because they're bathsalts? var/datum/brain_trauma/special/psychotic_brawling/bath_salts/rage -/datum/reagent/drug/bath_salts/on_mob_add(mob/living/L) +/datum/reagent/drug/bath_salts/on_mob_metabolize(mob/living/L) ..() ADD_TRAIT(L, TRAIT_STUNIMMUNE, id) ADD_TRAIT(L, TRAIT_SLEEPIMMUNE, id) @@ -271,7 +271,7 @@ rage = new() C.gain_trauma(rage, TRAUMA_RESILIENCE_ABSOLUTE) -/datum/reagent/drug/bath_salts/on_mob_delete(mob/living/L) +/datum/reagent/drug/bath_salts/on_mob_end_metabolize(mob/living/L) REMOVE_TRAIT(L, TRAIT_STUNIMMUNE, id) REMOVE_TRAIT(L, TRAIT_SLEEPIMMUNE, id) if(rage) @@ -381,7 +381,7 @@ addiction_stage3_end = 40 addiction_stage4_end = 240 -/datum/reagent/drug/skooma/on_mob_add(mob/living/L) +/datum/reagent/drug/skooma/on_mob_metabolize(mob/living/L) . = ..() ADD_TRAIT(L, TRAIT_GOTTAGOFAST, id) L.next_move_modifier *= 2 @@ -392,7 +392,7 @@ if(H.dna && H.dna.species) H.dna.species.punchdamagehigh *= 5 -/datum/reagent/drug/skooma/on_mob_delete(mob/living/L) +/datum/reagent/drug/skooma/on_mob_end_metabolize(mob/living/L) . = ..() REMOVE_TRAIT(L, TRAIT_GOTTAGOFAST, id) L.next_move_modifier *= 0.5 diff --git a/code/modules/reagents/chemistry/reagents/food_reagents.dm b/code/modules/reagents/chemistry/reagents/food_reagents.dm index afa469706a..38db62fd2a 100644 --- a/code/modules/reagents/chemistry/reagents/food_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/food_reagents.dm @@ -32,6 +32,8 @@ SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "quality_drink", /datum/mood_event/quality_verygood) if (DRINK_FANTASTIC) SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "quality_drink", /datum/mood_event/quality_fantastic) + if (FOOD_AMAZING) + SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "quality_food", /datum/mood_event/amazingtaste) return ..() /datum/reagent/consumable/nutriment @@ -401,7 +403,7 @@ metabolization_rate = 0.2 * REAGENTS_METABOLISM taste_description = "mushroom" -/datum/reagent/mushroomhallucinogen/on_mob_life(mob/living/carbon/M) +/datum/reagent/drug/mushroomhallucinogen/on_mob_life(mob/living/carbon/M) M.slurring = max(M.slurring,50) switch(current_cycle) if(1 to 5) @@ -686,7 +688,7 @@ /datum/reagent/consumable/tinlux/reaction_mob(mob/living/M) M.set_light(2) -/datum/reagent/consumable/tinlux/on_mob_delete(mob/living/M) +/datum/reagent/consumable/tinlux/on_mob_end_metabolize(mob/living/M) M.set_light(-2) /datum/reagent/consumable/vitfro @@ -711,3 +713,14 @@ nutriment_factor = 5 * REAGENTS_METABOLISM color = "#eef442" // rgb: 238, 244, 66 taste_description = "mournful honking" + +/datum/reagent/consumable/secretsauce + name = "secret sauce" + id = "secret_sauce" + description = "What could it be." + nutriment_factor = 2 * REAGENTS_METABOLISM + color = "#792300" + taste_description = "indescribable" + quality = FOOD_AMAZING + taste_mult = 100 + can_synth = FALSE diff --git a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm index 07a2a9c02a..ed441504a5 100644 --- a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm @@ -366,7 +366,7 @@ to_chat(M, "You feel your wounds fade away to nothing!" ) ..() -/datum/reagent/medicine/mine_salve/on_mob_delete(mob/living/M) +/datum/reagent/medicine/mine_salve/on_mob_end_metabolize(mob/living/M) if(iscarbon(M)) var/mob/living/carbon/N = M N.hal_screwyhud = SCREWYHUD_NONE @@ -483,16 +483,24 @@ reagent_state = LIQUID color = "#E6FFF0" metabolization_rate = 0.5 * REAGENTS_METABOLISM + var/healtoxinlover = FALSE /datum/reagent/medicine/pen_acid/on_mob_life(mob/living/carbon/M) M.radiation -= max(M.radiation-RAD_MOB_SAFE, 0)/50 - M.adjustToxLoss(-2*REM, 0) + M.adjustToxLoss(-2*REM, 0, healtoxinlover) for(var/datum/reagent/R in M.reagents.reagent_list) if(R != src) M.reagents.remove_reagent(R.id,2) ..() . = 1 +/datum/reagent/medicine/pen_acid/pen_jelly + name = "Pentetic Jelly" + id = "pen_jelly" + description = "Reduces massive amounts of radiation and toxin damage while purging other chemicals from the body. Slimepeople friendly!" + color = "#91D865" + healtoxinlover = TRUE + /datum/reagent/medicine/sal_acid name = "Salicyclic Acid" id = "sal_acid" @@ -630,11 +638,11 @@ overdose_threshold = 30 addiction_threshold = 25 -/datum/reagent/medicine/morphine/on_mob_add(mob/living/L) +/datum/reagent/medicine/morphine/on_mob_metabolize(mob/living/L) ..() L.ignore_slowdown(id) -/datum/reagent/medicine/morphine/on_mob_delete(mob/living/L) +/datum/reagent/medicine/morphine/on_mob_end_metabolize(mob/living/L) L.unignore_slowdown(id) ..() @@ -875,11 +883,11 @@ metabolization_rate = 0.5 * REAGENTS_METABOLISM overdose_threshold = 60 -/datum/reagent/medicine/stimulants/on_mob_add(mob/living/L) +/datum/reagent/medicine/stimulants/on_mob_metabolize(mob/living/L) ..() ADD_TRAIT(L, TRAIT_GOTTAGOFAST, id) -/datum/reagent/medicine/stimulants/on_mob_delete(mob/living/L) +/datum/reagent/medicine/stimulants/on_mob_end_metabolize(mob/living/L) REMOVE_TRAIT(L, TRAIT_GOTTAGOFAST, id) ..() @@ -1102,7 +1110,7 @@ M.adjustBruteLoss(-3 * REM, 0) M.adjustFireLoss(-3 * REM, 0) M.adjustOxyLoss(-15 * REM, 0) - M.adjustToxLoss(-3 * REM, 0) + M.adjustToxLoss(-3 * REM, 0, TRUE) //Heals TOXINLOVERS M.adjustBrainLoss(2 * REM, 150) //This does, after all, come from ambrosia, and the most powerful ambrosia in existence, at that! M.adjustCloneLoss(-1 * REM, 0) M.adjustStaminaLoss(-30 * REM, 0) @@ -1113,7 +1121,7 @@ /datum/reagent/medicine/earthsblood/overdose_process(mob/living/M) M.hallucination = min(max(0, M.hallucination + 5), 60) - M.adjustToxLoss(5 * REM, 0) + M.adjustToxLoss(8 * REM, 0, TRUE) //Hurts TOXINLOVERS ..() . = 1 @@ -1188,11 +1196,11 @@ color = "#C8A5DC" metabolization_rate = 1 -/datum/reagent/medicine/changelinghaste/on_mob_add(mob/living/L) +/datum/reagent/medicine/changelinghaste/on_mob_metabolize(mob/living/L) ..() ADD_TRAIT(L, TRAIT_GOTTAGOREALLYFAST, id) -/datum/reagent/medicine/changelinghaste/on_mob_delete(mob/living/L) +/datum/reagent/medicine/changelinghaste/on_mob_end_metabolize(mob/living/L) REMOVE_TRAIT(L, TRAIT_GOTTAGOREALLYFAST, id) ..() @@ -1210,11 +1218,11 @@ color = "#F5F5F5" self_consuming = TRUE -/datum/reagent/medicine/corazone/on_mob_add(mob/living/M) +/datum/reagent/medicine/corazone/on_mob_metabolize(mob/living/M) ..() ADD_TRAIT(M, TRAIT_STABLEHEART, id) -/datum/reagent/medicine/corazone/on_mob_delete(mob/living/M) +/datum/reagent/medicine/corazone/on_mob_end_metabolize(mob/living/M) REMOVE_TRAIT(M, TRAIT_STABLEHEART, id) ..() @@ -1223,11 +1231,11 @@ id = "muscle_stimulant" description = "A potent chemical that allows someone under its influence to be at full physical ability even when under massive amounts of pain." -/datum/reagent/medicine/muscle_stimulant/on_mob_add(mob/living/M) +/datum/reagent/medicine/muscle_stimulant/on_mob_metabolize(mob/living/M) . = ..() M.ignore_slowdown(id) -/datum/reagent/medicine/muscle_stimulant/on_mob_delete(mob/living/M) +/datum/reagent/medicine/muscle_stimulant/on_mob_end_metabolize(mob/living/M) . = ..() M.unignore_slowdown(id) @@ -1242,11 +1250,11 @@ taste_description = "salt" // it actually does taste salty var/overdose_progress = 0 // to track overdose progress -/datum/reagent/medicine/modafinil/on_mob_add(mob/living/M) +/datum/reagent/medicine/modafinil/on_mob_metabolize(mob/living/M) ADD_TRAIT(M, TRAIT_SLEEPIMMUNE, id) ..() -/datum/reagent/medicine/modafinil/on_mob_delete(mob/living/M) +/datum/reagent/medicine/modafinil/on_mob_end_metabolize(mob/living/M) REMOVE_TRAIT(M, TRAIT_SLEEPIMMUNE, id) ..() diff --git a/code/modules/reagents/chemistry/reagents/other_reagents.dm b/code/modules/reagents/chemistry/reagents/other_reagents.dm index 40242909de..890403691e 100644 --- a/code/modules/reagents/chemistry/reagents/other_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm @@ -196,11 +196,11 @@ glass_name = "glass of holy water" glass_desc = "A glass of holy water." -/datum/reagent/water/holywater/on_mob_add(mob/living/L) +/datum/reagent/water/holywater/on_mob_metabolize(mob/living/L) ..() ADD_TRAIT(L, TRAIT_HOLY, id) -/datum/reagent/water/holywater/on_mob_delete(mob/living/L) +/datum/reagent/water/holywater/on_mob_end_metabolize(mob/living/L) REMOVE_TRAIT(L, TRAIT_HOLY, id) ..() @@ -1241,12 +1241,12 @@ color = "E1A116" taste_description = "sourness" -/datum/reagent/stimulum/on_mob_add(mob/living/L) +/datum/reagent/stimulum/on_mob_metabolize(mob/living/L) ..() ADD_TRAIT(L, TRAIT_STUNIMMUNE, id) ADD_TRAIT(L, TRAIT_SLEEPIMMUNE, id) -/datum/reagent/stimulum/on_mob_delete(mob/living/L) +/datum/reagent/stimulum/on_mob_end_metabolize(mob/living/L) REMOVE_TRAIT(L, TRAIT_STUNIMMUNE, id) REMOVE_TRAIT(L, TRAIT_SLEEPIMMUNE, id) ..() @@ -1266,11 +1266,11 @@ color = "90560B" taste_description = "burning" -/datum/reagent/nitryl/on_mob_add(mob/living/L) +/datum/reagent/nitryl/on_mob_metabolize(mob/living/L) ..() ADD_TRAIT(L, TRAIT_GOTTAGOFAST, id) -/datum/reagent/nitryl/on_mob_delete(mob/living/L) +/datum/reagent/nitryl/on_mob_end_metabolize(mob/living/L) REMOVE_TRAIT(L, TRAIT_GOTTAGOFAST, id) ..() @@ -1723,7 +1723,7 @@ H.update_transform() ..() -/datum/reagent/growthserum/on_mob_delete(mob/living/M) +/datum/reagent/growthserum/on_mob_end_metabolize(mob/living/M) M.resize = 1/current_size M.update_transform() ..() @@ -1777,11 +1777,11 @@ taste_description = "water" metabolization_rate = 0.25 * REAGENTS_METABOLISM -/datum/reagent/pax/on_mob_add(mob/living/L) +/datum/reagent/pax/on_mob_metabolize(mob/living/L) ..() ADD_TRAIT(L, TRAIT_PACIFISM, id) -/datum/reagent/pax/on_mob_delete(mob/living/L) +/datum/reagent/pax/on_mob_end_metabolize(mob/living/L) REMOVE_TRAIT(L, TRAIT_PACIFISM, id) ..() @@ -1793,11 +1793,11 @@ taste_description = "acrid cinnamon" metabolization_rate = 0.2 * REAGENTS_METABOLISM -/datum/reagent/bz_metabolites/on_mob_add(mob/living/L) +/datum/reagent/bz_metabolites/on_mob_metabolize(mob/living/L) ..() ADD_TRAIT(L, CHANGELING_HIVEMIND_MUTE, id) -/datum/reagent/bz_metabolites/on_mob_delete(mob/living/L) +/datum/reagent/bz_metabolites/on_mob_end_metabolize(mob/living/L) ..() REMOVE_TRAIT(L, CHANGELING_HIVEMIND_MUTE, id) @@ -1814,14 +1814,14 @@ description = "A colorless liquid that suppresses violence on the subjects. Cheaper to synthetize, but wears out faster than normal Pax." metabolization_rate = 1.5 * REAGENTS_METABOLISM -/datum/reagent/peaceborg/confuse +/datum/reagent/peaceborg_confuse name = "Dizzying Solution" id = "dizzysolution" description = "Makes the target off balance and dizzy" metabolization_rate = 1.5 * REAGENTS_METABOLISM taste_description = "dizziness" -/datum/reagent/peaceborg/confuse/on_mob_life(mob/living/carbon/M) +/datum/reagent/peaceborg_confuse/on_mob_life(mob/living/carbon/M) if(M.confused < 6) M.confused = CLAMP(M.confused + 3, 0, 5) if(M.dizziness < 6) @@ -1830,14 +1830,14 @@ to_chat(M, "You feel confused and disorientated.") ..() -/datum/reagent/peaceborg/tire +/datum/reagent/peaceborg_tire name = "Tiring Solution" id = "tiresolution" description = "An extremely weak stamina-toxin that tires out the target. Completely harmless." metabolization_rate = 1.5 * REAGENTS_METABOLISM taste_description = "tiredness" -/datum/reagent/peaceborg/tire/on_mob_life(mob/living/carbon/M) +/datum/reagent/peaceborg_tire/on_mob_life(mob/living/carbon/M) var/healthcomp = (100 - M.health) //DOES NOT ACCOUNT FOR ADMINBUS THINGS THAT MAKE YOU HAVE MORE THAN 200/210 HEALTH, OR SOMETHING OTHER THAN A HUMAN PROCESSING THIS. if(M.getStaminaLoss() < (45 - healthcomp)) //At 50 health you would have 200 - 150 health meaning 50 compensation. 60 - 50 = 10, so would only do 10-19 stamina.) M.adjustStaminaLoss(10) diff --git a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm index 8be95efb83..d9a4e3a843 100644 --- a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm @@ -156,11 +156,11 @@ toxpwr = 0.5 taste_description = "death" -/datum/reagent/toxin/zombiepowder/on_mob_add(mob/living/L) +/datum/reagent/toxin/zombiepowder/on_mob_metabolize(mob/living/L) ..() L.fakedeath(id) -/datum/reagent/toxin/zombiepowder/on_mob_delete(mob/living/L) +/datum/reagent/toxin/zombiepowder/on_mob_end_metabolize(mob/living/L) L.cure_fakedeath(id) ..() @@ -178,11 +178,11 @@ toxpwr = 0.8 taste_description = "death" -/datum/reagent/toxin/ghoulpowder/on_mob_add(mob/living/L) +/datum/reagent/toxin/ghoulpowder/on_mob_metabolize(mob/living/L) ..() ADD_TRAIT(L, TRAIT_FAKEDEATH, id) -/datum/reagent/toxin/ghoulpowder/on_mob_delete(mob/living/L) +/datum/reagent/toxin/ghoulpowder/on_mob_end_metabolize(mob/living/L) REMOVE_TRAIT(L, TRAIT_FAKEDEATH, id) ..() @@ -626,7 +626,7 @@ toxpwr = 0 metabolization_rate = 0.5 * REAGENTS_METABOLISM -/datum/reagent/toxin/amanitin/on_mob_delete(mob/living/M) +/datum/reagent/toxin/amanitin/on_mob_end_metabolize(mob/living/M) var/toxdamage = current_cycle*3*REM M.log_message("has taken [toxdamage] toxin damage from amanitin toxin", LOG_ATTACK) M.adjustToxLoss(toxdamage) @@ -742,7 +742,7 @@ animate(transform = matrix(-rotation, MATRIX_ROTATE), time = 5, easing = QUAD_EASING) return ..() -/datum/reagent/toxin/rotatium/on_mob_delete(mob/living/M) +/datum/reagent/toxin/rotatium/on_mob_end_metabolize(mob/living/M) if(M && M.hud_used) var/list/screens = list(M.hud_used.plane_masters["[FLOOR_PLANE]"], M.hud_used.plane_masters["[GAME_PLANE]"], M.hud_used.plane_masters["[LIGHTING_PLANE]"]) for(var/whole_screen in screens) @@ -779,7 +779,7 @@ */ return ..() -/datum/reagent/toxin/skewium/on_mob_delete(mob/living/M) +/datum/reagent/toxin/skewium/on_mob_end_metabolize(mob/living/M) if(M && M.hud_used) var/list/screens = list(M.hud_used.plane_masters["[FLOOR_PLANE]"], M.hud_used.plane_masters["[GAME_PLANE]"], M.hud_used.plane_masters["[LIGHTING_PLANE]"]) for(var/whole_screen in screens) @@ -798,7 +798,7 @@ /datum/reagent/toxin/anacea/on_mob_life(mob/living/carbon/M) var/remove_amt = 5 - if(holder.has_reagent("calomel") || holder.has_reagent("pen_acid")) + if(holder.has_reagent("calomel") || holder.has_reagent("pen_acid") || holder.has_reagent("pen_jelly")) remove_amt = 0.5 for(var/datum/reagent/medicine/R in M.reagents.reagent_list) M.reagents.remove_reagent(R.id,remove_amt) @@ -882,8 +882,8 @@ toxpwr = 0 taste_description = "stillness" -/datum/reagent/toxin/mimesbane/on_mob_add(mob/living/L) +/datum/reagent/toxin/mimesbane/on_mob_metabolize(mob/living/L) ADD_TRAIT(L, TRAIT_EMOTEMUTE, id) -/datum/reagent/toxin/mimesbane/on_mob_delete(mob/living/L) +/datum/reagent/toxin/mimesbane/on_mob_end_metabolize(mob/living/L) REMOVE_TRAIT(L, TRAIT_EMOTEMUTE, id) diff --git a/code/modules/reagents/chemistry/recipes/medicine.dm b/code/modules/reagents/chemistry/recipes/medicine.dm index dc7c32d925..727048a12c 100644 --- a/code/modules/reagents/chemistry/recipes/medicine.dm +++ b/code/modules/reagents/chemistry/recipes/medicine.dm @@ -94,6 +94,12 @@ results = list("pen_acid" = 6) required_reagents = list("welding_fuel" = 1, "chlorine" = 1, "ammonia" = 1, "formaldehyde" = 1, "sodium" = 1, "cyanide" = 1) +/datum/chemical_reaction/pen_jelly + name = "Pentetic Jelly" + id = "pen_jelly" + results = list("pen_jelly" = 2) + required_reagents = list("pen_acid" = 1, "slimejelly" = 1) + /datum/chemical_reaction/sal_acid name = "Salicyclic Acid" id = "sal_acid" diff --git a/code/modules/reagents/chemistry/recipes/special.dm b/code/modules/reagents/chemistry/recipes/special.dm new file mode 100644 index 0000000000..153372101e --- /dev/null +++ b/code/modules/reagents/chemistry/recipes/special.dm @@ -0,0 +1,212 @@ +GLOBAL_LIST_INIT(food_reagents, build_reagents_to_food()) //reagentid = related food types + +/proc/build_reagents_to_food() + . = list() + for (var/type in subtypesof(/obj/item/reagent_containers/food)) + var/obj/item/reagent_containers/food/item = new type() + for(var/r in item.list_reagents) + if (!.[r]) + .[r] = list() + .[r] += type + qdel(item) + //dang plant snowflake + for (var/type in subtypesof(/obj/item/seeds)) + var/obj/item/seeds/item = new type() + for(var/r in item.reagents_add) + if (!.[r]) + .[r] = list() + .[r] += type + qdel(item) + + +#define RNGCHEM_INPUT "input" +#define RNGCHEM_CATALYSTS "catalysts" +#define RNGCHEM_OUTPUT "output" + +/datum/chemical_reaction/randomized + name = "semi randomized reaction" + + var/persistent = FALSE + var/persistence_period = 7 //Will reset every x days + var/created //creation timestamp + + var/randomize_container = FALSE + var/list/possible_containers = list() + + var/randomize_req_temperature = TRUE + var/min_temp = 1 + var/max_temp = 600 + + var/randomize_inputs = TRUE + var/min_input_reagent_amount = 1 + var/max_input_reagent_amount = 10 + var/min_input_reagents = 2 + var/max_input_reagents = 5 + var/list/possible_reagents = list() + var/min_catalysts = 0 + var/max_catalysts = 2 + var/list/possible_catalysts = list() + + var/randomize_results = FALSE + var/min_output_reagent_amount = 1 + var/max_output_reagent_amount = 5 + var/min_result_reagents = 1 + var/max_result_reagents = 1 + var/list/possible_results = list() + +/datum/chemical_reaction/randomized/proc/GenerateRecipe() + created = world.time + if(randomize_container) + required_container = pick(possible_containers) + if(randomize_req_temperature) + required_temp = rand(min_temp,max_temp) + is_cold_recipe = pick(TRUE,FALSE) + + if(randomize_results) + results = list() + var/list/remaining_possible_results = GetPossibleReagents(RNGCHEM_OUTPUT) + var/out_reagent_count = min(rand(min_result_reagents,max_result_reagents),remaining_possible_results.len) + for(var/i in 1 to out_reagent_count) + var/r_id = pick_n_take(remaining_possible_results) + results[r_id] = rand(min_output_reagent_amount,max_output_reagent_amount) + + if(randomize_inputs) + var/list/remaining_possible_reagents = GetPossibleReagents(RNGCHEM_INPUT) + var/list/remaining_possible_catalysts = GetPossibleReagents(RNGCHEM_CATALYSTS) + + //We're going to assume we're not doing any weird partial reactions for now. + for(var/reagent_type in results) + remaining_possible_catalysts -= reagent_type + remaining_possible_reagents -= reagent_type + + var/in_reagent_count = min(rand(min_input_reagents,max_input_reagents),remaining_possible_reagents.len) + if(in_reagent_count <= 0) + return FALSE + + required_reagents = list() + for(var/i in 1 to in_reagent_count) + var/r_id = pick_n_take(remaining_possible_reagents) + required_reagents[r_id] = rand(min_input_reagent_amount,max_input_reagent_amount) + remaining_possible_catalysts -= r_id //Can't have same reagents both as catalyst and reagent. Or can we ? + + required_catalysts = list() + var/in_catalyst_count = min(rand(min_catalysts,max_catalysts),remaining_possible_catalysts.len) + for(var/i in 1 to in_catalyst_count) + var/r_id = pick_n_take(remaining_possible_catalysts) + required_catalysts[r_id] = rand(min_input_reagent_amount,max_input_reagent_amount) + + return TRUE + +/datum/chemical_reaction/randomized/proc/GetPossibleReagents(kind) + switch(kind) + if(RNGCHEM_INPUT) + return possible_reagents.Copy() + if(RNGCHEM_CATALYSTS) + return possible_catalysts.Copy() + if(RNGCHEM_OUTPUT) + return possible_results.Copy() + +/datum/chemical_reaction/randomized/proc/HasConflicts() + for(var/x in required_reagents) + for(var/datum/chemical_reaction/R in GLOB.chemical_reactions_list[x]) + if(chem_recipes_do_conflict(R,src)) + return TRUE + return FALSE + +/datum/chemical_reaction/randomized/proc/unwrap_reagent_list(list/textreagents) + . = list() + for(var/R in textreagents) + var/pathR = text2path(R) + if(!pathR) + return null + .[pathR] = textreagents[R] + +/datum/chemical_reaction/randomized/proc/LoadOldRecipe(recipe_data) + created = text2num(recipe_data["timestamp"]) + + var/req_reag = unwrap_reagent_list(recipe_data["required_reagents"]) + if(!req_reag) + return FALSE + required_reagents = req_reag + + var/req_catalysts = unwrap_reagent_list(recipe_data["required_catalysts"]) + if(!req_catalysts) + return FALSE + required_catalysts = req_catalysts + + required_temp = recipe_data["required_temp"] + is_cold_recipe = recipe_data["is_cold_recipe"] + + var/temp_results = unwrap_reagent_list(recipe_data["results"]) + if(!temp_results) + return FALSE + results = temp_results + var/containerpath = text2path(recipe_data["required_container"]) + if(!containerpath) + return FALSE + required_container = containerpath + return TRUE + +/datum/chemical_reaction/randomized/secret_sauce + name = "secret sauce creation" + id = "secretsauce" + persistent = TRUE + persistence_period = 7 //Reset every week + randomize_container = TRUE + possible_containers = list(/obj/item/reagent_containers/glass/bucket) //easy way to ensure no common conflicts + randomize_req_temperature = TRUE + results = list("secret_sauce" =1) + +/datum/chemical_reaction/randomized/secret_sauce/GetPossibleReagents(kind) + switch(kind) + if(RNGCHEM_INPUT,RNGCHEM_CATALYSTS) + var/food_reagent_ids = list() + for(var/key in GLOB.food_reagents) + food_reagent_ids += key + return food_reagent_ids + return ..() + + +/obj/item/paper/secretrecipe + name = "old recipe" + var/recipe_id = "secretsauce" + +/obj/item/paper/secretrecipe/examine(mob/user) //Extra secret + if(isobserver(user)) + return + . = ..() + +/obj/item/paper/secretrecipe/Initialize() + . = ..() + if(SSpersistence.initialized) + UpdateInfo() + else + SSticker.OnRoundstart(CALLBACK(src,.proc/UpdateInfo)) + +/obj/item/paper/secretrecipe/proc/UpdateInfo() + var/datum/chemical_reaction/recipe = get_chemical_reaction(recipe_id) + if(!recipe) + info = "This recipe is illegible." + var/list/dat = list("" + if(recipe.required_catalysts.len) + dat += "With following present: " + dat += "Mix slowly" + if(recipe.required_container) + var/obj/item/I = recipe.required_container + dat += " in [initial(I.name)]" + if(recipe.required_temp != 0) + if(recipe.is_cold_recipe) + dat += " below [recipe.required_temp] degrees" + else + dat += " above [recipe.required_temp] degrees" + dat += "." + info = dat.Join("") + update_icon() \ No newline at end of file diff --git a/code/modules/reagents/reagent_containers/syringes.dm b/code/modules/reagents/reagent_containers/syringes.dm index 4947ddde6f..cc83eb28f6 100644 --- a/code/modules/reagents/reagent_containers/syringes.dm +++ b/code/modules/reagents/reagent_containers/syringes.dm @@ -259,3 +259,92 @@ /obj/item/reagent_containers/syringe/get_belt_overlay() return mutable_appearance('icons/obj/clothing/belt_overlays.dmi', "pouch") + +/obj/item/reagent_containers/syringe/dart + name = "medicinal smartdart" + desc = "A non-harmful dart that can administer medication from a range. Once it hits a patient using it's smart nanofilter technology only medicines contained within the dart are administered to the patient. Additonally, due to capillary action, injection of chemicals past the overdose limit is prevented." + volume = 20 + amount_per_transfer_from_this = 20 + icon_state = "empty" + item_state = "syringe_empty" + var/emptrig = FALSE + +/obj/item/reagent_containers/syringe/dart/afterattack(atom/target, mob/user , proximity) + + if(busy) + return + if(!proximity) + return + if(!target.reagents) + return + + var/mob/living/L + if(isliving(target)) + L = target + if(!L.can_inject(user, 1)) + return + + switch(mode) + if(SYRINGE_DRAW) + + if(reagents.total_volume >= reagents.maximum_volume) + to_chat(user, "The dart is full!") + return + + if(L) //living mob + to_chat(user, "You can't draw blood using a dart!") + return + + else //if not mob + if(!target.reagents.total_volume) + to_chat(user, "[target] is empty!") + return + + if(!target.is_drawable()) + to_chat(user, "You cannot directly remove reagents from [target]!") + return + + var/trans = target.reagents.trans_to(src, amount_per_transfer_from_this) + + to_chat(user, "You soak the [src] with [trans] units of the solution. It now contains [reagents.total_volume] units.") + if (reagents.total_volume >= reagents.maximum_volume) + mode=!mode + update_icon() + + if(SYRINGE_INJECT) + src.visible_message("The smartdart gives a frustrated boop! It's fully saturated; You need to shoot someone with it!") + +/obj/item/reagent_containers/syringe/dart/attack_self(mob/user) + return + +/obj/item/reagent_containers/syringe/dart/update_icon() + cut_overlays() + var/rounded_vol + + rounded_vol = "empty" + if(reagents && reagents.total_volume) + if(volume/reagents.total_volume == 1) + rounded_vol="full" + + icon_state = "[rounded_vol]" + item_state = "syringe_[rounded_vol]" + if(ismob(loc)) + var/mob/M = loc + var/injoverlay + switch(mode) + if (SYRINGE_DRAW) + injoverlay = "draw" + if (SYRINGE_INJECT) + injoverlay = "ready" + add_overlay(injoverlay) + M.update_inv_hands() + +/obj/item/reagent_containers/syringe/dart/emp_act(severity) + emptrig = TRUE + ..() + +/obj/item/reagent_containers/syringe/dart/bluespace + name = "bluespace smartdart" + desc = "A non-harmful dart that can administer medication from a range. Once it hits a patient using it's smart nanofilter technology only medicines contained within the dart are administered to the patient. Additonally, due to capillary action, injection of chemicals past the overdose limit is prevented. Has an extended volume capacity thanks to bluespace foam." + amount_per_transfer_from_this = 50 + volume = 50 diff --git a/code/modules/research/designs/medical_designs.dm b/code/modules/research/designs/medical_designs.dm index 7224d0e4e8..3a7ef68903 100644 --- a/code/modules/research/designs/medical_designs.dm +++ b/code/modules/research/designs/medical_designs.dm @@ -92,6 +92,36 @@ category = list("Medical Designs") departmental_flags = DEPARTMENTAL_FLAG_MEDICAL +/datum/design/medicinalsmartdart + name = "Medicinal Smartdart" + desc = "A non-harmful dart that can administer medication from a range. Once it hits a patient using it's smart nanofilter technology only medicines contained within the dart are administered to the patient. Additonally, due to capillary action, injection of chemicals past the overdose limit is prevented." + id = "medicinalsmartdart" + build_type = PROTOLATHE + materials = list(MAT_GLASS = 100, MAT_PLASTIC = 100, MAT_METAL = 100) + build_path = /obj/item/reagent_containers/syringe/dart + category = list("Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL + +/datum/design/bluespacesmartdart + name = "bluespace smartdart" + desc = "A non-harmful dart that can administer medication from a range. Once it hits a patient using it's smart nanofilter technology only medicines contained within the dart are administered to the patient. Additonally, due to capillary action, injection of chemicals past the overdose limit is prevented. Has an extended volume capacity thanks to bluespace foam." + id = "bluespacesmartdart" + build_type = PROTOLATHE + materials = list(MAT_GLASS = 250, MAT_PLASTIC = 250, MAT_METAL = 250, MAT_BLUESPACE = 250) + build_path = /obj/item/reagent_containers/syringe/dart/bluespace + category = list("Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL + +/datum/design/smartdartgun + name = "dart gun" + desc = "A compressed air gun, designed to fit medicinal darts for application of medicine for those patients just out of reach." + id = "smartdartgun" + build_type = PROTOLATHE + materials = list(MAT_GLASS = 500, MAT_PLASTIC = 1000, MAT_METAL = 500) + build_path = /obj/item/gun/syringe/dart + category = list("Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL + /datum/design/bluespacebodybag name = "Bluespace Body Bag" desc = "A bluespace body bag, powered by experimental bluespace technology. It can hold loads of bodies and the largest of creatures." @@ -172,6 +202,16 @@ category = list("Medical Designs") departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE +/datum/design/organbox + name = "Empty Organ Box" + desc = "A large cool box that can hold large amouts of medical tools or organs." + id = "organbox" + build_type = PROTOLATHE + materials = list(MAT_METAL = 3000, MAT_GLASS = 1000, MAT_SILVER= 3500, MAT_GOLD = 3500, MAT_PLASTIC = 5000) + build_path = /obj/item/storage/belt/organbox + category = list("Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE + //////////////////////////////////////// //////////Defibrillator Tech//////////// //////////////////////////////////////// diff --git a/code/modules/research/nanites/nanite_programs.dm b/code/modules/research/nanites/nanite_programs.dm index f691c828c9..a06311f26f 100644 --- a/code/modules/research/nanites/nanite_programs.dm +++ b/code/modules/research/nanites/nanite_programs.dm @@ -57,6 +57,7 @@ deactivate() if(passive_enabled) disable_passive_effect() + on_mob_remove() if(nanites) nanites.programs -= src return ..() @@ -107,6 +108,9 @@ if(activated) //apply activation effects if it starts active activate() +datum/nanite_program/proc/on_mob_remove() + return + /datum/nanite_program/proc/toggle() if(!activated) activate() @@ -115,6 +119,7 @@ /datum/nanite_program/proc/activate() activated = TRUE + timer_counter = activation_delay /datum/nanite_program/proc/deactivate() if(passive_enabled) @@ -135,8 +140,10 @@ if(timer && timer_counter > timer) if(timer_type == NANITE_TIMER_DEACTIVATE) deactivate() + return else if(timer_type == NANITE_TIMER_SELFDELETE) qdel(src) + return else if(can_trigger && timer_type == NANITE_TIMER_TRIGGER) trigger() timer_counter = activation_delay @@ -251,4 +258,3 @@ return "Trigger" if(NANITE_TIMER_RESET) return "Reset Activation Timer" - diff --git a/code/modules/research/nanites/nanite_programs/utility.dm b/code/modules/research/nanites/nanite_programs/utility.dm index 4405401cec..77fb4e1005 100644 --- a/code/modules/research/nanites/nanite_programs/utility.dm +++ b/code/modules/research/nanites/nanite_programs/utility.dm @@ -237,7 +237,11 @@ if(prob(10)) var/list/mob/living/target_hosts = list() for(var/mob/living/L in oview(5, host_mob)) + if(!(MOB_ORGANIC in L.mob_biotypes) && !(MOB_UNDEAD in L.mob_biotypes)) + continue target_hosts += L + if(!target_hosts.len) + return var/mob/living/infectee = pick(target_hosts) if(prob(100 - (infectee.get_permeability_protection() * 100))) //this will potentially take over existing nanites! diff --git a/code/modules/research/techweb/all_nodes.dm b/code/modules/research/techweb/all_nodes.dm index 80c597c2c0..4331d8858b 100644 --- a/code/modules/research/techweb/all_nodes.dm +++ b/code/modules/research/techweb/all_nodes.dm @@ -69,7 +69,7 @@ display_name = "Advanced Biotechnology" description = "Advanced Biotechnology" prereq_ids = list("biotech") - design_ids = list("piercesyringe", "crewpinpointer", "smoke_machine", "plasmarefiller", "limbgrower", "defibrillator", "meta_beaker", "healthanalyzer_advanced","harvester","holobarrier_med") + design_ids = list("piercesyringe", "crewpinpointer", "smoke_machine", "plasmarefiller", "limbgrower", "defibrillator", "meta_beaker", "healthanalyzer_advanced","harvester","holobarrier_med","smartdartgun","medicinalsmartdart") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) export_price = 5000 @@ -115,7 +115,7 @@ display_name = "Advanced Surgery" description = "When simple medicine doesn't cut it." prereq_ids = list("adv_biotech") - design_ids = list("surgery_lobotomy", "surgery_reconstruction") + design_ids = list("surgery_lobotomy", "surgery_reconstruction", "organbox") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) export_price = 5000 @@ -246,7 +246,7 @@ display_name = "Applied Bluespace Research" description = "Using bluespace to make things faster and better." prereq_ids = list("bluespace_basic", "engineering") - design_ids = list("bs_rped","biobag_holding","minerbag_holding", "bluespacebeaker", "bluespacesyringe", "phasic_scanning", "roastingstick", "ore_silo") + design_ids = list("bs_rped","biobag_holding","minerbag_holding", "bluespacebeaker", "bluespacesyringe", "phasic_scanning", "roastingstick", "ore_silo", "bluespacesmartdart") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 7500) export_price = 5000 diff --git a/code/modules/ruins/lavaland_ruin_code.dm b/code/modules/ruins/lavaland_ruin_code.dm index 28ea849782..161ea3ac62 100644 --- a/code/modules/ruins/lavaland_ruin_code.dm +++ b/code/modules/ruins/lavaland_ruin_code.dm @@ -22,7 +22,7 @@ icon_state = "datadisk1" max_blueprints = 1 -/obj/item/disk/design_disk/golem_shell/Initialize() +/obj/item/disk/design_disk/plant_disk/Initialize() . = ..() var/datum/design/diskplantgene/P = new blueprints[1] = P diff --git a/code/modules/spells/spell_types/construct_spells.dm b/code/modules/spells/spell_types/construct_spells.dm index 39066ae4a9..bb3cc1f7e3 100644 --- a/code/modules/spells/spell_types/construct_spells.dm +++ b/code/modules/spells/spell_types/construct_spells.dm @@ -146,11 +146,14 @@ clothes_req = 0 invocation = "none" invocation_type = "none" + proj_type = /obj/effect/proc_holder/spell/targeted/inflict_handler/magic_missile/lesser proj_lifespan = 10 max_targets = 6 action_icon_state = "magicm" action_background_icon_state = "bg_demon" +/obj/effect/proc_holder/spell/targeted/inflict_handler/magic_missile/lesser + amt_knockdown = 84 /obj/effect/proc_holder/spell/targeted/smoke/disable name = "Paralysing Smoke" @@ -304,7 +307,8 @@ name = "Gauntlet Echo" alpha = 180 amt_dam_brute = 30 - amt_knockdown = 50 + amt_knockdown = 84 + amt_dam_stam = 30 sound = 'sound/weapons/punch3.ogg' /obj/effect/proc_holder/spell/targeted/inflict_handler/juggernaut/cast(list/targets,mob/user = usr) diff --git a/code/modules/spells/spell_types/inflict_handler.dm b/code/modules/spells/spell_types/inflict_handler.dm index da0af7a601..25bdc7c9d2 100644 --- a/code/modules/spells/spell_types/inflict_handler.dm +++ b/code/modules/spells/spell_types/inflict_handler.dm @@ -3,10 +3,12 @@ desc = "This spell blinds and/or destroys/damages/heals and/or knockdowns/stuns the target." var/amt_knockdown = 0 + var/amt_hardstun var/amt_unconscious = 0 var/amt_stun = 0 //set to negatives for healing + var/amt_dam_stam var/amt_dam_fire = 0 var/amt_dam_brute = 0 var/amt_dam_oxy = 0 @@ -41,7 +43,10 @@ target.adjustToxLoss(amt_dam_tox) target.adjustOxyLoss(amt_dam_oxy) //disabling - target.Knockdown(amt_knockdown) + if(!amt_knockdown && amt_dam_stam) + target.adjustStaminaLoss(amt_dam_stam) + else + target.Knockdown(amt_knockdown, override_hardstun = amt_hardstun, amt_dam_stam) target.Unconscious(amt_unconscious) target.Stun(amt_stun) diff --git a/code/modules/spells/spell_types/wizard.dm b/code/modules/spells/spell_types/wizard.dm index aec0e7806b..c4d2c34a71 100644 --- a/code/modules/spells/spell_types/wizard.dm +++ b/code/modules/spells/spell_types/wizard.dm @@ -28,7 +28,8 @@ sound = 'sound/magic/magic_missile.ogg' /obj/effect/proc_holder/spell/targeted/inflict_handler/magic_missile - amt_knockdown = 60 + amt_knockdown = 120 + amt_hardstun = 5 sound = 'sound/magic/mm_hit.ogg' /obj/effect/proc_holder/spell/targeted/genetic/mutate @@ -262,7 +263,7 @@ action_icon_state = "repulse" -/obj/effect/proc_holder/spell/aoe_turf/repulse/cast(list/targets,mob/user = usr, var/stun_amt = 40) +/obj/effect/proc_holder/spell/aoe_turf/repulse/cast(list/targets,mob/user = usr, stun_amt = 50) var/list/thrownatoms = list() var/atom/throwtarget var/distfromcaster @@ -286,14 +287,14 @@ if(distfromcaster == 0) if(isliving(AM)) var/mob/living/M = AM - M.Knockdown(100) + M.Knockdown(100, override_hardstun = 20) M.adjustBruteLoss(5) to_chat(M, "You're slammed into the floor by [user]!") else new sparkle_path(get_turf(AM), get_dir(user, AM)) //created sparkles will disappear on their own if(isliving(AM)) var/mob/living/M = AM - M.Knockdown(stun_amt) + M.Knockdown(stun_amt, override_hardstun = stun_amt * 0.2) to_chat(M, "You're thrown back by [user]!") AM.throw_at(throwtarget, ((CLAMP((maxthrow - (CLAMP(distfromcaster - 2, 0, distfromcaster))), 3, maxthrow))), 1,user)//So stuff gets tossed around at the same time. diff --git a/code/modules/surgery/bodyparts/bodyparts.dm b/code/modules/surgery/bodyparts/bodyparts.dm index 9204de3d08..a97a133685 100644 --- a/code/modules/surgery/bodyparts/bodyparts.dm +++ b/code/modules/surgery/bodyparts/bodyparts.dm @@ -21,7 +21,7 @@ var/held_index = 0 //are we a hand? if so, which one! var/is_pseudopart = FALSE //For limbs that don't really exist, eg chainsaws - var/disabled = FALSE //If TRUE, limb is as good as missing + var/disabled = BODYPART_NOT_DISABLED //If disabled, limb is as good as missing var/body_damage_coeff = 1 //Multiplier of the limb's damage that gets applied to the mob var/stam_damage_coeff = 0.5 var/brutestate = 0 @@ -189,7 +189,7 @@ if(stamina > DAMAGE_PRECISION) owner.update_stamina() consider_processing() - check_disabled() + update_disabled() return update_bodypart_damage_state() //Heals brute and burn damage for the organ. Returns 1 if the damage-icon states changed at all. @@ -209,7 +209,7 @@ if(owner && updating_health) owner.updatehealth() consider_processing() - check_disabled() + update_disabled() return update_bodypart_damage_state() //Returns total damage. @@ -220,7 +220,24 @@ return total //Checks disabled status thresholds -/obj/item/bodypart/proc/check_disabled() + +//Checks disabled status thresholds +/obj/item/bodypart/proc/update_disabled() + set_disabled(is_disabled()) + +/obj/item/bodypart/proc/is_disabled() + if(HAS_TRAIT(owner, TRAIT_PARALYSIS)) + return BODYPART_DISABLED_PARALYSIS + if(can_dismember() && !HAS_TRAIT(owner, TRAIT_NODISMEMBER)) + . = disabled //inertia, to avoid limbs healing 0.1 damage and being re-enabled + if((get_damage(TRUE) >= max_damage)) + return BODYPART_DISABLED_DAMAGE + if(disabled && (get_damage(TRUE) <= (max_damage * 0.5))) + return BODYPART_NOT_DISABLED + else + return BODYPART_NOT_DISABLED + +/obj/item/bodypart/proc/check_disabled() //This might be depreciated and should be safe to remove. if(!can_dismember() || HAS_TRAIT(owner, TRAIT_NODISMEMBER)) return if(!disabled && (get_damage(TRUE) >= max_damage)) @@ -228,7 +245,8 @@ else if(disabled && (get_damage(TRUE) <= (max_damage * 0.5))) set_disabled(FALSE) -/obj/item/bodypart/proc/set_disabled(new_disabled = TRUE) + +/obj/item/bodypart/proc/set_disabled(new_disabled) if(disabled == new_disabled) return disabled = new_disabled @@ -546,6 +564,11 @@ max_stamina_damage = 200 var/obj/item/cavity_item +/obj/item/bodypart/chest/can_dismember(obj/item/I) + if(!((owner.stat == DEAD) || owner.InFullCritical())) + return FALSE + return ..() + /obj/item/bodypart/chest/Destroy() if(cavity_item) qdel(cavity_item) @@ -601,13 +624,27 @@ px_y = 0 stam_heal_tick = 2 -/obj/item/bodypart/l_arm/set_disabled(new_disabled = TRUE) - ..() - if(disabled) - to_chat(owner, "Your [name] is too damaged to function!") - owner.emote("scream") +/obj/item/bodypart/l_arm/is_disabled() + if(HAS_TRAIT(owner, TRAIT_PARALYSIS_L_ARM)) + return BODYPART_DISABLED_PARALYSIS + return ..() + +/obj/item/bodypart/l_arm/set_disabled(new_disabled) + . = ..() + if(disabled == new_disabled) + return + if(disabled == BODYPART_DISABLED_DAMAGE) + if(owner.stat > UNCONSCIOUS) + owner.emote("scream") + if(. && (owner.stat > DEAD)) + to_chat(owner, "Your [name] is too damaged to function!") if(held_index) owner.dropItemToGround(owner.get_item_for_held_index(held_index)) + else if(disabled == BODYPART_DISABLED_PARALYSIS) + if(. && (owner.stat > DEAD)) + to_chat(owner, "You can't feel your [name]!") + if(held_index) + owner.dropItemToGround(owner.get_item_for_held_index(held_index)) if(owner.hud_used) var/obj/screen/inventory/hand/L = owner.hud_used.hand_slots["[held_index]"] if(L) @@ -652,18 +689,33 @@ stam_heal_tick = 2 max_stamina_damage = 50 -/obj/item/bodypart/r_arm/set_disabled(new_disabled = TRUE) - ..() - if(disabled) - to_chat(owner, "Your [name] is too damaged to function!") - owner.emote("scream") +/obj/item/bodypart/r_arm/is_disabled() + if(HAS_TRAIT(owner, TRAIT_PARALYSIS_R_ARM)) + return BODYPART_DISABLED_PARALYSIS + return ..() + +/obj/item/bodypart/r_arm/set_disabled(new_disabled) + . = ..() + if(disabled == new_disabled) + return + if(disabled == BODYPART_DISABLED_DAMAGE) + if(owner.stat > UNCONSCIOUS) + owner.emote("scream") + if(. && (owner.stat > DEAD)) + to_chat(owner, "Your [name] is too damaged to function!") if(held_index) owner.dropItemToGround(owner.get_item_for_held_index(held_index)) + else if(disabled == BODYPART_DISABLED_PARALYSIS) + if(. && (owner.stat > DEAD)) + to_chat(owner, "You can't feel your [name]!") + if(held_index) + owner.dropItemToGround(owner.get_item_for_held_index(held_index)) if(owner.hud_used) var/obj/screen/inventory/hand/R = owner.hud_used.hand_slots["[held_index]"] if(R) R.update_icon() + /obj/item/bodypart/r_arm/monkey icon = 'icons/mob/animal_parts.dmi' icon_state = "default_monkey_r_arm" @@ -700,11 +752,24 @@ stam_heal_tick = 2 max_stamina_damage = 50 -/obj/item/bodypart/l_leg/set_disabled(new_disabled = TRUE) - ..() - if(disabled) - to_chat(owner, "Your [name] is too damaged to function!") - owner.emote("scream") +/obj/item/bodypart/l_leg/is_disabled() + if(HAS_TRAIT(owner, TRAIT_PARALYSIS_L_LEG)) + return BODYPART_DISABLED_PARALYSIS + return ..() + +/obj/item/bodypart/l_leg/set_disabled(new_disabled) + . = ..() + if(disabled == new_disabled) + return + if(disabled == BODYPART_DISABLED_DAMAGE) + if(owner.stat > UNCONSCIOUS) + owner.emote("scream") + if(. && (owner.stat > DEAD)) + to_chat(owner, "Your [name] is too damaged to function!") + else if(disabled == BODYPART_DISABLED_PARALYSIS) + if(. && (owner.stat > DEAD)) + to_chat(owner, "You can't feel your [name]!") + /obj/item/bodypart/l_leg/digitigrade name = "left digitigrade leg" @@ -747,11 +812,23 @@ max_stamina_damage = 50 stam_heal_tick = 2 -/obj/item/bodypart/r_leg/set_disabled(new_disabled = TRUE) - ..() - if(disabled) - to_chat(owner, "Your [name] is too damaged to function!") - owner.emote("scream") +/obj/item/bodypart/r_leg/is_disabled() + if(HAS_TRAIT(owner, TRAIT_PARALYSIS_R_LEG)) + return BODYPART_DISABLED_PARALYSIS + return ..() + +/obj/item/bodypart/r_leg/set_disabled(new_disabled) + . = ..() + if(disabled == new_disabled) + return + if(disabled == BODYPART_DISABLED_DAMAGE) + if(owner.stat > UNCONSCIOUS) + owner.emote("scream") + if(. && (owner.stat > DEAD)) + to_chat(owner, "Your [name] is too damaged to function!") + else if(disabled == BODYPART_DISABLED_PARALYSIS) + if(. && (owner.stat > DEAD)) + to_chat(owner, "You can't feel your [name]!") /obj/item/bodypart/r_leg/digitigrade name = "right digitigrade leg" diff --git a/code/modules/surgery/organs/augments_arms.dm b/code/modules/surgery/organs/augments_arms.dm index ad07ce7238..f09258f19f 100644 --- a/code/modules/surgery/organs/augments_arms.dm +++ b/code/modules/surgery/organs/augments_arms.dm @@ -129,11 +129,14 @@ holder = null if(contents.len == 1) Extend(contents[1]) - else // TODO: make it similar to borg's storage-like module selection - var/obj/item/choise = input("Activate which item?", "Arm Implant", null, null) as null|anything in items_list - if(owner && owner == usr && owner.stat != DEAD && (src in owner.internal_organs) && !holder && istype(choise) && (choise in contents)) - // This monster sanity check is a nice example of how bad input() is. - Extend(choise) + else + var/list/choice_list = list() + for(var/obj/item/I in items_list) + choice_list[I] = getFlatIcon(I) + var/obj/item/choice = show_radial_menu(owner, owner, choice_list) + if(owner && owner == usr && owner.stat != DEAD && (src in owner.internal_organs) && !holder && (choice in contents)) + // This monster sanity check is a nice example of how bad input is. + Extend(choice) else Retract() diff --git a/code/modules/unit_tests/reagent_recipe_collisions.dm b/code/modules/unit_tests/reagent_recipe_collisions.dm index 31027c2cd3..20e875422f 100644 --- a/code/modules/unit_tests/reagent_recipe_collisions.dm +++ b/code/modules/unit_tests/reagent_recipe_collisions.dm @@ -11,57 +11,5 @@ for(var/i2 in (i+1) to reactions.len) var/datum/chemical_reaction/r1 = reactions[i] var/datum/chemical_reaction/r2 = reactions[i2] - if(recipes_do_conflict(r1, r2)) + if(chem_recipes_do_conflict(r1, r2)) Fail("Chemical recipe conflict between [r1.type] and [r2.type]") - -/datum/unit_test/reagent_recipe_collisions/proc/recipes_do_conflict(datum/chemical_reaction/r1, datum/chemical_reaction/r2) - //do the non-list tests first, because they are cheaper - if(r1.required_container != r2.required_container) - return FALSE - if(r1.is_cold_recipe == r2.is_cold_recipe) - if(r1.required_temp != r2.required_temp) - //one reaction requires a more extreme temperature than the other, so there is no conflict - return FALSE - else - var/datum/chemical_reaction/cold_one = r1.is_cold_recipe ? r1 : r2 - var/datum/chemical_reaction/warm_one = r1.is_cold_recipe ? r2 : r1 - if(cold_one.required_temp < warm_one.required_temp) - //the range of temperatures does not overlap, so there is no conflict - return FALSE - - //find the reactions with the shorter and longer required_reagents list - var/datum/chemical_reaction/long_req - var/datum/chemical_reaction/short_req - if(r1.required_reagents.len > r2.required_reagents.len) - long_req = r1 - short_req = r2 - else if(r1.required_reagents.len < r2.required_reagents.len) - long_req = r2 - short_req = r1 - else - //if they are the same length, sort instead by the length of the catalyst list - //this is important if the required_reagents lists are the same - if(r1.required_catalysts.len > r2.required_catalysts.len) - long_req = r1 - short_req = r2 - else - long_req = r2 - short_req = r1 - - - //check if the shorter reaction list is a subset of the longer one - var/list/overlap = r1.required_reagents & r2.required_reagents - if(overlap.len != short_req.required_reagents.len) - //there is at least one reagent in the short list that is not in the long list, so there is no conflict - return FALSE - - //check to see if the shorter reaction's catalyst list is also a subset of the longer reaction's catalyst list - //if the longer reaction's catalyst list is a subset of the shorter ones, that is fine - //if the reaction lists are the same, the short reaction will have the shorter required_catalysts list, so it will register as a conflict - var/list/short_minus_long_catalysts = short_req.required_catalysts - long_req.required_catalysts - if(short_minus_long_catalysts.len) - //there is at least one unique catalyst for the short reaction, so there is no conflict - return FALSE - - //if we got this far, the longer reaction will be impossible to create if the shorter one is earlier in GLOB.chemical_reactions_list, and will require the reagents to be added in a particular order otherwise - return TRUE \ No newline at end of file diff --git a/code/modules/uplink/uplink_items.dm b/code/modules/uplink/uplink_items.dm index 0d5a5e5819..3018ebf03c 100644 --- a/code/modules/uplink/uplink_items.dm +++ b/code/modules/uplink/uplink_items.dm @@ -109,72 +109,194 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) /datum/uplink_item/discounts category = "Discounted Gear" -// Nuclear Operative (Special Offers) -/datum/uplink_item/nukeoffer - category = "Special Offers" +//All bundles and telecrystals +/datum/uplink_item/bundles_TC + category = "Bundles and Telecrystals" surplus = 0 - include_modes = list(/datum/game_mode/nuclear) cant_discount = TRUE -/datum/uplink_item/nukeoffer/c20r - name = "C-20r bundle" - desc = "Old faithful: The classic C-20r, bundled with two magazines, and a (surplus) suppressor at discount price." - item = /obj/item/storage/backpack/duffelbag/syndie/c20rbundle - cost = 14 // normally 16 - -/datum/uplink_item/nukeoffer/bulldog - name = "Bulldog bundle" - desc = "Lean and mean: Optimised for people that want to get up close and personal. Contains the popular \ - Bulldog shotgun, two 12g drums, and a pair of Thermal imaging goggles." - item = /obj/item/storage/backpack/duffelbag/syndie/bulldogbundle - cost = 13 // normally 16 - -/datum/uplink_item/nukeoffer/medical - name = "Medical bundle" - desc = "The support specialist: Aid your fellow operatives with this medical bundle. Contains a Donksoft machine gun, \ - a box of ammo, and a pair of magboots to rescue your friends in no-gravity environments." - item = /obj/item/storage/backpack/duffelbag/syndie/med/medicalbundle - cost = 15 // normally 20 - -/datum/uplink_item/nukeoffer/sniper - name = "Sniper bundle" - desc = "Elegant and refined: Contains a collapsed sniper rifle in an expensive carrying case, a hollow-point \ - a soporific knockout magazine, a free surplus supressor, and a worn out suit and tie." - item = /obj/item/storage/briefcase/sniperbundle - cost = 20 // normally 26 - -/datum/uplink_item/nukeoffer/chemical +/datum/uplink_item/bundles_TC/chemical name = "Bioterror bundle" desc = "For the madman: Contains Bioterror spray, Bioterror grenade, chemicals, syringe gun, box of syringes,\ Donksoft assault rifle, and some darts. Remember: Seal suit and equip internals before use." item = /obj/item/storage/backpack/duffelbag/syndie/med/bioterrorbundle cost = 30 // normally 42 + include_modes = list(/datum/game_mode/nuclear) -/datum/uplink_item/nukeoffer/firestarter +/datum/uplink_item/bundles_TC/bulldog + name = "Bulldog bundle" + desc = "Lean and mean: Optimised for people that want to get up close and personal. Contains the popular \ + Bulldog shotgun, two 12g drums, and a pair of Thermal imaging goggles." + item = /obj/item/storage/backpack/duffelbag/syndie/bulldogbundle + cost = 13 // normally 16 + include_modes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/bundles_TC/c20r + name = "C-20r bundle" + desc = "Old faithful: The classic C-20r, bundled with two magazines, and a (surplus) suppressor at discount price." + item = /obj/item/storage/backpack/duffelbag/syndie/c20rbundle + cost = 14 // normally 16 + include_modes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/bundles_TC/cybernetics_bundle + name = "Cybernetic Implants Bundle" + desc = "A random selection of cybernetic implants. Guaranteed 5 high quality implants. Comes with an autosurgeon." + item = /obj/item/storage/box/cyber_implants + cost = 40 + include_modes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/bundles_TC/medical + name = "Medical bundle" + desc = "The support specialist: Aid your fellow operatives with this medical bundle. Contains a Donksoft machine gun, \ + a box of ammo, and a pair of magboots to rescue your friends in no-gravity environments." + item = /obj/item/storage/backpack/duffelbag/syndie/med/medicalbundle + cost = 15 // normally 20 + include_modes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/bundles_TC/modular + name = "Modular Pistol Kit" + desc = "A heavy briefcase containing one modular pistol (chambered in 10mm), one supressor, and spare ammunition, including a box of soporific ammo. \ + Includes a suit jacket that is padded with a robust liner." + item = /obj/item/storage/briefcase/modularbundle + cost = 12 + +/datum/uplink_item/bundles_TC/shredder + name = "Shredder bundle" + desc = "A truly horrific weapon designed simply to maim its victim, the CX Shredder is banned by several intergalactic treaties. \ + You'll get two of them with this. And spare ammo to boot. And we'll throw in an extra elite hardsuit and chest rig to hold them all!" + item = /obj/item/storage/backpack/duffelbag/syndie/shredderbundle + cost = 30 // normally 41 + include_modes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/bundles_TC/sniper + name = "Sniper bundle" + desc = "Elegant and refined: Contains a collapsed sniper rifle in an expensive carrying case, a hollow-point \ + a soporific knockout magazine, a free surplus supressor, and a worn out suit and tie." + item = /obj/item/storage/briefcase/sniperbundle + cost = 20 // normally 26 + include_modes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/bundles_TC/firestarter name = "Spetsnaz Pyro bundle" desc = "For systematic suppression of carbon lifeforms in close range: Contains a specialist Pyrotechnic equipment, foreign pistol, two magazines, a pipebomb, and a stimulant syringe." item = /obj/item/storage/backpack/duffelbag/syndie/firestarter cost = 30 + include_modes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/bundles_TC/bundle + name = "Syndicate Bundle" + desc = "Syndicate Bundles are specialized groups of items that arrive in a plain box. \ + These items are collectively worth more than 20 telecrystals, but you do not know which specialization \ + you will receive." + item = /obj/item/storage/box/syndicate + cost = 20 + exclude_modes = list(/datum/game_mode/nuclear) + cant_discount = TRUE + +/datum/uplink_item/bundles_TC/surplus + name = "Syndicate Surplus Crate" + desc = "A dusty crate from the back of the Syndicate warehouse. Rumored to contain a valuable assortment of items, \ + but you never know. Contents are sorted to always be worth 50 TC." + item = /obj/structure/closet/crate + cost = 20 + player_minimum = 25 + exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + cant_discount = TRUE + var/starting_crate_value = 50 + +/datum/uplink_item/bundles_TC/surplus/super + name = "Super Surplus Crate" + desc = "A dusty SUPER-SIZED from the back of the Syndicate warehouse. Rumored to contain a valuable assortment of items, \ + but you never know. Contents are sorted to always be worth 125 TC." + cost = 40 + player_minimum = 40 + starting_crate_value = 125 + +/datum/uplink_item/bundles_TC/surplus/purchase(mob/user, datum/component/uplink/U) + var/list/uplink_items = get_uplink_items(SSticker && SSticker.mode? SSticker.mode : null, FALSE) + + var/crate_value = starting_crate_value + var/obj/structure/closet/crate/C = spawn_item(/obj/structure/closet/crate, user) + if(U.purchase_log) + U.purchase_log.LogPurchase(C, src, cost) + while(crate_value) + var/category = pick(uplink_items) + var/item = pick(uplink_items[category]) + var/datum/uplink_item/I = uplink_items[category][item] + + if(!I.surplus || prob(100 - I.surplus)) + continue + if(crate_value < I.cost) + continue + crate_value -= I.cost + var/obj/goods = new I.item(C) + if(U.purchase_log) + U.purchase_log.LogPurchase(goods, I, 0) + return C + +/datum/uplink_item/bundles_TC/random + name = "Random Item" + desc = "Picking this will purchase a random item. Useful if you have some TC to spare or if you haven't decided on a strategy yet." + item = /obj/effect/gibspawner/generic // non-tangible item because techwebs use this path to determine illegal tech + cost = 0 + cant_discount = TRUE + +/datum/uplink_item/bundles_TC/random/purchase(mob/user, datum/component/uplink/U) + var/list/uplink_items = U.uplink_items + var/list/possible_items = list() + for(var/category in uplink_items) + for(var/item in uplink_items[category]) + var/datum/uplink_item/I = uplink_items[category][item] + if(src == I || !I.item) + continue + if(U.telecrystals < I.cost) + continue + if(I.limited_stock == 0) + continue + possible_items += I + + if(possible_items.len) + var/datum/uplink_item/I = pick(possible_items) + SSblackbox.record_feedback("tally", "traitor_random_uplink_items_gotten", 1, initial(I.name)) + U.MakePurchase(user, I) + +/datum/uplink_item/bundles_TC/telecrystal + name = "1 Raw Telecrystal" + desc = "A telecrystal in its rawest and purest form; can be utilized on active uplinks to increase their telecrystal count." + item = /obj/item/stack/telecrystal + cost = 1 + surplus = 0 + cant_discount = TRUE + // Don't add telecrystals to the purchase_log since + // it's just used to buy more items (including itself!) + purchase_log_vis = FALSE + +/datum/uplink_item/bundles_TC/telecrystal/five + name = "5 Raw Telecrystals" + desc = "Five telecrystals in their rawest and purest form; can be utilized on active uplinks to increase their telecrystal count." + item = /obj/item/stack/telecrystal/five + cost = 5 + +/datum/uplink_item/bundles_TC/telecrystal/twenty + name = "20 Raw Telecrystals" + desc = "Twenty telecrystals in their rawest and purest form; can be utilized on active uplinks to increase their telecrystal count." + item = /obj/item/stack/telecrystal/twenty + cost = 20 // Dangerous Items /datum/uplink_item/dangerous category = "Conspicuous and Dangerous Weapons" -/datum/uplink_item/dangerous/pistol - name = "Stechkin Pistol" - desc = "A small, easily concealable handgun that uses 10mm auto rounds in 8-round magazines and is compatible \ - with suppressors." - item = /obj/item/gun/ballistic/automatic/pistol - cost = 7 - exclude_modes = list(/datum/game_mode/nuclear/clown_ops) - -/datum/uplink_item/dangerous/revolver - name = "Syndicate Revolver" - desc = "A brutally simple syndicate revolver that fires .357 Magnum rounds and has 7 chambers." - item = /obj/item/gun/ballistic/revolver - cost = 13 - surplus = 50 - exclude_modes = list(/datum/game_mode/nuclear/clown_ops) +/datum/uplink_item/dangerous/antitank + name = "Anti Tank Pistol" + desc = "Essentially amounting to a sniper rifle with no stock and barrel (or indeed, any rifling at all), \ + this extremely dubious pistol is guaranteed to dislocate your wrists and hit the broad side of a barn! \ + Uses sniper ammo. \ + Bullets tend to veer off-course. We are not responsible for any unintentional damage or injury resulting from inaacuracy." + item = /obj/item/gun/ballistic/automatic/pistol/antitank/syndicate + cost = 14 + surplus = 25 + include_modes = list(/datum/game_mode/nuclear) /datum/uplink_item/dangerous/pie_cannon name = "Banana Cream Pie Cannon" @@ -184,6 +306,42 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) surplus = 0 include_modes = list(/datum/game_mode/nuclear/clown_ops) +/datum/uplink_item/dangerous/bananashield + name = "Bananium Energy Shield" + desc = "A clown's most powerful defensive weapon, this personal shield provides near immunity to ranged energy attacks \ + by bouncing them back at the ones who fired them. It can also be thrown to bounce off of people, slipping them, \ + and returning to you even if you miss. WARNING: DO NOT ATTEMPT TO STAND ON SHIELD WHILE DEPLOYED, EVEN IF WEARING ANTI-SLIP SHOES." + item = /obj/item/shield/energy/bananium + cost = 16 + surplus = 0 + include_modes = list(/datum/game_mode/nuclear/clown_ops) + +/datum/uplink_item/dangerous/clownsword + name = "Bananium Energy Sword" + desc = "An energy sword that deals no damage, but will slip anyone it contacts, be it by melee attack, thrown \ + impact, or just stepping on it. Beware friendly fire, as even anti-slip shoes will not protect against it." + item = /obj/item/melee/transforming/energy/sword/bananium + cost = 3 + surplus = 0 + include_modes = list(/datum/game_mode/nuclear/clown_ops) + +/datum/uplink_item/dangerous/bioterror + name = "Biohazardous Chemical Sprayer" + desc = "A chemical sprayer that allows a wide dispersal of selected chemicals. Especially tailored by the Tiger \ + Cooperative, the deadly blend it comes stocked with will disorient, damage, and disable your foes... \ + Use with extreme caution, to prevent exposure to yourself and your fellow operatives." + item = /obj/item/reagent_containers/spray/chemsprayer/bioterror + cost = 20 + surplus = 0 + include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + +/datum/uplink_item/dangerous/throwingweapons + name = "Box of Throwing Weapons" + desc = "A box of shurikens and reinforced bolas from ancient Earth martial arts. They are highly effective \ + throwing weapons. The bolas can knock a target down and the shurikens will embed into limbs." + item = /obj/item/storage/box/syndie_kit/throwing_weapons + cost = 3 + /datum/uplink_item/dangerous/shotgun name = "Bulldog Shotgun" desc = "A fully-loaded semi-automatic drum-fed shotgun. Compatible with all 12g rounds. Designed for close \ @@ -202,86 +360,6 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) surplus = 40 include_modes = list(/datum/game_mode/nuclear) -/datum/uplink_item/dangerous/carbine - name = "M-90gl Carbine" - desc = "A fully-loaded, specialized three-round burst carbine that fires 5.56mm ammunition from a 30 round magazine \ - with a togglable 40mm under-barrel grenade launcher." - item = /obj/item/gun/ballistic/automatic/m90 - cost = 18 - surplus = 50 - include_modes = list(/datum/game_mode/nuclear) - -/datum/uplink_item/dangerous/machinegun - name = "L6 Squad Automatic Weapon" - desc = "A fully-loaded Aussec Armoury belt-fed machine gun. \ - This deadly weapon has a massive 50-round magazine of devastating 1.95x129mm ammunition." - item = /obj/item/gun/ballistic/automatic/l6_saw - cost = 18 - surplus = 0 - include_modes = list(/datum/game_mode/nuclear) - -/datum/uplink_item/dangerous/grenadier - name = "Grenadier's belt" - desc = "A belt of a large variety of lethally dangerous and destructive grenades." - item = /obj/item/storage/belt/grenade/full - include_modes = list(/datum/game_mode/nuclear) - cost = 22 - surplus = 0 - -/datum/uplink_item/dangerous/sniper - name = "Sniper Rifle" - desc = "Ranged fury, Syndicate style. Guaranteed to cause shock and awe or your TC back!" - item = /obj/item/gun/ballistic/automatic/sniper_rifle/syndicate - cost = 16 - surplus = 25 - include_modes = list(/datum/game_mode/nuclear) - -/datum/uplink_item/dangerous/bolt_action - name = "Surplus Rifle" - desc = "A horribly outdated bolt action weapon. You've got to be desperate to use this." - item = /obj/item/gun/ballistic/shotgun/boltaction - cost = 2 - include_modes = list(/datum/game_mode/nuclear) - -/datum/uplink_item/dangerous/crossbow - name = "Miniature Energy Crossbow" - desc = "A short bow mounted across a tiller in miniature. Small enough to \ - fit into a pocket or slip into a bag unnoticed. It will synthesize \ - and fire bolts tipped with a paralyzing toxin that will briefly stun \ - targets and cause them to slur as if inebriated. It can produce an \ - infinite number of bolts, but takes time to automatically recharge \ - after each shot." - item = /obj/item/gun/energy/kinetic_accelerator/crossbow - cost = 12 - surplus = 50 - exclude_modes = list(/datum/game_mode/nuclear) - -/datum/uplink_item/dangerous/flamethrower - name = "Flamethrower" - desc = "A flamethrower, fueled by a portion of highly flammable biotoxins stolen previously from Nanotrasen \ - stations. Make a statement by roasting the filth in their own greed. Use with caution." - item = /obj/item/flamethrower/full/tank - cost = 4 - surplus = 40 - include_modes = list(/datum/game_mode/nuclear) - -/datum/uplink_item/dangerous/sword - name = "Energy Sword" - desc = "The energy sword is an edged weapon with a blade of pure energy. The sword is small enough to be \ - pocketed when inactive. Activating it produces a loud, distinctive noise." - item = /obj/item/melee/transforming/energy/sword/saber - cost = 8 - exclude_modes = list(/datum/game_mode/nuclear/clown_ops) - -/datum/uplink_item/dangerous/clownsword - name = "Bananium Energy Sword" - desc = "An energy sword that deals no damage, but will slip anyone it contacts, be it by melee attack, thrown \ - impact, or just stepping on it. Beware friendly fire, as even anti-slip shoes will not protect against it." - item = /obj/item/melee/transforming/energy/sword/bananium - cost = 3 - surplus = 0 - include_modes = list(/datum/game_mode/nuclear/clown_ops) - /datum/uplink_item/dangerous/doublesword name = "Double-Bladed Energy Sword" desc = "The double-bladed energy sword does slightly more damage than a standard energy sword and will deflect \ @@ -294,6 +372,90 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) /datum/uplink_item/dangerous/doublesword/get_discount() return pick(4;0.8,2;0.65,1;0.5) +/datum/uplink_item/dangerous/cxneb + name = "Dragon's Tooth Non-Eutactic Blade" + desc = "An illegal modification of a weapon that is functionally identical to the energy sword, \ + the Non-Eutactic Blade (NEB) forges a hardlight blade on-demand, \ + generating an extremely sharp, unbreakable edge that is guaranteed to satisfy your every need. \ + This particular model has a polychromic hardlight generator, allowing you to murder in style! \ + The illegal modifications bring this weapon up to par with the classic energy sword, and also gives it the energy sword's distinctive sounds." + item = /obj/item/melee/transforming/energy/sword/cx/traitor + cost = 8 + +/datum/uplink_item/dangerous/sword + name = "Energy Sword" + desc = "The energy sword is an edged weapon with a blade of pure energy. The sword is small enough to be \ + pocketed when inactive. Activating it produces a loud, distinctive noise." + item = /obj/item/melee/transforming/energy/sword/saber + cost = 8 + exclude_modes = list(/datum/game_mode/nuclear/clown_ops) + +/datum/uplink_item/dangerous/shield + name = "Energy Shield" + desc = "An incredibly useful personal shield projector, capable of reflecting energy projectiles and defending \ + against other attacks. Pair with an Energy Sword for a killer combination." + item = /obj/item/shield/energy + cost = 16 + surplus = 20 + include_modes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/dangerous/flamethrower + name = "Flamethrower" + desc = "A flamethrower, fueled by a portion of highly flammable biotoxins stolen previously from Nanotrasen \ + stations. Make a statement by roasting the filth in their own greed. Use with caution." + item = /obj/item/flamethrower/full/tank + cost = 4 + surplus = 40 + include_modes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/dangerous/flechettegun + name = "Flechette Launcher" + desc = "A compact bullpup that fires micro-flechettes.\ + Flechettes have very poor performance idividually, but can be very deadly in numbers. \ + Pre-loaded with armor piercing flechettes that are capable of puncturing most kinds of armor." + item = /obj/item/gun/ballistic/automatic/flechette + cost = 12 + surplus = 30 + include_modes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/badass/rapid + name = "Gloves of the North Star" + desc = "These gloves let the user punch people very fast. Does not improve weapon attack speed or the meaty fists of a hulk." + item = /obj/item/clothing/gloves/rapid + cost = 8 + +/datum/uplink_item/dangerous/guardian + name = "Holoparasites" + desc = "Though capable of near sorcerous feats via use of hardlight holograms and nanomachines, they require an \ + organic host as a home base and source of fuel." + item = /obj/item/storage/box/syndie_kit/guardian + cost = 15 + refundable = TRUE + cant_discount = TRUE + surplus = 0 + exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + player_minimum = 25 + restricted = TRUE + refund_path = /obj/item/guardiancreator/tech/choose/traitor + +/datum/uplink_item/dangerous/machinegun + name = "L6 Squad Automatic Weapon" + desc = "A fully-loaded Aussec Armoury belt-fed machine gun. \ + This deadly weapon has a massive 50-round magazine of devastating 1.95x129mm ammunition." + item = /obj/item/gun/ballistic/automatic/l6_saw + cost = 18 + surplus = 0 + include_modes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/dangerous/carbine + name = "M-90gl Carbine" + desc = "A fully-loaded, specialized three-round burst carbine that fires 5.56mm ammunition from a 30 round magazine \ + with a togglable 40mm under-barrel grenade launcher." + item = /obj/item/gun/ballistic/automatic/m90 + cost = 18 + surplus = 50 + include_modes = list(/datum/game_mode/nuclear) + /datum/uplink_item/dangerous/powerfist name = "Power Fist" desc = "The power-fist is a metal gauntlet with a built-in piston-ram powered by an external gas supply.\ @@ -303,46 +465,36 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) item = /obj/item/melee/powerfist cost = 8 -/datum/uplink_item/badass/combatglovesplus - name = "Combat Gloves Plus" - desc = "A pair of gloves that are fireproof and shock resistant, however unlike the regular Combat Gloves this one uses nanotechnology \ - to learn the abilities of krav maga to the wearer." - item = /obj/item/clothing/gloves/krav_maga/combatglovesplus - cost = 5 - include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) +/datum/uplink_item/dangerous/sniper + name = "Sniper Rifle" + desc = "Ranged fury, Syndicate style. Guaranteed to cause shock and awe or your TC back!" + item = /obj/item/gun/ballistic/automatic/sniper_rifle/syndicate + cost = 16 + surplus = 25 + include_modes = list(/datum/game_mode/nuclear) -/datum/uplink_item/dangerous/emp - name = "EMP Grenades and Implanter Kit" - desc = "A box that contains two EMP grenades and an EMP implant. Useful to disrupt communication, \ - security's energy weapons, and silicon lifeforms when you're in a tight spot." - item = /obj/item/storage/box/syndie_kit/emp - cost = 2 - -/datum/uplink_item/dangerous/syndicate_minibomb - name = "Syndicate Minibomb" - desc = "The minibomb is a grenade with a five-second fuse. Upon detonation, it will create a small hull breach \ - in addition to dealing high amounts of damage to nearby personnel." - item = /obj/item/grenade/syndieminibomb - cost = 6 +/datum/uplink_item/dangerous/pistol + name = "Stechkin Pistol" + desc = "A small, easily concealable handgun that uses 10mm auto rounds in 8-round magazines and is compatible \ + with suppressors." + item = /obj/item/gun/ballistic/automatic/pistol + cost = 7 exclude_modes = list(/datum/game_mode/nuclear/clown_ops) -/datum/uplink_item/dangerous/bombanana - name = "Bombanana" - desc = "A banana with an explosive taste! discard the peel quickly, as it will explode with the force of a syndicate minibomb \ - a few seconds after the banana is eaten." - item = /obj/item/reagent_containers/food/snacks/grown/banana/bombanana - cost = 4 //it is a bit cheaper than a minibomb because you have to take off your helmet to eat it, which is how you arm it - surplus = 0 - include_modes = list(/datum/game_mode/nuclear/clown_ops) +/datum/uplink_item/dangerous/bolt_action + name = "Surplus Rifle" + desc = "A horribly outdated bolt action weapon. You've got to be desperate to use this." + item = /obj/item/gun/ballistic/shotgun/boltaction + cost = 2 + include_modes = list(/datum/game_mode/nuclear) -/datum/uplink_item/dangerous/tearstache - name = "Teachstache Grenade" - desc = "A teargas grenade that launches sticky moustaches onto the face of anyone not wearing a clown or mime mask. The moustaches will \ - remain attached to the face of all targets for one minute, preventing the use of breath masks and other such devices." - item = /obj/item/grenade/chem_grenade/teargas/moustache - cost = 3 - surplus = 0 - include_modes = list(/datum/game_mode/nuclear/clown_ops) +/datum/uplink_item/dangerous/revolver + name = "Syndicate Revolver" + desc = "A brutally simple syndicate revolver that fires .357 Magnum rounds and has 7 chambers." + item = /obj/item/gun/ballistic/revolver/syndie + cost = 13 + surplus = 50 + exclude_modes = list(/datum/game_mode/nuclear/clown_ops) /datum/uplink_item/dangerous/foamsmg name = "Toy Submachine Gun" @@ -361,65 +513,132 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) surplus = 0 include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) -/datum/uplink_item/dangerous/viscerators - name = "Viscerator Delivery Grenade" - desc = "A unique grenade that deploys a swarm of viscerators upon activation, which will chase down and shred \ - any non-operatives in the area." - item = /obj/item/grenade/spawnergrenade/manhacks - cost = 5 - surplus = 35 - include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) +/datum/uplink_item/dangerous/foampistol + name = "Toy Gun with Riot Darts" + desc = "An innocent-looking toy pistol designed to fire foam darts. Comes loaded with riot-grade \ + darts effective at incapacitating a target." + item = /obj/item/gun/ballistic/automatic/toy/pistol/riot + cost = 3 + surplus = 10 -/datum/uplink_item/dangerous/bioterrorfoam - name = "Chemical Foam Grenade" - desc = "A powerful chemical foam grenade which creates a deadly torrent of foam that will mute, blind, confuse, \ - mutate, and irritate carbon lifeforms. Specially brewed by Tiger Cooperative chemical weapons specialists \ - using additional spore toxin. Ensure suit is sealed before use." - item = /obj/item/grenade/chem_grenade/bioterrorfoam - cost = 5 - surplus = 35 - include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) +// Stealthy Weapons +/datum/uplink_item/stealthy_weapons + category = "Stealthy and Inconspicuous Weapons" -/datum/uplink_item/dangerous/bioterror - name = "Biohazardous Chemical Sprayer" - desc = "A chemical sprayer that allows a wide dispersal of selected chemicals. Especially tailored by the Tiger \ - Cooperative, the deadly blend it comes stocked with will disorient, damage, and disable your foes... \ - Use with extreme caution, to prevent exposure to yourself and your fellow operatives." - item = /obj/item/reagent_containers/spray/chemsprayer/bioterror - cost = 20 +/datum/uplink_item/stealthy_weapons/combatglovesplus + name = "Combat Gloves Plus" + desc = "A pair of gloves that are fireproof and shock resistant, however unlike the regular Combat Gloves this one uses nanotechnology \ + to learn the abilities of krav maga to the wearer." + item = /obj/item/clothing/gloves/krav_maga/combatglovesplus + cost = 5 + include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) surplus = 0 - include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) -/datum/uplink_item/stealthy_weapons/virus_grenade - name = "Fungal Tuberculosis Grenade" - desc = "A primed bio-grenade packed into a compact box. Comes with five Bio Virus Antidote Kit (BVAK) \ - autoinjectors for rapid application on up to two targets each, a syringe, and a bottle containing \ - the BVAK solution." - item = /obj/item/storage/box/syndie_kit/tuberculosisgrenade - cost = 8 - surplus = 35 +/datum/uplink_item/stealthy_weapons/cqc + name = "CQC Manual" + desc = "A manual that teaches a single user tactical Close-Quarters Combat before self-destructing." + item = /obj/item/book/granter/martial/cqc include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) - restricted = TRUE + cost = 13 + surplus = 0 -/datum/uplink_item/dangerous/guardian - name = "Holoparasites" - desc = "Though capable of near sorcerous feats via use of hardlight holograms and nanomachines, they require an \ - organic host as a home base and source of fuel." - item = /obj/item/storage/box/syndie_kit/guardian - cost = 18 +/datum/uplink_item/stealthy_weapons/dart_pistol + name = "Dart Pistol" + desc = "A miniaturized version of a normal syringe gun. It is very quiet when fired and can fit into any \ + space a small item can." + item = /obj/item/gun/syringe/syndicate + cost = 4 + surplus = 50 + +/datum/uplink_item/stealthy_weapons/dehy_carp + name = "Dehydrated Space Carp" + desc = "Looks like a plush toy carp, but just add water and it becomes a real-life space carp! Activate in \ + your hand before use so it knows not to kill you." + item = /obj/item/toy/plush/carpplushie/dehy_carp + cost = 1 + +/datum/uplink_item/stealthy_weapons/edagger + name = "Energy Dagger" + desc = "A dagger made of energy that looks and functions as a pen when off." + item = /obj/item/pen/edagger + cost = 2 + +/datum/uplink_item/stealthy_weapons/martialarts + name = "Martial Arts Scroll" + desc = "This scroll contains the secrets of an ancient martial arts technique. You will master unarmed combat, \ + deflecting all ranged weapon fire, but you also refuse to use dishonorable ranged weaponry." + item = /obj/item/book/granter/martial/carp + cost = 17 surplus = 0 exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) - player_minimum = 25 - restricted = TRUE -/datum/uplink_item/dangerous/buzzkill - name = "Buzzkill Grenade Box" - desc = "A box with three grenades that release a swarm of angry bees upon activation. These bees indiscriminately attack friend or foe \ - with random toxins. Courtesy of the BLF and Tiger Cooperative." - item = /obj/item/storage/box/syndie_kit/bee_grenades - cost = 15 - surplus = 35 - include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) +/datum/uplink_item/stealthy_weapons/crossbow + name = "Miniature Energy Crossbow" + desc = "A short bow mounted across a tiller in miniature. Small enough to \ + fit into a pocket or slip into a bag unnoticed. It will synthesize \ + and fire bolts tipped with a paralyzing toxin that will briefly stun \ + targets and cause them to slur as if inebriated. It can produce an \ + infinite number of bolts, but takes time to automatically recharge \ + after each shot." + item = /obj/item/gun/energy/kinetic_accelerator/crossbow + cost = 12 + surplus = 50 + exclude_modes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/stealthy_weapons/traitor_chem_bottle + name = "Poison Kit" + desc = "An assortment of deadly chemicals packed into a compact box. Comes with a syringe for more precise application." + item = /obj/item/storage/box/syndie_kit/chemical + cost = 6 + surplus = 50 + +/datum/uplink_item/stealthy_weapons/romerol_kit + name = "Romerol" + desc = "A highly experimental bioterror agent which creates dormant nodules to be etched into the grey matter of the brain. On death, these nodules take control of the dead body, causing limited revivification, along with slurred speech, aggression, and the ability to infect others with this agent." + item = /obj/item/storage/box/syndie_kit/romerol + cost = 25 + cant_discount = TRUE + exclude_modes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/stealthy_weapons/sleepy_pen + name = "Sleepy Pen" + desc = "A syringe disguised as a functional pen, filled with a potent mix of drugs, including a \ + strong anesthetic and a chemical that prevents the target from speaking. \ + The pen holds one dose of the mixture, and can be refilled. Note that before the target \ + falls asleep, they will be able to move and act." + item = /obj/item/pen/sleepy + cost = 4 + exclude_modes = list(/datum/game_mode/nuclear) + +datum/uplink_item/stealthy_weapons/taeclowndo_shoes + name = "Tae-clown-do Shoes" + desc = "A pair of shoes for the most elite agents of the honkmotherland. They grant the mastery of taeclowndo with some honk-fu moves as long as they're worn." + cost = 12 + item = /obj/item/clothing/shoes/clown_shoes/taeclowndo + include_modes = list(/datum/game_mode/nuclear/clown_ops) + +/datum/uplink_item/stealthy_weapons/suppressor + name = "Universal Suppressor" + desc = "Fitted for use on any small caliber weapon with a threaded barrel, this suppressor will silence the \ + shots of the weapon for increased stealth and superior ambushing capability." + item = /obj/item/suppressor + cost = 1 + surplus = 10 + exclude_modes = list(/datum/game_mode/nuclear/clown_ops) + +/datum/uplink_item/stealthy_weapons/soap + name = "Syndicate Soap" + desc = "A sinister-looking surfactant used to clean blood stains to hide murders and prevent DNA analysis. \ + You can also drop it underfoot to slip people." + item = /obj/item/soap/syndie + cost = 1 + surplus = 50 + +/datum/uplink_item/stealthy_weapons/soap_clusterbang + name = "Slipocalypse Clusterbang" + desc = "A traditional clusterbang grenade with a payload consisting entirely of Syndicate soap. Useful in any scenario!" + item = /obj/item/grenade/clusterbuster/soap + cost = 6 // Ammunition /datum/uplink_item/ammo @@ -441,13 +660,6 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) cost = 2 exclude_modes = list(/datum/game_mode/nuclear/clown_ops) -/datum/uplink_item/ammo/pistolfire - name = "10mm Incendiary Magazine" - desc = "An additional 8-round 10mm magazine; compatible with the Stechkin Pistol. Loaded with incendiary rounds which ignite the target." - item = /obj/item/ammo_box/magazine/m10mm/fire - cost = 2 - exclude_modes = list(/datum/game_mode/nuclear/clown_ops) - /datum/uplink_item/ammo/pistolhp name = "10mm Hollow Point Magazine" desc = "An additional 8-round 10mm magazine; compatible with the Stechkin Pistol. These rounds are more damaging but ineffective against armour." @@ -455,51 +667,35 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) cost = 3 exclude_modes = list(/datum/game_mode/nuclear/clown_ops) -/datum/uplink_item/ammo/pistolaps - name = "9mm Handgun Magazine" - desc = "An additional 15-round 9mm magazine, compatible with the Stetchkin APS pistol, found in the Spetsnaz Pyro bundle." - item = /obj/item/ammo_box/magazine/pistolm9mm +/datum/uplink_item/ammo/pistolfire + name = "10mm Incendiary Magazine" + desc = "An additional 8-round 10mm magazine; compatible with the Stechkin Pistol. Loaded with incendiary rounds which ignite the target." + item = /obj/item/ammo_box/magazine/m10mm/fire cost = 2 - include_modes = list(/datum/game_mode/nuclear) - -/datum/uplink_item/ammo/bolt_action - name = "Surplus Rifle Clip" - desc = "A stripper clip used to quickly load bolt action rifles. Contains 5 rounds." - item = /obj/item/ammo_box/a762 - cost = 1 - include_modes = list(/datum/game_mode/nuclear) - -/datum/uplink_item/ammo/revolver - name = ".357 Speed Loader" - desc = "A speed loader that contains seven additional .357 Magnum rounds; usable with the Syndicate revolver. \ - For when you really need a lot of things dead." - item = /obj/item/ammo_box/a357 - cost = 4 exclude_modes = list(/datum/game_mode/nuclear/clown_ops) +/datum/uplink_item/ammo/pistolzzz + name = "10mm Soporific Magazine" + desc = "An additional 8-round 10mm magazine; compatible with the Stechkin Pistol. Loaded with soporific rounds that put the target to sleep. \ + NOTE: Soporific is not instant acting due to the constraints of the round's scale. Will usually require three shots to take effect." + item = /obj/item/ammo_box/magazine/m10mm/soporific + cost = 2 + /datum/uplink_item/ammo/shotgun cost = 2 include_modes = list(/datum/game_mode/nuclear) +/datum/uplink_item/ammo/shotgun/bag + name = "12g Ammo Duffel Bag" + desc = "A duffel bag filled with enough 12g ammo to supply an entire team, at a discounted price." + item = /obj/item/storage/backpack/duffelbag/syndie/ammo/shotgun + cost = 12 + /datum/uplink_item/ammo/shotgun/buck name = "12g Buckshot Drum" desc = "An additional 8-round buckshot magazine for use with the Bulldog shotgun. Front towards enemy." item = /obj/item/ammo_box/magazine/m12g -/datum/uplink_item/ammo/shotgun/slug - name = "12g Slug Drum" - desc = "An additional 8-round slug magazine for use with the Bulldog shotgun. \ - Now 8 times less likely to shoot your pals." - cost = 3 - item = /obj/item/ammo_box/magazine/m12g/slug - -/datum/uplink_item/ammo/shotgun/stun - name = "12g Stun Slug Drum" - desc = "An alternative 8-round stun slug magazine for use with the Bulldog shotgun. \ - Saying that they're completely non-lethal would be lying." - item = /obj/item/ammo_box/magazine/m12g/stun - include_modes = list(/datum/game_mode/nuclear) - /datum/uplink_item/ammo/shotgun/dragon name = "12g Dragon's Breath Drum" desc = "An alternative 8-round dragon's breath magazine for use in the Bulldog shotgun. \ @@ -520,18 +716,34 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) item = /obj/item/ammo_box/magazine/m12g/scatter cost = 4 // most armor has less laser protection then bullet -/datum/uplink_item/ammo/shotgun/bag - name = "12g Ammo Duffel Bag" - desc = "A duffel bag filled with enough 12g ammo to supply an entire team, at a discounted price." - item = /obj/item/storage/backpack/duffelbag/syndie/ammo/shotgun - cost = 12 - -/datum/uplink_item/ammo/smg - name = ".45 SMG Magazine" - desc = "An additional 24-round .45 magazine suitable for use with the C-20r submachine gun. \ - These bullets pack a lot of punch that can knock most targets down, but do limited overall damage." - item = /obj/item/ammo_box/magazine/smgm45 +/datum/uplink_item/ammo/shotgun/slug + name = "12g Slug Drum" + desc = "An additional 8-round slug magazine for use with the Bulldog shotgun. \ + Now 8 times less likely to shoot your pals." cost = 3 + item = /obj/item/ammo_box/magazine/m12g/slug + +/datum/uplink_item/ammo/shotgun/stun + name = "12g Stun Slug Drum" + desc = "An alternative 8-round stun slug magazine for use with the Bulldog shotgun. \ + Saying that they're completely non-lethal would be lying." + item = /obj/item/ammo_box/magazine/m12g/stun + include_modes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/ammo/revolver + name = ".357 Speed Loader" + desc = "A speed loader that contains seven additional .357 Magnum rounds; usable with the Syndicate revolver. \ + For when you really need a lot of things dead." + item = /obj/item/ammo_box/a357 + cost = 4 + exclude_modes = list(/datum/game_mode/nuclear/clown_ops) + +/datum/uplink_item/ammo/a40mm + name = "40mm Grenade" + desc = "A 40mm HE grenade for use with the M-90gl's under-barrel grenade launcher. \ + Your teammates will ask you to not shoot these down small hallways." + item = /obj/item/ammo_casing/a40mm + cost = 2 include_modes = list(/datum/game_mode/nuclear) /datum/uplink_item/ammo/smg/bag @@ -541,6 +753,36 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) cost = 20 include_modes = list(/datum/game_mode/nuclear) +/datum/uplink_item/ammo/smg + name = ".45 SMG Magazine" + desc = "An additional 24-round .45 magazine suitable for use with the C-20r submachine gun. \ + These bullets pack a lot of punch that can knock most targets down, but do limited overall damage." + item = /obj/item/ammo_box/magazine/smgm45 + cost = 3 + include_modes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/ammo/sniper + cost = 4 + include_modes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/ammo/sniper/basic + name = ".50 Magazine" + desc = "An additional standard 6-round magazine for use with .50 sniper rifles." + item = /obj/item/ammo_box/magazine/sniper_rounds + +/datum/uplink_item/ammo/sniper/penetrator + name = ".50 Penetrator Magazine" + desc = "A 5-round magazine of penetrator ammo designed for use with .50 sniper rifles. \ + Can pierce walls and multiple enemies." + item = /obj/item/ammo_box/magazine/sniper_rounds/penetrator + cost = 5 + +/datum/uplink_item/ammo/sniper/soporific + name = ".50 Soporific Magazine" + desc = "A 3-round magazine of soporific ammo designed for use with .50 sniper rifles. Put your enemies to sleep today!" + item = /obj/item/ammo_box/magazine/sniper_rounds/soporific + cost = 6 + /datum/uplink_item/ammo/carbine name = "5.56mm Toploader Magazine" desc = "An additional 30-round 5.56mm magazine; suitable for use with the M-90gl carbine. \ @@ -549,14 +791,6 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) cost = 4 include_modes = list(/datum/game_mode/nuclear) -/datum/uplink_item/ammo/a40mm - name = "40mm Grenade" - desc = "A 40mm HE grenade for use with the M-90gl's under-barrel grenade launcher. \ - Your teammates will ask you to not shoot these down small hallways." - item = /obj/item/ammo_casing/a40mm - cost = 2 - include_modes = list(/datum/game_mode/nuclear) - /datum/uplink_item/ammo/machinegun cost = 6 surplus = 0 @@ -568,12 +802,6 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) By the time you need to use this, you'll already be on a pile of corpses." item = /obj/item/ammo_box/magazine/mm195x129 -/datum/uplink_item/ammo/machinegun/hollow - name = "1.95x129mm (Hollow-Point) Box Magazine" - desc = "A 50-round magazine of 1.95x129mm ammunition for use in the L6 SAW; equipped with hollow-point tips to help \ - with the unarmored masses of crew." - item = /obj/item/ammo_box/magazine/mm195x129/hollow - /datum/uplink_item/ammo/machinegun/ap name = "1.95x129mm (Armor Penetrating) Box Magazine" desc = "A 50-round magazine of 1.95x129mm ammunition for use in the L6 SAW; equipped with special properties \ @@ -581,33 +809,41 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) item = /obj/item/ammo_box/magazine/mm195x129/ap cost = 9 +/datum/uplink_item/ammo/machinegun/hollow + name = "1.95x129mm (Hollow-Point) Box Magazine" + desc = "A 50-round magazine of 1.95x129mm ammunition for use in the L6 SAW; equipped with hollow-point tips to help \ + with the unarmored masses of crew." + item = /obj/item/ammo_box/magazine/mm195x129/hollow + /datum/uplink_item/ammo/machinegun/incen name = "1.95x129mm (Incendiary) Box Magazine" desc = "A 50-round magazine of 1.95x129mm ammunition for use in the L6 SAW; tipped with a special flammable \ mixture that'll ignite anyone struck by the bullet. Some men just want to watch the world burn." item = /obj/item/ammo_box/magazine/mm195x129/incen -/datum/uplink_item/ammo/sniper - cost = 4 +/datum/uplink_item/ammo/pistolaps + name = "9mm Handgun Magazine" + desc = "An additional 15-round 9mm magazine, compatible with the Stetchkin APS pistol, found in the Spetsnaz Pyro bundle." + item = /obj/item/ammo_box/magazine/pistolm9mm + cost = 2 include_modes = list(/datum/game_mode/nuclear) -/datum/uplink_item/ammo/sniper/basic - name = ".50 Magazine" - desc = "An additional standard 6-round magazine for use with .50 sniper rifles." - item = /obj/item/ammo_box/magazine/sniper_rounds +/datum/uplink_item/ammo/flechetteap + name = "Armor Piercing Flechette Magazine" + desc = "An additional 40-round flechette magazine; compatible with the Flechette Launcer. \ + Loaded with armor piercing flechettes that very nearly ignore armor, but are not very effective agaisnt flesh." + item = /obj/item/ammo_box/magazine/flechette + cost = 2 + include_modes = list(/datum/game_mode/nuclear) -/datum/uplink_item/ammo/sniper/soporific - name = ".50 Soporific Magazine" - desc = "A 3-round magazine of soporific ammo designed for use with .50 sniper rifles. Put your enemies to sleep today!" - item = /obj/item/ammo_box/magazine/sniper_rounds/soporific - cost = 6 - -/datum/uplink_item/ammo/sniper/penetrator - name = ".50 Penetrator Magazine" - desc = "A 5-round magazine of penetrator ammo designed for use with .50 sniper rifles. \ - Can pierce walls and multiple enemies." - item = /obj/item/ammo_box/magazine/sniper_rounds/penetrator - cost = 5 +/datum/uplink_item/ammo/flechettes + name = "Serrated Flechette Magazine" + desc = "An additional 40-round flechette magazine; compatible with the Flechette Launcer. \ + Loaded with serrated flechettes that shreds flesh, but is stopped dead in its tracks by armor. \ + These flechettes are highly likely to sever arteries, and even limbs." + item = /obj/item/ammo_box/magazine/flechette/s + cost = 2 + include_modes = list(/datum/game_mode/nuclear) /datum/uplink_item/ammo/toydarts name = "Box of Riot Darts" @@ -624,12 +860,184 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) cost = 6 include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) +/datum/uplink_item/ammo/bolt_action + name = "Surplus Rifle Clip" + desc = "A stripper clip used to quickly load bolt action rifles. Contains 5 rounds." + item = /obj/item/ammo_box/a762 + cost = 1 + include_modes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/explosives + category = "Grenades and Explosives" + +/datum/uplink_item/explosives/bioterrorfoam + name = "Chemical Foam Grenade" + desc = "A powerful chemical foam grenade which creates a deadly torrent of foam that will mute, blind, confuse, \ + mutate, and irritate carbon lifeforms. Specially brewed by Tiger Cooperative chemical weapons specialists \ + using additional spore toxin. Ensure suit is sealed before use." + item = /obj/item/grenade/chem_grenade/bioterrorfoam + cost = 5 + surplus = 35 + include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + +/datum/uplink_item/explosives/bombanana + name = "Bombanana" + desc = "A banana with an explosive taste! discard the peel quickly, as it will explode with the force of a syndicate minibomb \ + a few seconds after the banana is eaten." + item = /obj/item/reagent_containers/food/snacks/grown/banana/bombanana + cost = 4 //it is a bit cheaper than a minibomb because you have to take off your helmet to eat it, which is how you arm it + surplus = 0 + include_modes = list(/datum/game_mode/nuclear/clown_ops) + +/datum/uplink_item/explosives/buzzkill + name = "Buzzkill Grenade Box" + desc = "A box with three grenades that release a swarm of angry bees upon activation. These bees indiscriminately attack friend or foe \ + with random toxins. Courtesy of the BLF and Tiger Cooperative." + item = /obj/item/storage/box/syndie_kit/bee_grenades + cost = 15 + surplus = 35 + include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + +/datum/uplink_item/explosives/c4 + name = "Composition C-4" + 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/grenade/plastic/c4 + cost = 1 + +/datum/uplink_item/explosives/c4bag + name = "Bag of C-4 explosives" + desc = "Because sometimes quantity is quality. Contains 10 C-4 plastic explosives." + item = /obj/item/storage/backpack/duffelbag/syndie/c4 + cost = 9 //10% discount! + cant_discount = TRUE + +/datum/uplink_item/explosives/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/storage/backpack/duffelbag/syndie/x4 + cost = 4 // + cant_discount = TRUE + +/datum/uplink_item/explosives/clown_bomb_clownops + name = "Clown Bomb" + desc = "The Clown bomb is a hilarious device capable of massive pranks. It has an adjustable timer, \ + with a minimum of 60 seconds, and can be bolted to the floor with a wrench to prevent \ + movement. The bomb is bulky and cannot be moved; upon ordering this item, a smaller beacon will be \ + transported to you that will teleport the actual bomb to it upon activation. Note that this bomb can \ + be defused, and some crew may attempt to do so." + item = /obj/item/sbeacondrop/clownbomb + cost = 15 + surplus = 0 + include_modes = list(/datum/game_mode/nuclear/clown_ops) + +/datum/uplink_item/explosives/detomatix + name = "Detomatix PDA Cartridge" + desc = "When inserted into a personal digital assistant, this cartridge gives you four opportunities to \ + detonate PDAs of crewmembers who have their message feature enabled. \ + The concussive effect from the explosion will knock the recipient out for a short period, and deafen \ + them for longer. Beware, it has a chance to detonate your PDA." + item = /obj/item/cartridge/virus/syndicate + cost = 5 + restricted = TRUE + +/datum/uplink_item/explosives/emp + name = "EMP Grenades and Implanter Kit" + desc = "A box that contains two EMP grenades and an EMP implant. Useful to disrupt communication, \ + security's energy weapons, and silicon lifeforms when you're in a tight spot." + item = /obj/item/storage/box/syndie_kit/emp + cost = 2 + +/datum/uplink_item/explosives/virus_grenade + name = "Fungal Tuberculosis Grenade" + desc = "A primed bio-grenade packed into a compact box. Comes with five Bio Virus Antidote Kit (BVAK) \ + autoinjectors for rapid application on up to two targets each, a syringe, and a bottle containing \ + the BVAK solution." + item = /obj/item/storage/box/syndie_kit/tuberculosisgrenade + cost = 8 + surplus = 35 + include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + restricted = TRUE + +/datum/uplink_item/explosives/grenadier + name = "Grenadier's belt" + desc = "A belt of a large variety of lethally dangerous and destructive grenades." + item = /obj/item/storage/belt/grenade/full + include_modes = list(/datum/game_mode/nuclear) + cost = 22 + surplus = 0 + +/datum/uplink_item/explosives/pizza_bomb + name = "Pizza Bomb" + desc = "A pizza box with a bomb cunningly attached to the lid. The timer needs to be set by opening the box; afterwards, \ + opening the box again will trigger the detonation after the timer has elapsed. Comes with free pizza, for you or your target!" + item = /obj/item/pizzabox/bomb + cost = 6 + surplus = 8 + +/datum/uplink_item/explosives/syndicate_bomb + name = "Syndicate Bomb" + desc = "The Syndicate bomb is a fearsome device capable of massive destruction. It has an adjustable timer, \ + with a minimum of 60 seconds, and can be bolted to the floor with a wrench to prevent \ + movement. The bomb is bulky and cannot be moved; upon ordering this item, a smaller beacon will be \ + transported to you that will teleport the actual bomb to it upon activation. Note that this bomb can \ + be defused, and some crew may attempt to do so." + item = /obj/item/sbeacondrop/bomb + cost = 11 + +/datum/uplink_item/explosives/syndicate_detonator + name = "Syndicate Detonator" + desc = "The Syndicate detonator is a companion device to the Syndicate bomb. Simply press the included button \ + and an encrypted radio frequency will instruct all live Syndicate bombs to detonate. \ + Useful for when speed matters or you wish to synchronize multiple bomb blasts. Be sure to stand clear of \ + the blast radius before using the detonator." + item = /obj/item/syndicatedetonator + cost = 3 + include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + +/datum/uplink_item/explosives/syndicate_minibomb + name = "Syndicate Minibomb" + desc = "The minibomb is a grenade with a five-second fuse. Upon detonation, it will create a small hull breach \ + in addition to dealing high amounts of damage to nearby personnel." + item = /obj/item/grenade/syndieminibomb + cost = 6 + exclude_modes = list(/datum/game_mode/nuclear/clown_ops) + +/datum/uplink_item/explosives/tearstache + name = "Teachstache Grenade" + desc = "A teargas grenade that launches sticky moustaches onto the face of anyone not wearing a clown or mime mask. The moustaches will \ + remain attached to the face of all targets for one minute, preventing the use of breath masks and other such devices." + item = /obj/item/grenade/chem_grenade/teargas/moustache + cost = 3 + surplus = 0 + include_modes = list(/datum/game_mode/nuclear/clown_ops) + +/datum/uplink_item/explosives/viscerators + name = "Viscerator Delivery Grenade" + desc = "A unique grenade that deploys a swarm of viscerators upon activation, which will chase down and shred \ + any non-operatives in the area." + item = /obj/item/grenade/spawnergrenade/manhacks + cost = 5 + surplus = 35 + include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + + //Support and Mechs /datum/uplink_item/support category = "Support and Mechanized Exosuits" surplus = 0 include_modes = list(/datum/game_mode/nuclear) +/datum/uplink_item/support/clown_reinforcement + name = "Clown Reinforcements" + desc = "Call in an additional clown to share the fun, equipped with full starting gear, but no telecrystals." + item = /obj/item/antag_spawner/nuke_ops/clown + cost = 20 + include_modes = list(/datum/game_mode/nuclear/clown_ops) + restricted = TRUE + /datum/uplink_item/support/reinforcement name = "Reinforcements" desc = "Call in an additional team member. They won't come with any gear, so you'll have to save some telecrystals \ @@ -664,13 +1072,6 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) item = /obj/mecha/combat/gygax/dark/loaded cost = 80 -/datum/uplink_item/support/mauler - name = "Mauler Exosuit" - desc = "A massive and incredibly deadly military-grade exosuit. Features long-range targeting, thrust vectoring, \ - and deployable smoke." - item = /obj/mecha/combat/marauder/mauler/loaded - cost = 140 - /datum/uplink_item/support/honker name = "Dark H.O.N.K." desc = "A clown combat mech equipped with bombanana peel and tearstache grenade launchers, as well as the ubiquitous HoNkER BlAsT 5000." @@ -678,141 +1079,36 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) cost = 80 include_modes = list(/datum/game_mode/nuclear/clown_ops) -/datum/uplink_item/support/clown_reinforcement - name = "Clown Reinforcements" - desc = "Call in an additional clown to share the fun, equipped with full starting gear, but no telecrystals." - item = /obj/item/antag_spawner/nuke_ops/clown - cost = 20 - include_modes = list(/datum/game_mode/nuclear/clown_ops) - restricted = TRUE - -// Stealthy Weapons -/datum/uplink_item/stealthy_weapons - category = "Stealthy and Inconspicuous Weapons" - -/datum/uplink_item/stealthy_weapons/martialarts - name = "Martial Arts Scroll" - desc = "This scroll contains the secrets of an ancient martial arts technique. You will master unarmed combat, \ - deflecting all ranged weapon fire, but you also refuse to use dishonorable ranged weaponry." - item = /obj/item/book/granter/martial/carp - cost = 17 - surplus = 0 - exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) - -/datum/uplink_item/stealthy_weapons/cqc - name = "CQC Manual" - desc = "A manual that teaches a single user tactical Close-Quarters Combat before self-destructing." - item = /obj/item/book/granter/martial/cqc - include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) - cost = 13 - surplus = 0 - -/datum/uplink_item/stealthy_weapons/throwingweapons - name = "Box of Throwing Weapons" - desc = "A box of shurikens and reinforced bolas from ancient Earth martial arts. They are highly effective \ - throwing weapons. The bolas can knock a target down and the shurikens will embed into limbs." - item = /obj/item/storage/box/syndie_kit/throwing_weapons - cost = 3 - -/datum/uplink_item/stealthy_weapons/edagger - name = "Energy Dagger" - desc = "A dagger made of energy that looks and functions as a pen when off." - item = /obj/item/pen/edagger - cost = 2 - -/datum/uplink_item/stealthy_weapons/foampistol - name = "Toy Gun with Riot Darts" - desc = "An innocent-looking toy pistol designed to fire foam darts. Comes loaded with riot-grade \ - darts effective at incapacitating a target." - item = /obj/item/gun/ballistic/automatic/toy/pistol/riot - cost = 3 - surplus = 10 - -/datum/uplink_item/stealthy_weapons/sleepy_pen - name = "Sleepy Pen" - desc = "A syringe disguised as a functional pen, filled with a potent mix of drugs, including a \ - strong anesthetic and a chemical that prevents the target from speaking. \ - The pen holds one dose of the mixture, and can be refilled. Note that before the target \ - falls asleep, they will be able to move and act." - item = /obj/item/pen/sleepy - cost = 4 - exclude_modes = list(/datum/game_mode/nuclear) - -/datum/uplink_item/stealthy_weapons/soap - name = "Syndicate Soap" - desc = "A sinister-looking surfactant used to clean blood stains to hide murders and prevent DNA analysis. \ - You can also drop it underfoot to slip people." - item = /obj/item/soap/syndie - cost = 1 - surplus = 50 - -/datum/uplink_item/stealthy_weapons/traitor_chem_bottle - name = "Poison Kit" - desc = "An assortment of deadly chemicals packed into a compact box. Comes with a syringe for more precise application." - item = /obj/item/storage/box/syndie_kit/chemical - cost = 6 - surplus = 50 - -/datum/uplink_item/stealthy_weapons/romerol_kit - name = "Romerol" - desc = "A highly experimental bioterror agent which creates dormant nodules to be etched into the grey matter of the brain. On death, these nodules take control of the dead body, causing limited revivification, along with slurred speech, aggression, and the ability to infect others with this agent." - item = /obj/item/storage/box/syndie_kit/romerol - cost = 25 - cant_discount = TRUE - exclude_modes = list(/datum/game_mode/nuclear) - -/datum/uplink_item/stealthy_weapons/dart_pistol - name = "Dart Pistol" - desc = "A miniaturized version of a normal syringe gun. It is very quiet when fired and can fit into any \ - space a small item can." - item = /obj/item/gun/syringe/syndicate - cost = 4 - surplus = 50 - -/datum/uplink_item/stealthy_weapons/detomatix - name = "Detomatix PDA Cartridge" - desc = "When inserted into a personal digital assistant, this cartridge gives you four opportunities to \ - detonate PDAs of crewmembers who have their message feature enabled. \ - The concussive effect from the explosion will knock the recipient out for a short period, and deafen \ - them for longer. Beware, it has a chance to detonate your PDA." - item = /obj/item/cartridge/virus/syndicate - cost = 5 - restricted = TRUE - -/datum/uplink_item/stealthy_weapons/suppressor - name = "Universal Suppressor" - desc = "Fitted for use on any small caliber weapon with a threaded barrel, this suppressor will silence the \ - shots of the weapon for increased stealth and superior ambushing capability." - item = /obj/item/suppressor - cost = 1 - surplus = 10 - exclude_modes = list(/datum/game_mode/nuclear/clown_ops) - -/datum/uplink_item/stealthy_weapons/pizza_bomb - name = "Pizza Bomb" - desc = "A pizza box with a bomb cunningly attached to the lid. The timer needs to be set by opening the box; afterwards, \ - opening the box again will trigger the detonation after the timer has elapsed. Comes with free pizza, for you or your target!" - item = /obj/item/pizzabox/bomb - cost = 6 - surplus = 8 - -/datum/uplink_item/stealthy_weapons/dehy_carp - name = "Dehydrated Space Carp" - desc = "Looks like a plush toy carp, but just add water and it becomes a real-life space carp! Activate in \ - your hand before use so it knows not to kill you." - item = /obj/item/toy/plush/carpplushie/dehy_carp - cost = 1 - -/datum/uplink_item/stealthy_weapons/soap_clusterbang - name = "Slipocalypse Clusterbang" - desc = "A traditional clusterbang grenade with a payload consisting entirely of Syndicate soap. Useful in any scenario!" - item = /obj/item/grenade/clusterbuster/soap - cost = 6 +/datum/uplink_item/support/mauler + name = "Mauler Exosuit" + desc = "A massive and incredibly deadly military-grade exosuit. Features long-range targeting, thrust vectoring, \ + and deployable smoke." + item = /obj/mecha/combat/marauder/mauler/loaded + cost = 140 // Stealth Items /datum/uplink_item/stealthy_tools category = "Stealth and Camouflage Items" +/datum/uplink_item/stealthy_tools/agent_card + name = "Agent Identification Card" + desc = "Agent cards prevent artificial intelligences from tracking the wearer, and can copy access \ + from other identification cards. The access is cumulative, so scanning one card does not erase the \ + access gained from another. In addition, they can be forged to display a new assignment and name. \ + This can be done an unlimited amount of times. Some Syndicate areas and devices can only be accessed \ + with these cards." + item = /obj/item/card/id/syndicate + cost = 2 + +/datum/uplink_item/stealthy_tools/ai_detector + name = "Artificial Intelligence Detector" + desc = "A functional multitool that turns red when it detects an artificial intelligence watching it, and can be \ + activated to display their exact viewing location and nearby security camera blind spots. Knowing when \ + an artificial intelligence is watching you is useful for knowing when to maintain cover, and finding nearby \ + blind spots can help you identify escape routes." + item = /obj/item/multitool/ai_detect + cost = 1 + /datum/uplink_item/stealthy_tools/chameleon name = "Chameleon Kit" desc = "A set of items that contain chameleon technology allowing you to disguise as pretty much anything on the station, and more!" @@ -820,6 +1116,46 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) cost = 2 exclude_modes = list(/datum/game_mode/nuclear) +/datum/uplink_item/stealthy_tools/chameleon_proj + name = "Chameleon Projector" + desc = "Projects an image across a user, disguising them as an object scanned with it, as long as they don't \ + move the projector from their hand. Disguised users move slowly, and projectiles pass over them." + item = /obj/item/chameleon + cost = 7 + +/datum/uplink_item/stealthy_tools/codespeak_manual + name = "Codespeak Manual" + desc = "Syndicate agents can be trained to use a series of codewords to convey complex information, which sounds like random concepts and drinks to anyone listening. This manual teaches you this Codespeak. You can also hit someone else with the manual in order to teach them. This is the deluxe edition, which has unlimited used." + item = /obj/item/codespeak_manual/unlimited + cost = 3 + +/datum/uplink_item/stealthy_tools/combatbananashoes + name = "Combat Banana Shoes" + desc = "While making the wearer immune to most slipping attacks like regular combat clown shoes, these shoes \ + can generate a large number of synthetic banana peels as the wearer walks, slipping up would-be pursuers. They also \ + squeak significantly louder." + item = /obj/item/clothing/shoes/clown_shoes/banana_shoes/combat + cost = 6 + surplus = 0 + include_modes = list(/datum/game_mode/nuclear/clown_ops) + +/datum/uplink_item/stealthy_tools/emplight + name = "EMP Flashlight" + desc = "A small, self-charging, short-ranged EMP device disguised as a flashlight. \ + Useful for disrupting headsets, cameras, and borgs during stealth operations." + item = /obj/item/flashlight/emp + cost = 2 + surplus = 30 + +/datum/uplink_item/stealthy_tools/mulligan + name = "Mulligan" + desc = "Screwed up and have security on your tail? This handy syringe will give you a completely new identity \ + and appearance." + item = /obj/item/reagent_containers/syringe/mulligan + cost = 3 + surplus = 30 + exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + /datum/uplink_item/stealthy_tools/syndigaloshes name = "No-Slip Chameleon Shoes" desc = "These shoes will allow the wearer to run on wet floors and slippery objects without falling down. \ @@ -835,57 +1171,22 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) exclude_modes = list() include_modes = list(/datum/game_mode/nuclear) -/datum/uplink_item/stealthy_tools/combatbananashoes - name = "Combat Banana Shoes" - desc = "While making the wearer immune to most slipping attacks like regular combat clown shoes, these shoes \ - can generate a large number of synthetic banana peels as the wearer walks, slipping up would-be pursuers. They also \ - squeak significantly louder." - item = /obj/item/clothing/shoes/clown_shoes/banana_shoes/combat - cost = 6 - surplus = 0 - include_modes = list(/datum/game_mode/nuclear/clown_ops) +/datum/uplink_item/stealthy_tools/jammer + name = "Radio Jammer" + desc = "This device will disrupt any nearby outgoing radio communication when activated." + item = /obj/item/jammer + cost = 5 -datum/uplink_item/stealthy_tools/taeclowndo_shoes - name = "Tae-clown-do Shoes" - desc = "A pair of shoes for the most elite agents of the honkmotherland. They grant the mastery of taeclowndo with some honk-fu moves as long as they're worn." - cost = 12 - item = /obj/item/clothing/shoes/clown_shoes/taeclowndo - include_modes = list(/datum/game_mode/nuclear/clown_ops) - -/datum/uplink_item/stealthy_tools/frame - name = "F.R.A.M.E. PDA Cartridge" - desc = "When inserted into a personal digital assistant, this cartridge gives you five PDA viruses which \ - when used cause the targeted PDA to become a new uplink with zero TCs, and immediately become unlocked. \ - You will receive the unlock code upon activating the virus, and the new uplink may be charged with \ - telecrystals normally." - item = /obj/item/cartridge/virus/frame - cost = 2 - restricted = TRUE - -/datum/uplink_item/stealthy_tools/agent_card - name = "Agent Identification Card" - desc = "Agent cards prevent artificial intelligences from tracking the wearer, and can copy access \ - from other identification cards. The access is cumulative, so scanning one card does not erase the \ - access gained from another. In addition, they can be forged to display a new assignment and name. \ - This can be done an unlimited amount of times. Some Syndicate areas and devices can only be accessed \ - with these cards." - item = /obj/item/card/id/syndicate - cost = 2 - -/datum/uplink_item/stealthy_tools/chameleon_proj - name = "Chameleon Projector" - desc = "Projects an image across a user, disguising them as an object scanned with it, as long as they don't \ - move the projector from their hand. Disguised users move slowly, and projectiles pass over them." - item = /obj/item/chameleon - cost = 7 - -/datum/uplink_item/stealthy_tools/camera_bug - name = "Camera Bug" - desc = "Enables you to view all cameras on the network and track a target. Bugging cameras allows you \ - to disable them remotely." - item = /obj/item/camera_bug - cost = 1 - surplus = 90 +/*/datum/uplink_item/stealthy_tools/syndi_borer + name = "Syndicate Brain Slug" + desc = "A small cortical borer, modified to be completely loyal to the owner. \ + Genetically infertile, these brain slugs can assist medically in a support role, or take direct action \ + to assist their host." + item = /obj/item/antag_spawner/syndi_borer + refundable = TRUE + cost = 10 + surplus = 20 //Let's not have this be too common + exclude_modes = list(/datum/game_mode/nuclear) */ /datum/uplink_item/stealthy_tools/smugglersatchel name = "Smuggler's Satchel" @@ -896,46 +1197,6 @@ datum/uplink_item/stealthy_tools/taeclowndo_shoes cost = 2 surplus = 30 -/datum/uplink_item/stealthy_tools/stimpack - name = "Stimpack" - desc = "Stimpacks, the tool of many great heroes, make you nearly immune to stuns and knockdowns for about \ - 5 minutes after injection." - item = /obj/item/reagent_containers/syringe/stimulants - cost = 5 - surplus = 90 - -/datum/uplink_item/stealthy_tools/mulligan - name = "Mulligan" - desc = "Screwed up and have security on your tail? This handy syringe will give you a completely new identity \ - and appearance." - item = /obj/item/reagent_containers/syringe/mulligan - cost = 3 - surplus = 30 - exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) - -/datum/uplink_item/stealthy_tools/emplight - name = "EMP Flashlight" - desc = "A small, self-charging, short-ranged EMP device disguised as a flashlight. \ - Useful for disrupting headsets, cameras, and borgs during stealth operations." - item = /obj/item/flashlight/emp - cost = 2 - surplus = 30 - -/datum/uplink_item/stealthy_tools/cutouts - name = "Adaptive Cardboard Cutouts" - desc = "These cardboard cutouts are coated with a thin material that prevents discoloration and makes the images on them appear more lifelike. This pack contains three as well as a \ - crayon for changing their appearances." - item = /obj/item/storage/box/syndie_kit/cutouts - cost = 1 - surplus = 20 - -/datum/uplink_item/stealthy_tools/fakenucleardisk - name = "Decoy Nuclear Authentication Disk" - desc = "It's just a normal disk. Visually it's identical to the real deal, but it won't hold up under closer scrutiny by the Captain. Don't try to give this to us to complete your objective, we know better!" - item = /obj/item/disk/nuclear/fake - cost = 1 - surplus = 1 - //Space Suits and Hardsuits /datum/uplink_item/suits category = "Space Suits and Hardsuits" @@ -982,6 +1243,74 @@ datum/uplink_item/stealthy_tools/taeclowndo_shoes /datum/uplink_item/device_tools category = "Devices and Tools" +/datum/uplink_item/device_tools/cutouts + name = "Adaptive Cardboard Cutouts" + desc = "These cardboard cutouts are coated with a thin material that prevents discoloration and makes the images on them appear more lifelike. This pack contains three as well as a \ + crayon for changing their appearances." + item = /obj/item/storage/box/syndie_kit/cutouts + cost = 1 + surplus = 20 + +/datum/uplink_item/device_tools/assault_pod + name = "Assault Pod Targeting Device" + desc = "Use to select the landing zone of your assault pod." + item = /obj/item/assault_pod + cost = 30 + surplus = 0 + include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + restricted = TRUE + +/datum/uplink_item/device_tools/binary + name = "Binary Translator Key" + desc = "A key that, when inserted into a radio headset, allows you to listen to and talk with silicon-based lifeforms, \ + such as AI units and cyborgs, over their private binary channel. Caution should \ + be taken while doing this, as unless they are allied with you, they are programmed to report such intrusions." + item = /obj/item/encryptionkey/binary + cost = 2 + surplus = 75 + restricted = TRUE + +/datum/uplink_item/device_tools/magboots + name = "Blood-Red Magboots" + desc = "A pair of magnetic boots with a Syndicate paintjob that assist with freer movement in space or on-station \ + during gravitational generator failures. These reverse-engineered knockoffs of Nanotrasen's \ + 'Advanced Magboots' slow you down in simulated-gravity environments much like the standard issue variety." + item = /obj/item/clothing/shoes/magboots/syndie + cost = 2 + include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + +/datum/uplink_item/device_tools/compressionkit + name = "Bluespace Compression Kit" + desc = "A modified version of a BSRPED that can be used to reduce the size of most items while retaining their original functions! \ + Does not work on storage items. \ + Recharge using bluespace crystals. \ + Comes with 5 charges." + item = /obj/item/compressionkit + cost = 5 + +/datum/uplink_item/device_tools/briefcase_launchpad + name = "Briefcase Launchpad" + desc = "A briefcase containing a launchpad, a device able to teleport items and people to and from targets up to twenty tiles away from the briefcase. \ + Also includes a remote control, disguised as an ordinary folder. Touch the briefcase with the remote to link it." + surplus = 0 + item = /obj/item/storage/briefcase/launchpad + cost = 6 + +/datum/uplink_item/device_tools/camera_bug + name = "Camera Bug" + desc = "Enables you to view all cameras on the network and track a target. Bugging cameras allows you \ + to disable them remotely." + item = /obj/item/camera_bug + cost = 1 + surplus = 90 + +/datum/uplink_item/device_tools/military_belt + name = "Chest Rig" + desc = "A robust seven-slot set of webbing that is capable of holding all manner of tactical equipment." + item = /obj/item/storage/belt/military + cost = 1 + exclude_modes = list(/datum/game_mode/nuclear) + /datum/uplink_item/device_tools/emag name = "Cryptographic Sequencer" desc = "The cryptographic sequencer, electromagnetic card, or emag, is a small card that unlocks hidden functions \ @@ -989,6 +1318,29 @@ datum/uplink_item/stealthy_tools/taeclowndo_shoes item = /obj/item/card/emag cost = 6 +/datum/uplink_item/device_tools/emagrecharge + name = "Electromagnet Charging Device" + desc = "A small device intended for recharging Cryptographic Sequencers. Using it will add five extra charges to the Cryptographic Sequencer." + item = /obj/item/emagrecharge + cost = 2 + +/datum/uplink_item/device_tools/fakenucleardisk + name = "Decoy Nuclear Authentication Disk" + desc = "It's just a normal disk. Visually it's identical to the real deal, but it won't hold up under closer scrutiny by the Captain. Don't try to give this to us to complete your objective, we know better!" + item = /obj/item/disk/nuclear/fake + cost = 1 + surplus = 1 + +/datum/uplink_item/device_tools/frame + name = "F.R.A.M.E. PDA Cartridge" + desc = "When inserted into a personal digital assistant, this cartridge gives you five PDA viruses which \ + when used cause the targeted PDA to become a new uplink with zero TCs, and immediately become unlocked. \ + You will receive the unlock code upon activating the virus, and the new uplink may be charged with \ + telecrystals normally." + item = /obj/item/cartridge/virus/frame + cost = 2 + restricted = TRUE + /datum/uplink_item/device_tools/toolbox name = "Full Syndicate Toolbox" desc = "The syndicate toolbox is a suspicious black and red. It comes loaded with a full tool set including a \ @@ -996,12 +1348,28 @@ datum/uplink_item/stealthy_tools/taeclowndo_shoes item = /obj/item/storage/toolbox/syndicate cost = 1 -/datum/uplink_item/device_tools/surgerybag - name = "Syndicate Surgery Duffel Bag" - desc = "The Syndicate surgery duffel bag is a toolkit containing all surgery tools, surgical drapes, \ - a Syndicate brand MMI, a straitjacket, and a muzzle." - item = /obj/item/storage/backpack/duffelbag/syndie/surgery - cost = 3 +/datum/uplink_item/device_tools/syndie_glue + name = "Glue" + desc = "A cheap bottle of one use syndicate brand super glue. \ + Use on any item to make it undroppable. \ + Be careful not to glue an item you're already holding!" + item = /obj/item/syndie_glue + cost = 2 + +/datum/uplink_item/device_tools/hacked_module + name = "Hacked AI Law Upload Module" + desc = "When used with an upload console, this module allows you to upload priority laws to an artificial intelligence. \ + Be careful with wording, as artificial intelligences may look for loopholes to exploit." + item = /obj/item/aiModule/syndicate + cost = 9 + +/datum/uplink_item/device_tools/medgun + name = "Medbeam Gun" + desc = "A wonder of Syndicate engineering, the Medbeam gun, or Medi-Gun enables a medic to keep his fellow \ + operatives in the fight, even while under fire." + item = /obj/item/gun/medbeam + cost = 15 + include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) /datum/uplink_item/device_tools/nutcracker name = "Nutcracker" @@ -1009,19 +1377,39 @@ datum/uplink_item/stealthy_tools/taeclowndo_shoes item = /obj/item/nutcracker cost = 1 -/datum/uplink_item/device_tools/surgerybag_adv - name = "Advanced Syndicate Surgery Duffel Bag" - desc = "The Syndicate surgery duffel bag is a toolkit containing all newest surgery tools, surgical drapes, \ - a Syndicate brand MMI, a straitjacket, a muzzle, and a full Syndicate Combat Medic Kit." - item = /obj/item/storage/backpack/duffelbag/syndie/surgery_adv - cost = 10 +/datum/uplink_item/device_tools/singularity_beacon + name = "Power Beacon" + desc = "When screwed to wiring attached to an electric grid and activated, this large device pulls any \ + active gravitational singularities or tesla balls towards it. This will not work when the engine is still \ + in containment. Because of its size, it cannot be carried. Ordering this \ + sends you a small beacon that will teleport the larger beacon to your location upon activation." + item = /obj/item/sbeacondrop + cost = 14 -/datum/uplink_item/device_tools/military_belt - name = "Chest Rig" - desc = "A robust seven-slot set of webbing that is capable of holding all manner of tactical equipment." - item = /obj/item/storage/belt/military - cost = 1 - exclude_modes = list(/datum/game_mode/nuclear) +/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 \ + load on the grid, causing a station-wide blackout. The sink is large and cannot be stored in most \ + traditional bags and boxes." + item = /obj/item/powersink + cost = 6 + +/datum/uplink_item/device_tools/rad_laser + name = "Radioactive Microlaser" + desc = "A radioactive microlaser disguised as a standard Nanotrasen health analyzer. When used, it emits a \ + powerful burst of radiation, which, after a short delay, can incapacitate all but the most protected \ + of humanoids. It has two settings: intensity, which controls the power of the radiation, \ + and wavelength, which controls how long the radiation delay is." + item = /obj/item/healthanalyzer/rad_laser + cost = 3 + +/datum/uplink_item/device_tools/stimpack + name = "Stimpack" + desc = "Stimpacks, the tool of many great heroes, make you nearly immune to stuns and knockdowns for about \ + 5 minutes after injection." + item = /obj/item/reagent_containers/syringe/stimulants + cost = 5 + surplus = 90 /datum/uplink_item/device_tools/medkit name = "Syndicate Combat Medic Kit" @@ -1032,6 +1420,29 @@ datum/uplink_item/stealthy_tools/taeclowndo_shoes cost = 4 include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) +/datum/uplink_item/device_tools/surgerybag + name = "Syndicate Surgery Duffel Bag" + desc = "The Syndicate surgery duffel bag is a toolkit containing all surgery tools, surgical drapes, \ + a Syndicate brand MMI, a straitjacket, and a muzzle." + item = /obj/item/storage/backpack/duffelbag/syndie/surgery + cost = 3 + +/datum/uplink_item/device_tools/surgerybag_adv + name = "Advanced Syndicate Surgery Duffel Bag" + desc = "The Syndicate surgery duffel bag is a toolkit containing all newest surgery tools, surgical drapes, \ + a Syndicate brand MMI, a straitjacket, a muzzle, and a full Syndicate Combat Medic Kit." + item = /obj/item/storage/backpack/duffelbag/syndie/surgery_adv + cost = 10 + +/datum/uplink_item/device_tools/encryptionkey + name = "Syndicate Encryption Key" + desc = "A key that, when inserted into a radio headset, allows you to listen to all station department channels \ + as well as talk on an encrypted Syndicate channel with other agents that have the same key." + item = /obj/item/encryptionkey/syndicate + cost = 2 + surplus = 75 + restricted = TRUE + /datum/uplink_item/device_tools/syndietome name = "Syndicate Tome" desc = "Using rare artifacts acquired at great cost, the syndicate has reverse engineered \ @@ -1050,175 +1461,6 @@ datum/uplink_item/stealthy_tools/taeclowndo_shoes item = /obj/item/clothing/glasses/thermal/syndi cost = 4 -/datum/uplink_item/device_tools/binary - name = "Binary Translator Key" - desc = "A key that, when inserted into a radio headset, allows you to listen to and talk with silicon-based lifeforms, \ - such as AI units and cyborgs, over their private binary channel. Caution should \ - be taken while doing this, as unless they are allied with you, they are programmed to report such intrusions." - item = /obj/item/encryptionkey/binary - cost = 2 - surplus = 75 - restricted = TRUE - -/datum/uplink_item/device_tools/encryptionkey - name = "Syndicate Encryption Key" - desc = "A key that, when inserted into a radio headset, allows you to listen to all station department channels \ - as well as talk on an encrypted Syndicate channel with other agents that have the same key." - item = /obj/item/encryptionkey/syndicate - cost = 2 - surplus = 75 - restricted = TRUE - -/datum/uplink_item/device_tools/ai_detector - name = "Artificial Intelligence Detector" - desc = "A functional multitool that turns red when it detects an artificial intelligence watching it, and can be \ - activated to display their exact viewing location and nearby security camera blind spots. Knowing when \ - an artificial intelligence is watching you is useful for knowing when to maintain cover, and finding nearby \ - blind spots can help you identify escape routes." - item = /obj/item/multitool/ai_detect - cost = 1 - -/datum/uplink_item/device_tools/hacked_module - name = "Hacked AI Law Upload Module" - desc = "When used with an upload console, this module allows you to upload priority laws to an artificial intelligence. \ - Be careful with wording, as artificial intelligences may look for loopholes to exploit." - item = /obj/item/aiModule/syndicate - cost = 9 - -/datum/uplink_item/device_tools/briefcase_launchpad - name = "Briefcase Launchpad" - desc = "A briefcase containing a launchpad, a device able to teleport items and people to and from targets up to twenty tiles away from the briefcase. \ - Also includes a remote control, disguised as an ordinary folder. Touch the briefcase with the remote to link it." - surplus = 0 - item = /obj/item/storage/briefcase/launchpad - cost = 6 - -/datum/uplink_item/device_tools/magboots - name = "Blood-Red Magboots" - desc = "A pair of magnetic boots with a Syndicate paintjob that assist with freer movement in space or on-station \ - during gravitational generator failures. These reverse-engineered knockoffs of Nanotrasen's \ - 'Advanced Magboots' slow you down in simulated-gravity environments much like the standard issue variety." - item = /obj/item/clothing/shoes/magboots/syndie - cost = 2 - include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) - -/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, 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/grenade/plastic/c4 - cost = 1 - -/datum/uplink_item/device_tools/c4bag - name = "Bag of C-4 explosives" - desc = "Because sometimes quantity is quality. Contains 10 C-4 plastic explosives." - item = /obj/item/storage/backpack/duffelbag/syndie/c4 - cost = 9 //10% discount! - cant_discount = TRUE - -/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/storage/backpack/duffelbag/syndie/x4 - cost = 4 // - cant_discount = TRUE - -/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 \ - load on the grid, causing a station-wide blackout. The sink is large and cannot be stored in most \ - traditional bags and boxes." - item = /obj/item/powersink - cost = 6 - -/datum/uplink_item/device_tools/singularity_beacon - name = "Power Beacon" - desc = "When screwed to wiring attached to an electric grid and activated, this large device pulls any \ - active gravitational singularities or tesla balls towards it. This will not work when the engine is still \ - in containment. Because of its size, it cannot be carried. Ordering this \ - sends you a small beacon that will teleport the larger beacon to your location upon activation." - item = /obj/item/sbeacondrop - cost = 14 - -/datum/uplink_item/device_tools/syndicate_bomb - name = "Syndicate Bomb" - desc = "The Syndicate bomb is a fearsome device capable of massive destruction. It has an adjustable timer, \ - with a minimum of 60 seconds, and can be bolted to the floor with a wrench to prevent \ - movement. The bomb is bulky and cannot be moved; upon ordering this item, a smaller beacon will be \ - transported to you that will teleport the actual bomb to it upon activation. Note that this bomb can \ - be defused, and some crew may attempt to do so." - item = /obj/item/sbeacondrop/bomb - cost = 11 - -/datum/uplink_item/device_tools/clown_bomb_clownops - name = "Clown Bomb" - desc = "The Clown bomb is a hilarious device capable of massive pranks. It has an adjustable timer, \ - with a minimum of 60 seconds, and can be bolted to the floor with a wrench to prevent \ - movement. The bomb is bulky and cannot be moved; upon ordering this item, a smaller beacon will be \ - transported to you that will teleport the actual bomb to it upon activation. Note that this bomb can \ - be defused, and some crew may attempt to do so." - item = /obj/item/sbeacondrop/clownbomb - cost = 15 - surplus = 0 - include_modes = list(/datum/game_mode/nuclear/clown_ops) - -/datum/uplink_item/device_tools/syndicate_detonator - name = "Syndicate Detonator" - desc = "The Syndicate detonator is a companion device to the Syndicate bomb. Simply press the included button \ - and an encrypted radio frequency will instruct all live Syndicate bombs to detonate. \ - Useful for when speed matters or you wish to synchronize multiple bomb blasts. Be sure to stand clear of \ - the blast radius before using the detonator." - item = /obj/item/syndicatedetonator - cost = 3 - include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) - -/datum/uplink_item/device_tools/rad_laser - name = "Radioactive Microlaser" - desc = "A radioactive microlaser disguised as a standard Nanotrasen health analyzer. When used, it emits a \ - powerful burst of radiation, which, after a short delay, can incapacitate all but the most protected \ - of humanoids. It has two settings: intensity, which controls the power of the radiation, \ - and wavelength, which controls how long the radiation delay is." - item = /obj/item/healthanalyzer/rad_laser - cost = 3 - -/datum/uplink_item/device_tools/assault_pod - name = "Assault Pod Targeting Device" - desc = "Use to select the landing zone of your assault pod." - item = /obj/item/assault_pod - cost = 30 - surplus = 0 - include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) - restricted = TRUE - -/datum/uplink_item/device_tools/shield - name = "Energy Shield" - desc = "An incredibly useful personal shield projector, capable of reflecting energy projectiles and defending \ - against other attacks. Pair with an Energy Sword for a killer combination." - item = /obj/item/shield/energy - cost = 16 - surplus = 20 - include_modes = list(/datum/game_mode/nuclear) - -/datum/uplink_item/device_tools/bananashield - name = "Bananium Energy Shield" - desc = "A clown's most powerful defensive weapon, this personal shield provides near immunity to ranged energy attacks \ - by bouncing them back at the ones who fired them. It can also be thrown to bounce off of people, slipping them, \ - and returning to you even if you miss. WARNING: DO NOT ATTEMPT TO STAND ON SHIELD WHILE DEPLOYED, EVEN IF WEARING ANTI-SLIP SHOES." - item = /obj/item/shield/energy/bananium - cost = 16 - surplus = 0 - include_modes = list(/datum/game_mode/nuclear/clown_ops) - -/datum/uplink_item/device_tools/medgun - name = "Medbeam Gun" - desc = "A wonder of Syndicate engineering, the Medbeam gun, or Medi-Gun enables a medic to keep his fellow \ - operatives in the fight, even while under fire." - item = /obj/item/gun/medbeam - cost = 15 - include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) - /datum/uplink_item/device_tools/potion name = "Syndicate Sentience Potion" item = /obj/item/slimepotion/slime/sentience/nuclear @@ -1227,79 +1469,12 @@ datum/uplink_item/stealthy_tools/taeclowndo_shoes include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) restricted = TRUE -/datum/uplink_item/device_tools/telecrystal - name = "Raw Telecrystal" - desc = "A telecrystal in its rawest and purest form; can be utilized on active uplinks to increase their telecrystal count." - item = /obj/item/stack/telecrystal - cost = 1 - surplus = 0 - cant_discount = TRUE - // Don't add telecrystals to the purchase_log since - // it's just used to buy more items (including itself!) - purchase_log_vis = FALSE - -/datum/uplink_item/device_tools/telecrystal/five - name = "5 Raw Telecrystals" - desc = "Five telecrystals in their rawest and purest form; can be utilized on active uplinks to increase their telecrystal count." - item = /obj/item/stack/telecrystal/five - cost = 5 - -/datum/uplink_item/device_tools/telecrystal/twenty - name = "20 Raw Telecrystals" - desc = "Twenty telecrystals in their rawest and purest form; can be utilized on active uplinks to increase their telecrystal count." - item = /obj/item/stack/telecrystal/twenty - cost = 20 - -/datum/uplink_item/device_tools/jammer - name = "Radio Jammer" - desc = "This device will disrupt any nearby outgoing radio communication when activated." - item = /obj/item/jammer - cost = 5 - -/datum/uplink_item/device_tools/codespeak_manual - name = "Codespeak Manual" - desc = "Syndicate agents can be trained to use a series of codewords to convey complex information, which sounds like random concepts and drinks to anyone listening. This manual teaches you this Codespeak. You can also hit someone else with the manual in order to teach them. This is the deluxe edition, which has unlimited used." - item = /obj/item/codespeak_manual/unlimited - cost = 3 - -/datum/uplink_item/device_tools/compressionkit - name = "Bluespace Compression Kit" - desc = "A modified version of a BSRPED that can be used to reduce the size of most items while retaining their original functions! \ - Does not work on storage items. \ - Recharge using bluespace crystals. \ - Comes with 5 charges." - item = /obj/item/compressionkit - cost = 5 - -/datum/uplink_item/device_tools/syndie_glue - name = "Glue" - desc = "A cheap bottle of one use syndicate brand super glue. \ - Use on any item to make it undroppable. \ - Be careful not to glue an item you're already holding!" - item = /obj/item/syndie_glue - cost = 2 // Implants /datum/uplink_item/implants category = "Implants" surplus = 50 -/datum/uplink_item/implants/freedom - name = "Freedom Implant" - desc = "An implant injected into the body and later activated at the user's will. It will attempt to free the \ - user from common restraints such as handcuffs." - item = /obj/item/storage/box/syndie_kit/imp_freedom - cost = 5 - -/datum/uplink_item/implants/uplink - name = "Uplink Implant" - desc = "An implant injected into the body, and later activated at the user's will. Has no telecrystals, must be charged by the use of physical telecrystals. Undetectable (except via surgery), and excellent for escaping confinement." - item = /obj/item/storage/box/syndie_kit/imp_uplink - cost = 4 - // An empty uplink is kinda useless. - surplus = 0 - restricted = TRUE - /datum/uplink_item/implants/adrenal name = "Adrenal Implant" desc = "An implant injected into the body, and later activated at the user's will. It will inject a chemical \ @@ -1308,12 +1483,19 @@ datum/uplink_item/stealthy_tools/taeclowndo_shoes cost = 8 player_minimum = 25 -/datum/uplink_item/implants/storage - name = "Storage Implant" - desc = "An implant injected into the body, and later activated at the user's will. It will open a small bluespace \ - pocket capable of storing two items." - item = /obj/item/storage/box/syndie_kit/imp_storage - cost = 8 +/datum/uplink_item/implants/antistun + name = "CNS Rebooter Implant" + desc = "This implant will help you get back up on your feet faster after being stunned. Comes with an autosurgeon." + item = /obj/item/autosurgeon/anti_stun + cost = 12 + include_modes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/implants/freedom + name = "Freedom Implant" + desc = "An implant injected into the body and later activated at the user's will. It will attempt to free the \ + user from common restraints such as handcuffs." + item = /obj/item/storage/box/syndie_kit/imp_freedom + cost = 5 /datum/uplink_item/implants/microbomb name = "Microbomb Implant" @@ -1340,48 +1522,49 @@ datum/uplink_item/stealthy_tools/taeclowndo_shoes cost = 4 restricted = TRUE +/datum/uplink_item/implants/reviver + name = "Reviver Implant" + desc = "This implant will attempt to revive you if you lose consciousness. Comes with an autosurgeon." + item = /obj/item/autosurgeon/reviver + cost = 8 + include_modes = list(/datum/game_mode/nuclear) + /datum/uplink_item/implants/stealthimplant name = "Stealth Implant" desc = "This one-of-a-kind implant will make you almost invisible if you play your cards right." item = /obj/item/implanter/stealth cost = 8 -// Cybernetics -/datum/uplink_item/cyber_implants - category = "Cybernetic Implants" - surplus = 0 - include_modes = list(/datum/game_mode/nuclear) +/datum/uplink_item/implants/storage + name = "Storage Implant" + desc = "An implant injected into the body, and later activated at the user's will. It will open a small bluespace \ + pocket capable of storing two items." + item = /obj/item/storage/box/syndie_kit/imp_storage + cost = 8 -/datum/uplink_item/cyber_implants/thermals +/datum/uplink_item/implants/thermals name = "Thermal Eyes" desc = "These cybernetic eyes will give you thermal vision. Comes with a free autosurgeon." item = /obj/item/autosurgeon/thermal_eyes cost = 8 + include_modes = list(/datum/game_mode/nuclear) -/datum/uplink_item/cyber_implants/xray +/datum/uplink_item/implants/uplink + name = "Uplink Implant" + desc = "An implant injected into the body, and later activated at the user's will. Has no telecrystals, must be charged by the use of physical telecrystals. Undetectable (except via surgery), and excellent for escaping confinement." + item = /obj/item/storage/box/syndie_kit/imp_uplink + cost = 4 + // An empty uplink is kinda useless. + surplus = 0 + restricted = TRUE + +/datum/uplink_item/implants/xray name = "X-ray Vision Implant" desc = "These cybernetic eyes will give you X-ray vision. Comes with an autosurgeon." item = /obj/item/autosurgeon/xray_eyes 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. Comes with an autosurgeon." - item = /obj/item/autosurgeon/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. Comes with an autosurgeon." - item = /obj/item/autosurgeon/reviver - cost = 8 - -/datum/uplink_item/cyber_implants/bundle - name = "Cybernetic Implants Bundle" - desc = "A random selection of cybernetic implants. Guaranteed 5 high quality implants. Comes with an autosurgeon." - item = /obj/item/storage/box/cyber_implants - cost = 40 - cant_discount = TRUE + surplus = 0 + include_modes = list(/datum/game_mode/nuclear) // Role-specific items /datum/uplink_item/role_restricted @@ -1389,23 +1572,62 @@ datum/uplink_item/stealthy_tools/taeclowndo_shoes exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) surplus = 0 -/datum/uplink_item/role_restricted/reverse_revolver - name = "Reverse Revolver" - desc = "A revolver that always fires at its user. \"Accidentally\" drop your weapon, then watch as the greedy corporate pigs blow their own brains all over the wall. \ - The revolver itself is actually real. Only clumsy people, and clowns, can fire it normally. Comes in a box of hugs. Honk." - cost = 14 - item = /obj/item/storage/box/hug/reverse_revolver +/datum/uplink_item/role_restricted/ancient_jumpsuit + name = "Ancient Jumpsuit" + desc = "A tattered old jumpsuit that will provide absolutely no benefit to you. It fills the wearer with a strange compulsion to blurt out 'glorf'." + item = /obj/item/clothing/under/color/grey/glorf + cost = 20 + restricted_roles = list("Assistant") + +/datum/uplink_item/role_restricted/pie_cannon + name = "Banana Cream Pie Cannon" + desc = "A special pie cannon for a special clown, this gadget can hold up to 20 pies and automatically fabricates one every two seconds!" + cost = 10 + item = /obj/item/pneumatic_cannon/pie/selfcharge restricted_roles = list("Clown") -/datum/uplink_item/role_restricted/reverse_bear_trap - name = "Reverse Bear Trap" - desc = "An ingenious execution device worn on (or forced onto) the head. Arming it starts a 1-minute kitchen timer mounted on the bear trap. When it goes off, the trap's jaws will \ - violently open, instantly killing anyone wearing it by tearing their jaws in half. To arm, attack someone with it while they're not wearing headgear, and you will force it onto their \ - head after three seconds uninterrupted." - cost = 5 - item = /obj/item/reverse_bear_trap +/datum/uplink_item/role_restricted/blastcannon + name = "Blast Cannon" + desc = "A highly specialized weapon, the Blast Cannon is actually relatively simple. It contains an attachment for a tank transfer valve mounted to an angled pipe specially constructed \ + withstand extreme pressure and temperatures, and has a mechanical trigger for triggering the transfer valve. Essentially, it turns the explosive force of a bomb into a narrow-angle \ + blast wave \"projectile\". Aspiring scientists may find this highly useful, as forcing the pressure shockwave into a narrow angle seems to be able to bypass whatever quirk of physics \ + disallows explosive ranges above a certain distance, allowing for the device to use the theoretical yield of a transfer valve bomb, instead of the factual yield." + item = /obj/item/gun/blastcannon + cost = 14 //High cost because of the potential for extreme damage in the hands of a skilled gas masked scientist. + restricted_roles = list("Research Director", "Scientist") + +/datum/uplink_item/role_restricted/brainwash_disk + name = "Brainwashing Surgery Program" + desc = "A disk containing the procedure to perform a brainwashing surgery, allowing you to implant an objective onto a target. \ + Insert into an Operating Console to enable the procedure." + item = /obj/item/disk/surgery/brainwashing + restricted_roles = list("Medical Doctor") + cost = 3 + +/datum/uplink_item/role_restricted/clown_bomb + name = "Clown Bomb" + desc = "The Clown bomb is a hilarious device capable of massive pranks. It has an adjustable timer, \ + with a minimum of 60 seconds, and can be bolted to the floor with a wrench to prevent \ + movement. The bomb is bulky and cannot be moved; upon ordering this item, a smaller beacon will be \ + transported to you that will teleport the actual bomb to it upon activation. Note that this bomb can \ + be defused, and some crew may attempt to do so." + item = /obj/item/sbeacondrop/clownbomb + cost = 15 restricted_roles = list("Clown") +/* +/datum/uplink_item/role_restricted/clowncar + name = "Clown Car" + desc = "The Clown Car is the ultimate transportation method for any worthy clown! \ + Simply insert your bikehorn and get in, and get ready to have the funniest ride of your life! \ + You can ram any spacemen you come across and stuff them into your car, kidnapping them and locking them inside until \ + someone saves them or they manage to crawl out. Be sure not to ram into any walls or vending machines, as the springloaded seats \ + are very sensetive. Now with our included lube defense mechanism which will protect you against any angry shitcurity!" + item = /obj/vehicle/sealed/car/clowncar + cost = 15 + restricted_roles = list("Clown") +*/ + /datum/uplink_item/role_restricted/clumsyDNA name = "Clumsy Clown DNA" desc = "A DNA injector that has been loaded with the clown gene that makes people clumsy.. \ @@ -1414,19 +1636,31 @@ datum/uplink_item/stealthy_tools/taeclowndo_shoes item = /obj/item/dnainjector/clumsymut restricted_roles = list("Clown") -/datum/uplink_item/role_restricted/taeclowndo_shoes - name = "Tae-clown-do Shoes" - desc = "A pair of shoes for the most elite agents of the honkmotherland. They grant the mastery of taeclowndo with some honk-fu moves as long as they're worn." - cost = 14 - item = /obj/item/clothing/shoes/clown_shoes/taeclowndo - restricted_roles = list("Clown") +/datum/uplink_item/role_restricted/haunted_magic_eightball + name = "Haunted Magic Eightball" + desc = "Most magic eightballs are toys with dice inside. Although identical in appearance to the harmless toys, this occult device reaches into the spirit world to find its answers. Be warned, that spirits are often capricious or just little assholes. To use, simply speak your question aloud, then begin shaking." + item = /obj/item/toy/eightball/haunted + cost = 2 + restricted_roles = list("Curator") + limited_stock = 1 //please don't spam deadchat -/datum/uplink_item/role_restricted/mimery - name = "Guide to Advanced Mimery Series" - desc = "The classical two part series on how to further hone your mime skills. Upon studying the series, the user should be able to make 3x1 invisible walls, and shoot bullets out of their fingers. Obviously only works for Mimes." - cost = 12 - item = /obj/item/storage/box/syndie_kit/mimery - restricted_roles = list("Mime") +/datum/uplink_item/role_restricted/his_grace + name = "His Grace" + desc = "An incredibly dangerous weapon recovered from a station overcome by the grey tide. Once activated, He will thirst for blood and must be used to kill to sate that thirst. \ + His Grace grants gradual regeneration and complete stun immunity to His wielder, but be wary: if He gets too hungry, He will become impossible to drop and eventually kill you if not fed. \ + However, if left alone for long enough, He will fall back to slumber. \ + To activate His Grace, simply unlatch Him." + item = /obj/item/his_grace + cost = 20 + restricted_roles = list("Chaplain") + surplus = 5 //Very low chance to get it in a surplus crate even without being the chaplain + +/datum/uplink_item/role_restricted/explosive_hot_potato + name = "Exploding Hot Potato" + desc = "A potato rigged with explosives. On activation, a special mechanism is activated that prevents it from being dropped. The only way to get rid of it if you are holding it is to attack someone else with it, causing it to latch to that person instead." + item = /obj/item/hot_potato/syndicate + cost = 4 + restricted_roles = list("Cook", "Botanist", "Clown", "Mime") /datum/uplink_item/role_restricted/ez_clean_bundle name = "EZ Clean Grenade Bundle" @@ -1436,6 +1670,36 @@ datum/uplink_item/stealthy_tools/taeclowndo_shoes surplus = 20 restricted_roles = list("Janitor") +/datum/uplink_item/role_restricted/goldenbox + name = "Gold Toolbox" + desc = "A gold planted plastitanium toolbox loaded with tools. Comes with a set of AI detection multi-tool and a pare of combat gloves." + item = /obj/item/storage/toolbox/gold_real + cost = 3 // Has syndie tools + gloves + a robust weapon + restricted_roles = list("Assistant", "Curator") //Curator due to this being made of gold - It fits the theme + +/datum/uplink_item/role_restricted/mimery + name = "Guide to Advanced Mimery Series" + desc = "The classical two part series on how to further hone your mime skills. Upon studying the series, the user should be able to make 3x1 invisible walls, and shoot bullets out of their fingers. Obviously only works for Mimes." + cost = 12 + item = /obj/item/storage/box/syndie_kit/mimery + restricted_roles = list("Mime") + +/datum/uplink_item/role_restricted/ultrahonkpins + name = "Hilarious firing pin" + desc = "A single firing pin made for Clown agents, this firing pin makes any gun honk when fired if not a true clown! \ + This firing pin also helps you fire the gun correctly. May the HonkMother HONK you agent." + item = /obj/item/firing_pin/clown/ultra + cost = 2 + restricted_roles = list("Clown") + +/datum/uplink_item/role_restricted/pressure_mod + name = "Kinetic Accelerator Pressure Mod" + desc = "A modification kit which allows Kinetic Accelerators to do greatly increased damage while indoors. Occupies 35% mod capacity." + item = /obj/item/borg/upgrade/modkit/indoors + cost = 5 //you need two for full damage, so total of 10 for maximum damage + limited_stock = 2 //you can't use more than two! + restricted_roles = list("Shaft Miner") + /datum/uplink_item/role_restricted/kitchen_gun name = "Kitchen Gun (TM)" desc = "A revolutionary .45 caliber cleaning solution! Say goodbye to daily stains and dirty surfaces with Kitchen Gun (TM)! Just five shots from Kitchen Gun (TM), and it'll sparkle like new! Includes two extra ammunition clips!" @@ -1451,60 +1715,12 @@ datum/uplink_item/stealthy_tools/taeclowndo_shoes restricted_roles = list("Cook", "Janitor") item = /obj/item/ammo_box/magazine/m45/kitchengun -/datum/uplink_item/role_restricted/explosive_hot_potato - name = "Exploding Hot Potato" - desc = "A potato rigged with explosives. On activation, a special mechanism is activated that prevents it from being dropped. The only way to get rid of it if you are holding it is to attack someone else with it, causing it to latch to that person instead." - item = /obj/item/hot_potato/syndicate - cost = 4 - restricted_roles = list("Cook", "Botanist", "Clown", "Mime") - -/datum/uplink_item/role_restricted/his_grace - name = "His Grace" - desc = "An incredibly dangerous weapon recovered from a station overcome by the grey tide. Once activated, He will thirst for blood and must be used to kill to sate that thirst. \ - His Grace grants gradual regeneration and complete stun immunity to His wielder, but be wary: if He gets too hungry, He will become impossible to drop and eventually kill you if not fed. \ - However, if left alone for long enough, He will fall back to slumber. \ - To activate His Grace, simply unlatch Him." - item = /obj/item/his_grace - cost = 20 - restricted_roles = list("Chaplain") - surplus = 5 //Very low chance to get it in a surplus crate even without being the chaplain - -/datum/uplink_item/role_restricted/pie_cannon - name = "Banana Cream Pie Cannon" - desc = "A special pie cannon for a special clown, this gadget can hold up to 20 pies and automatically fabricates one every two seconds!" - cost = 10 - item = /obj/item/pneumatic_cannon/pie/selfcharge - restricted_roles = list("Clown") - -/datum/uplink_item/role_restricted/ancient_jumpsuit - name = "Ancient Jumpsuit" - desc = "A tattered old jumpsuit that will provide absolutely no benefit to you. It fills the wearer with a strange compulsion to blurt out 'glorf'." - item = /obj/item/clothing/under/color/grey/glorf - cost = 20 - restricted_roles = list("Assistant") - -/datum/uplink_item/role_restricted/goldenbox - name = "Gold Toolbox" - desc = "A gold planted plastitanium toolbox loaded with tools. Comes with a set of AI detection multi-tool and a pare of combat gloves." - item = /obj/item/storage/toolbox/gold_real - cost = 3 // Has synda tools + gloves + a robust weapon - restricted_roles = list("Assistant", "Curator") //Curator do to being made of gold - It fits the theme - -/datum/uplink_item/role_restricted/brainwash_disk - name = "Brainwashing Surgery Program" - desc = "A disk containing the procedure to perform a brainwashing surgery, allowing you to implant an objective onto a target. \ - Insert into an Operating Console to enable the procedure." - item = /obj/item/disk/surgery/brainwashing - restricted_roles = list("Medical Doctor") - cost = 3 - -/datum/uplink_item/role_restricted/haunted_magic_eightball - name = "Haunted Magic Eightball" - desc = "Most magic eightballs are toys with dice inside. Although identical in appearance to the harmless toys, this occult device reaches into the spirit world to find its answers. Be warned, that spirits are often capricious or just little assholes. To use, simply speak your question aloud, then begin shaking." - item = /obj/item/toy/eightball/haunted - cost = 2 - restricted_roles = list("Curator") - limited_stock = 1 //please don't spam deadchat +/datum/uplink_item/role_restricted/magillitis_serum + name = "Magillitis Serum Autoinjector" + desc = "A single-use autoinjector which contains an experimental serum that causes rapid muscular growth in Hominidae. Side-affects may include hypertrichosis, violent outbursts, and an unending affinity for bananas." + item = /obj/item/reagent_containers/hypospray/magillitis + cost = 15 + restricted_roles = list("Geneticist", "Chief Medical Officer") /datum/uplink_item/role_restricted/modified_syringe_gun name = "Modified Syringe Gun" @@ -1520,100 +1736,41 @@ datum/uplink_item/stealthy_tools/taeclowndo_shoes cost = 12 restricted_roles = list("Chemist", "Chief Medical Officer") -/datum/uplink_item/role_restricted/magillitis_serum - name = "Magillitis Serum Autoinjector" - desc = "A single-use autoinjector which contains an experimental serum that causes rapid muscular growth in Hominidae. Side-affects may include hypertrichosis, violent outbursts, and an unending affinity for bananas." - item = /obj/item/reagent_containers/hypospray/magillitis - cost = 15 - restricted_roles = list("Geneticist", "Chief Medical Officer") - -/datum/uplink_item/role_restricted/pressure_mod - name = "Kinetic Accelerator Pressure Mod" - desc = "A modification kit which allows Kinetic Accelerators to do greatly increased damage while indoors. Occupies 35% mod capacity." - item = /obj/item/borg/upgrade/modkit/indoors - cost = 5 //you need two for full damage, so total of 10 for maximum damage - limited_stock = 2 //you can't use more than two! - restricted_roles = list("Shaft Miner") - -/datum/uplink_item/role_restricted/blastcannon - name = "Blast Cannon" - desc = "A highly specialized weapon, the Blast Cannon is actually relatively simple. It contains an attachment for a tank transfer valve mounted to an angled pipe specially constructed \ - withstand extreme pressure and temperatures, and has a mechanical trigger for triggering the transfer valve. Essentially, it turns the explosive force of a bomb into a narrow-angle \ - blast wave \"projectile\". Aspiring scientists may find this highly useful, as forcing the pressure shockwave into a narrow angle seems to be able to bypass whatever quirk of physics \ - disallows explosive ranges above a certain distance, allowing for the device to use the theoretical yield of a transfer valve bomb, instead of the factual yield." - item = /obj/item/gun/blastcannon - cost = 14 //High cost because of the potential for extreme damage in the hands of a skilled gas masked scientist. - restricted_roles = list("Research Director", "Scientist") - -/datum/uplink_item/device_tools/clown_bomb - name = "Clown Bomb" - desc = "The Clown bomb is a hilarious device capable of massive pranks. It has an adjustable timer, \ - with a minimum of 60 seconds, and can be bolted to the floor with a wrench to prevent \ - movement. The bomb is bulky and cannot be moved; upon ordering this item, a smaller beacon will be \ - transported to you that will teleport the actual bomb to it upon activation. Note that this bomb can \ - be defused, and some crew may attempt to do so." - item = /obj/item/sbeacondrop/clownbomb - cost = 15 +/datum/uplink_item/role_restricted/reverse_bear_trap + name = "Reverse Bear Trap" + desc = "An ingenious execution device worn on (or forced onto) the head. Arming it starts a 1-minute kitchen timer mounted on the bear trap. When it goes off, the trap's jaws will \ + violently open, instantly killing anyone wearing it by tearing their jaws in half. To arm, attack someone with it while they're not wearing headgear, and you will force it onto their \ + head after three seconds uninterrupted." + cost = 5 + item = /obj/item/reverse_bear_trap restricted_roles = list("Clown") -/datum/uplink_item/device_tools/ultrahonkpins //Idealy so they can place it into their own guns without needing cargo - name = "Hilarious firing pin" - desc = "A single firing pin made for Clown agents, this firing pin makes any gun honk when fired if not a true clown! \ - This firing pin also helps you fire the gun correctly. May the HonkMother HONK you agent." - item = /obj/item/firing_pin/clown/ultra - cost = 2 +/datum/uplink_item/role_restricted/reverse_revolver + name = "Reverse Revolver" + desc = "A revolver that always fires at its user. \"Accidentally\" drop your weapon, then watch as the greedy corporate pigs blow their own brains all over the wall. \ + The revolver itself is actually real. Only clumsy people, and clowns, can fire it normally. Comes in a box of hugs. Honk." + cost = 14 + item = /obj/item/storage/box/hug/reverse_revolver restricted_roles = list("Clown") -/* -/datum/uplink_item/role_restricted/clowncar - name = "Clown Car" - desc = "The Clown Car is the ultimate transportation method for any worthy clown! \ - Simply insert your bikehorn and get in, and get ready to have the funniest ride of your life! \ - You can ram any spacemen you come across and stuff them into your car, kidnapping them and locking them inside until \ - someone saves them or they manage to crawl out. Be sure not to ram into any walls or vending machines, as the springloaded seats \ - are very sensetive. Now with our included lube defense mechanism which will protect you against any angry shitcurity!" - item = /obj/vehicle/sealed/car/clowncar - cost = 15 +/datum/uplink_item/role_restricted/taeclowndo_shoes + name = "Tae-clown-do Shoes" + desc = "A pair of shoes for the most elite agents of the honkmotherland. They grant the mastery of taeclowndo with some honk-fu moves as long as they're worn." + cost = 14 + item = /obj/item/clothing/shoes/clown_shoes/taeclowndo restricted_roles = list("Clown") -*/ + // Pointless /datum/uplink_item/badass category = "(Pointless) Badassery" surplus = 0 -/datum/uplink_item/badass/syndiecards - name = "Syndicate Playing Cards" - desc = "A special deck of space-grade playing cards with a mono-molecular edge and metal reinforcement, \ - making them slightly more robust than a normal deck of cards. \ - You can also play card games with them or leave them on your victims." - item = /obj/item/toy/cards/deck/syndicate - cost = 1 - surplus = 40 - -/datum/uplink_item/badass/syndiecash - name = "Syndicate Briefcase Full of Cash" - desc = "A secure briefcase containing 5000 space credits. Useful for bribing personnel, or purchasing goods \ - and services at lucrative prices. The briefcase also feels a little heavier to hold; it has been \ - manufactured to pack a little bit more of a punch if your client needs some convincing." - item = /obj/item/storage/secure/briefcase/syndie - cost = 1 - -/datum/uplink_item/badass/syndiecigs - name = "Syndicate Smokes" - desc = "Strong flavor, dense smoke, infused with omnizine." - item = /obj/item/storage/fancy/cigarettes/cigpack_syndicate - cost = 2 - -/datum/uplink_item/badass/balloon - name = "Syndicate Balloon" - desc = "For showing that you are THE BOSS: A useless red balloon with the Syndicate logo on it. \ - Can blow the deepest of covers." - item = /obj/item/toy/syndicateballoon - cost = 20 - cant_discount = TRUE +/datum/uplink_item/badass/costumes/obvious_chameleon + name = "Broken Chameleon Kit" + desc = "A set of items that contain chameleon technology allowing you to disguise as pretty much anything on the station, and more! Please note that this kit did NOT pass quality control." + item = /obj/item/storage/box/syndie_kit/chameleon/broken /datum/uplink_item/badass/costumes - surplus = 0 include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) cost = 4 cant_discount = TRUE @@ -1628,90 +1785,45 @@ datum/uplink_item/stealthy_tools/taeclowndo_shoes desc = "Nothing is more terrifying than clowns with fully automatic weaponry." item = /obj/item/storage/backpack/duffelbag/clown/syndie -/datum/uplink_item/badass/costumes/obvious_chameleon - name = "Broken Chameleon Kit" - desc = "A set of items that contain chameleon technology allowing you to disguise as pretty much anything on the station, and more! Please note that this kit did NOT pass quality control." - item = /obj/item/storage/box/syndie_kit/chameleon/broken +/datum/uplink_item/badass/durasteel_toolbox + name = "Durasteel Toolbox" + desc = "A very high impact toolbox. Excels at destroying stationary structures." + item = /obj/item/storage/toolbox/durasteel + cost = 2 //18 damage on mobs, 50 on objects, 4.5 stam/hit -/datum/uplink_item/badass/rapid - name = "Gloves of the North Star" - desc = "These gloves let the user punch people very fast. Does not improve weapon attack speed or the meaty fists of a hulk." - item = /obj/item/clothing/gloves/rapid - cost = 8 - -/datum/uplink_item/badass/bundle - name = "Syndicate Bundle" - desc = "Syndicate Bundles are specialized groups of items that arrive in a plain box. \ - These items are collectively worth more than 20 telecrystals, but you do not know which specialization \ - you will receive." - item = /obj/item/storage/box/syndicate +/datum/uplink_item/badass/balloon + name = "Syndicate Balloon" + desc = "For showing that you are THE BOSS: A useless red balloon with the Syndicate logo on it. \ + Can blow the deepest of covers." + item = /obj/item/toy/syndicateballoon cost = 20 - exclude_modes = list(/datum/game_mode/nuclear) cant_discount = TRUE -/datum/uplink_item/badass/surplus - name = "Syndicate Surplus Crate" - desc = "A dusty crate from the back of the Syndicate warehouse. Rumored to contain a valuable assortment of items, \ - but you never know. Contents are sorted to always be worth 50 TC." - item = /obj/structure/closet/crate - cost = 20 - player_minimum = 25 - exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) - cant_discount = TRUE - var/starting_crate_value = 50 +/datum/uplink_item/badass/syndiecash + name = "Syndicate Briefcase Full of Cash" + desc = "A secure briefcase containing 5000 space credits. Useful for bribing personnel, or purchasing goods \ + and services at lucrative prices. The briefcase also feels a little heavier to hold; it has been \ + manufactured to pack a little bit more of a punch if your client needs some convincing." + item = /obj/item/storage/secure/briefcase/syndie + cost = 1 -/datum/uplink_item/badass/surplus/super - name = "Super Surplus Crate" - desc = "A dusty SUPER-SIZED from the back of the Syndicate warehouse. Rumored to contain a valuable assortment of items, \ - but you never know. Contents are sorted to always be worth 125 TC." - cost = 40 - player_minimum = 40 - starting_crate_value = 125 +/datum/uplink_item/badass/phantomthief + name = "Syndicate Mask" + desc = "A cheap plastic mask fitted with an adrenaline autoinjector, which can be used by simply tensing your muscles" + item = /obj/item/clothing/glasses/phantomthief/syndicate + cost = 2 -/datum/uplink_item/badass/surplus/purchase(mob/user, datum/component/uplink/U) - var/list/uplink_items = get_uplink_items(SSticker && SSticker.mode? SSticker.mode : null, FALSE) +/datum/uplink_item/badass/syndiecards + name = "Syndicate Playing Cards" + desc = "A special deck of space-grade playing cards with a mono-molecular edge and metal reinforcement, \ + making them slightly more robust than a normal deck of cards. \ + You can also play card games with them or leave them on your victims." + item = /obj/item/toy/cards/deck/syndicate + cost = 1 + surplus = 40 - var/crate_value = starting_crate_value - var/obj/structure/closet/crate/C = spawn_item(/obj/structure/closet/crate, user) - if(U.purchase_log) - U.purchase_log.LogPurchase(C, src, cost) - while(crate_value) - var/category = pick(uplink_items) - var/item = pick(uplink_items[category]) - var/datum/uplink_item/I = uplink_items[category][item] - - if(!I.surplus || prob(100 - I.surplus)) - continue - if(crate_value < I.cost) - continue - crate_value -= I.cost - var/obj/goods = new I.item(C) - if(U.purchase_log) - U.purchase_log.LogPurchase(goods, I, 0) - return C - -/datum/uplink_item/badass/random - name = "Random Item" - desc = "Picking this will purchase a random item. Useful if you have some TC to spare or if you haven't decided on a strategy yet." - item = /obj/effect/gibspawner/generic // non-tangible item because techwebs use this path to determine illegal tech - cost = 0 - cant_discount = TRUE - -/datum/uplink_item/badass/random/purchase(mob/user, datum/component/uplink/U) - var/list/uplink_items = U.uplink_items - var/list/possible_items = list() - for(var/category in uplink_items) - for(var/item in uplink_items[category]) - var/datum/uplink_item/I = uplink_items[category][item] - if(src == I || !I.item) - continue - if(U.telecrystals < I.cost) - continue - if(I.limited_stock == 0) - continue - possible_items += I - - if(possible_items.len) - var/datum/uplink_item/I = pick(possible_items) - SSblackbox.record_feedback("tally", "traitor_random_uplink_items_gotten", 1, initial(I.name)) - U.MakePurchase(user, I) +/datum/uplink_item/badass/syndiecigs + name = "Syndicate Smokes" + desc = "Strong flavor, dense smoke, infused with omnizine." + item = /obj/item/storage/fancy/cigarettes/cigpack_syndicate + cost = 2 diff --git a/code/modules/vehicles/_vehicle.dm b/code/modules/vehicles/_vehicle.dm index be59a6df65..54bc03bcf3 100644 --- a/code/modules/vehicles/_vehicle.dm +++ b/code/modules/vehicles/_vehicle.dm @@ -31,6 +31,19 @@ occupant_actions = list() generate_actions() +/obj/vehicle/examine(mob/user) + ..() + if(resistance_flags & ON_FIRE) + to_chat(user, "It's on fire!") + var/healthpercent = obj_integrity/max_integrity * 100 + switch(healthpercent) + if(50 to 99) + to_chat(user, "It looks slightly damaged.") + if(25 to 50) + to_chat(user, "It appears heavily damaged.") + if(0 to 25) + to_chat(user, "It's falling apart!") + /obj/vehicle/proc/is_key(obj/item/I) return I? (key_type_exact? (I.type == key_type) : istype(I, key_type)) : FALSE diff --git a/code/modules/vehicles/ridden.dm b/code/modules/vehicles/ridden.dm index 25a337bc22..8fe7322579 100644 --- a/code/modules/vehicles/ridden.dm +++ b/code/modules/vehicles/ridden.dm @@ -4,8 +4,8 @@ max_buckled_mobs = 1 buckle_lying = FALSE default_driver_move = FALSE - var/legs_required = 2 - var/arms_requires = 0 //why not? + var/legs_required = 1 + var/arms_required = 0 //why not? /obj/vehicle/ridden/Initialize() . = ..() @@ -31,6 +31,9 @@ /obj/vehicle/ridden/post_buckle_mob(mob/living/M) add_occupant(M) + if(M.get_num_legs() < legs_required) + to_chat(M, "You don't have enough legs to operate the pedals!") + unbuckle_mob(M) return ..() /obj/vehicle/ridden/attackby(obj/item/I, mob/user, params) diff --git a/code/modules/vehicles/wheelchair.dm b/code/modules/vehicles/wheelchair.dm new file mode 100644 index 0000000000..a5ba06e6fb --- /dev/null +++ b/code/modules/vehicles/wheelchair.dm @@ -0,0 +1,110 @@ +/obj/vehicle/ridden/wheelchair //ported from Hippiestation (by Jujumatic) Then ported by Fermis from tg! + name = "wheelchair" + desc = "A chair with big wheels. It looks like you can move in this on your own." + icon = 'icons/obj/vehicles.dmi' + icon_state = "wheelchair" + layer = OBJ_LAYER + max_integrity = 100 + armor = list("melee" = 10, "bullet" = 10, "laser" = 10, "energy" = 0, "bomb" = 10, "bio" = 0, "rad" = 0, "fire" = 20, "acid" = 30) //Wheelchairs aren't super tough yo + legs_required = 0 //You'll probably be using this if you don't have legs + canmove = TRUE + density = FALSE //Thought I couldn't fix this one easily, phew + arms_required = 1 + +/obj/vehicle/ridden/wheelchair/Initialize() + . = ..() + var/datum/component/riding/D = LoadComponent(/datum/component/riding) + D.vehicle_move_delay = 0 + D.set_vehicle_dir_layer(SOUTH, OBJ_LAYER) + D.set_vehicle_dir_layer(NORTH, ABOVE_MOB_LAYER) + D.set_vehicle_dir_layer(EAST, OBJ_LAYER) + D.set_vehicle_dir_layer(WEST, OBJ_LAYER) + +/obj/vehicle/ridden/wheelchair/ComponentInitialize() //Since it's technically a chair I want it to have chair properties + . = ..() + AddComponent(/datum/component/simple_rotation,ROTATION_ALTCLICK | ROTATION_CLOCKWISE, CALLBACK(src, .proc/can_user_rotate),CALLBACK(src, .proc/can_be_rotated),null) + +/obj/vehicle/ridden/wheelchair/obj_destruction(damage_flag) + new /obj/item/stack/rods(drop_location(), 1) + new /obj/item/stack/sheet/metal(drop_location(), 1) + ..() + +/obj/vehicle/ridden/wheelchair/Destroy() + if(has_buckled_mobs()) + var/mob/living/carbon/H = buckled_mobs[1] + unbuckle_mob(H) + return ..() + +/obj/vehicle/ridden/wheelchair/driver_move(mob/living/user, direction) + if(istype(user)) + if(canmove && (user.get_num_arms() < arms_required)) + to_chat(user, "You don't have enough arms to operate the wheels!") + canmove = FALSE + addtimer(VARSET_CALLBACK(src, canmove, TRUE), 20) + return FALSE + var/datum/component/riding/D = GetComponent(/datum/component/riding) + //1.5 (movespeed as of this change) multiplied by 6.7 gets ABOUT 10 (rounded), the old constant for the wheelchair that gets divided by how many arms they have + //if that made no sense this simply makes the wheelchair speed change along with movement speed delay + D.vehicle_move_delay = round(CONFIG_GET(number/movedelay/run_delay) * 6.7) / min(user.get_num_arms(), 2) + return ..() + +/obj/vehicle/ridden/wheelchair/Moved() + . = ..() + cut_overlays() + playsound(src, 'sound/effects/roll.ogg', 75, 1) + if(has_buckled_mobs()) + handle_rotation_overlayed() + + +/obj/vehicle/ridden/wheelchair/post_buckle_mob(mob/living/user) + . = ..() + handle_rotation_overlayed() + +/obj/vehicle/ridden/wheelchair/post_unbuckle_mob() + . = ..() + cut_overlays() + +/obj/vehicle/ridden/wheelchair/setDir(newdir) + ..() + handle_rotation(newdir) + +/obj/vehicle/ridden/wheelchair/wrench_act(mob/living/user, obj/item/I) //Attackby should stop it attacking the wheelchair after moving away during decon + to_chat(user, "You begin to detach the wheels...") + if(I.use_tool(src, user, 40, volume=50)) + to_chat(user, "You detach the wheels and deconstruct the chair.") + new /obj/item/stack/rods(drop_location(), 6) + new /obj/item/stack/sheet/metal(drop_location(), 4) + qdel(src) + return TRUE + +/obj/vehicle/ridden/wheelchair/proc/handle_rotation(direction) + if(has_buckled_mobs()) + handle_rotation_overlayed() + for(var/m in buckled_mobs) + var/mob/living/buckled_mob = m + buckled_mob.setDir(direction) + +/obj/vehicle/ridden/wheelchair/proc/handle_rotation_overlayed() + cut_overlays() + var/image/V = image(icon = icon, icon_state = "wheelchair_overlay", layer = FLY_LAYER, dir = src.dir) + add_overlay(V) + + + +/obj/vehicle/ridden/wheelchair/proc/can_be_rotated(mob/living/user) + return TRUE + +/obj/vehicle/ridden/wheelchair/proc/can_user_rotate(mob/living/user) + var/mob/living/L = user + if(istype(L)) + if(!user.canUseTopic(src, BE_CLOSE, ismonkey(user))) + return FALSE + if(isobserver(user) && CONFIG_GET(flag/ghost_interaction)) + return TRUE + return FALSE + +/obj/vehicle/ridden/wheelchair/the_whip/driver_move(mob/living/user, direction) + if(istype(user)) + var/datum/component/riding/D = GetComponent(/datum/component/riding) + D.vehicle_move_delay = round(CONFIG_GET(number/movedelay/run_delay) * 6.7) / user.get_num_arms() + return ..() diff --git a/code/modules/vending/medical.dm b/code/modules/vending/medical.dm index 5eba9b6b21..523606aa6a 100644 --- a/code/modules/vending/medical.dm +++ b/code/modules/vending/medical.dm @@ -32,7 +32,10 @@ /obj/item/reagent_containers/hypospray/medipen = 3, /obj/item/storage/belt/medical = 3, /obj/item/wrench/medical = 1, - /obj/item/storage/briefcase/medical = 2) + /obj/item/storage/belt/medolier/full = 2, + /obj/item/gun/syringe/dart = 2, + /obj/item/storage/briefcase/medical = 2) + armor = list("melee" = 100, "bullet" = 100, "laser" = 100, "energy" = 100, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 50) resistance_flags = FIRE_PROOF refill_canister = /obj/item/vending_refill/medical diff --git a/code/modules/vending/medical_wall.dm b/code/modules/vending/medical_wall.dm index 018eb09d86..514bbd8730 100644 --- a/code/modules/vending/medical_wall.dm +++ b/code/modules/vending/medical_wall.dm @@ -10,7 +10,8 @@ /obj/item/reagent_containers/medspray/styptic = 2, /obj/item/reagent_containers/medspray/silver_sulf = 2, /obj/item/reagent_containers/pill/charcoal = 2, - /obj/item/reagent_containers/medspray/sterilizine = 1) + /obj/item/reagent_containers/medspray/sterilizine = 1, + /obj/item/reagent_containers/syringe/dart = 10) contraband = list(/obj/item/reagent_containers/pill/tox = 2, /obj/item/reagent_containers/pill/morphine = 2) premium = list(/obj/item/reagent_containers/medspray/synthflesh = 2) diff --git a/config/spaceRuinBlacklist.txt b/config/spaceRuinBlacklist.txt index e70a6d081f..621184a530 100644 --- a/config/spaceRuinBlacklist.txt +++ b/config/spaceRuinBlacklist.txt @@ -46,3 +46,7 @@ #_maps/RandomRuins/SpaceRuins/way_home.dmm #_maps/RandomRuins/SpaceRuins/whiteshipdock.dmm #_maps/RandomRuins/SpaceRuins/whiteshipruin_box.dmm +#_maps/RandomRuins/SpaceRuins/augmentationfacility.dmm +#_maps/RandomRuins/SpaceRuins/bigape.dmm +#_maps/RandomRuins/SpaceRuins/arcade.dmm +#_maps/RandomRuins/SpaceRuins/spacehermit.dmm diff --git a/goon/browserassets/css/browserOutput.css b/goon/browserassets/css/browserOutput.css deleted file mode 100644 index 820537e32b..0000000000 --- a/goon/browserassets/css/browserOutput.css +++ /dev/null @@ -1,362 +0,0 @@ -/***************************************** -* -* GLOBAL STYLES -* -******************************************/ -html, body { - padding: 0; - margin: 0; - height: 100%; - color: #000000; -} -body { - background: #fff; - font-family: Verdana, sans-serif; - font-size: 9pt; - line-height: 1.4; - overflow-x: hidden; - overflow-y: scroll; - word-wrap: break-word; -} - -em { - font-style: normal; - font-weight: bold; -} - -img { - margin: 0; - padding: 0; - line-height: 1; -} -img.icon { - width: 16px; - height: 16px; -} - -a {color: #0000ff;} -a.visited {color: #ff00ff;} -a:visited {color: #ff00ff;} -a.popt {text-decoration: none;} - -/***************************************** -* -* OUTPUT NOT RELATED TO ACTUAL MESSAGES -* -******************************************/ -#loading { - position: fixed; - width: 300px; - height: 150px; - text-align: center; - left: 50%; - top: 50%; - margin: -75px 0 0 -150px; -} -#loading i {display: block; padding-bottom: 3px;} - -#messages { - font-size: 14px; - padding: 3px; - margin: 0; - word-wrap: break-word; -} -#newMessages { - position: fixed; - display: block; - bottom: 0; - right: 0; - padding: 8px; - background: #ddd; - text-decoration: none; - font-variant: small-caps; - font-size: 1.1em; - font-weight: bold; - color: #333; -} -#newMessages:hover {background: #ccc;} -#newMessages i {vertical-align: middle; padding-left: 3px;} -#ping { - position: fixed; - top: 0; - right: 40px; - width: 45px; - background: #ddd; - height: 30px; - padding: 8px 0 2px 0; -} -#ping i {display: block; text-align: center;} -#ping .ms { - display: block; - text-align: center; - font-size: 8pt; - padding-top: 2px; -} -#options { - position: fixed; - top: 0; - right: 0; -} -#options a { - background: #ddd; - height: 30px; - padding: 5px 0; - display: block; - color: #333; - text-decoration: none; - line-height: 28px; - border-top: 1px solid #b4b4b4; -} -#options a:hover {background: #ccc;} -#options .toggle { - width: 40px; - background: #ccc; - border-top: 0; - float: right; - text-align: center; -} -#options .sub {clear: both; display: none; width: 160px;} -#options .sub.scroll {overflow-y: scroll;} -#options .sub a {padding: 3px 0 3px 8px; line-height: 30px; font-size: 0.9em; clear: both;} -#options .sub span { - display: block; - line-height: 30px; - float: left; -} -#options .sub i { - display: block; - padding: 0 5px; - font-size: 1.1em; - width: 22px; - text-align: center; - line-height: 30px; - float: right; -} -#options .decreaseFont {border-top: 0;} - -/* POPUPS */ -.popup { - position: fixed; - top: 50%; - left: 50%; - background: #ddd; -} -.popup .close { - position: absolute; - background: #aaa; - top: 0; - right: 0; - color: #333; - text-decoration: none; - z-index: 2; - padding: 0 10px; - height: 30px; - line-height: 30px; -} -.popup .close:hover {background: #999;} -.popup .head { - background: #999; - color: #ddd; - padding: 0 10px; - height: 30px; - line-height: 30px; - text-transform: uppercase; - font-size: 0.9em; - font-weight: bold; - border-bottom: 2px solid green; -} -.popup input {border: 1px solid #999; background: #fff; margin: 0; padding: 5px; outline: none; color: #333;} -.popup input[type=text]:hover, .popup input[type=text]:active, .popup input[type=text]:focus {border-color: green;} -.popup input[type=submit] {padding: 5px 10px; background: #999; color: #ddd; text-transform: uppercase; font-size: 0.9em; font-weight: bold;} -.popup input[type=submit]:hover, .popup input[type=submit]:focus, .popup input[type=submit]:active {background: #aaa; cursor: pointer;} - -.changeFont {padding: 10px;} -.changeFont a {display: block; text-decoration: none; padding: 3px; color: #333;} -.changeFont a:hover {background: #ccc;} - -.highlightPopup {padding: 10px; text-align: center;} -.highlightPopup input[type=text] {display: block; width: 215px; text-align: left; margin-top: 5px;} -.highlightPopup input.highlightColor {background-color: #FFFF00;} -.highlightPopup input.highlightTermSubmit {margin-top: 5px;} - -/* ADMIN CONTEXT MENU */ -.contextMenu { - background-color: #ddd; - position: fixed; - margin: 2px; - width: 150px; -} -.contextMenu a { - display: block; - padding: 2px 5px; - text-decoration: none; - color: #333; -} - -.contextMenu a:hover { - background-color: #ccc; -} - -/* ADMIN FILTER MESSAGES MENU */ -.filterMessages {padding: 5px;} -.filterMessages div {padding: 2px 0;} -.filterMessages input {} -.filterMessages label {} - -.icon-stack {height: 1em; line-height: 1em; width: 1em; vertical-align: middle; margin-top: -2px;} - - -/***************************************** -* -* OUTPUT ACTUALLY RELATED TO MESSAGES -* -******************************************/ - -/* MOTD */ -.motd {color: #638500; font-family: Verdana, sans-serif;} -.motd h1, .motd h2, .motd h3, .motd h4, .motd h5, .motd h6 {color: #638500; text-decoration: underline;} -.motd a, .motd a:link, .motd a:visited, .motd a:active, .motd a:hover {color: #638500;} - -/* ADD HERE FOR BOLD */ -.bold, .name, .prefix, .ooc, .looc, .adminooc, .admin, .medal, .yell {font-weight: bold;} - -/* ADD HERE FOR ITALIC */ -.italic, .italics, .emote {font-style: italic;} - -/* OUTPUT COLORS */ -.highlight {background: yellow;} - -h1, h2, h3, h4, h5, h6 {color: #0000ff;font-family: Georgia, Verdana, sans-serif;} -h1.alert, h2.alert {color: #000000;} - -em {font-style: normal; font-weight: bold;} - -.adminobserverooc {color: #0099cc; font-weight: bold;} -.adminooc {color: #b82e00; font-weight: bold;} -.adminobserver {color: #996600; font-weight: bold;} -.admin {color: #386aff; font-weight: bold;} -/* SAY CLASSES */ -.say {} -.deadsay {color: #5c00e6;} -.siliconsay {font-family: 'Courier New', Courier, monospace;} -/* RADIO CLASSES */ -.radio {color: #008000;} - -.syndradio {color: #6d3f40;} -.centradio {color: #686868;} - -.aiprivradio {color: #ff00ff;} -.comradio {color: #948f02;} - -.secradio {color: #a30000;} -.engradio {color: #fb5613;} -.medradio {color: #337296;} -.sciradio {color: #993399;} -.supradio {color: #a8732b;} -.servadio {color: #6eaa2c;} - -.attack {color: #ff0000;} -.disarm {color: #990000;} -.passive {color: #660000;} - -.selecteddna {color: #ffffff; background-color: #001B1B} -.alert {color: #ff0000;} -.userdanger {color: #ff0000; font-weight: bold; font-size: 3;} -.danger {color: #ff0000;} -.warning {color: #ff0000; font-style: italic;} -.boldwarning {color: #ff0000; font-style: italic; font-weight: bold} -.announce {color: #228b22; font-weight: bold;} -.boldannounce {color: #ff0000; font-weight: bold;} -.greenannounce {color: #00ff00; font-weight: bold;} -.rose {color: #ff5050;} -.info {color: #0000CC;} -.notice {color: #000099;} -.boldnotice {color: #000099; font-weight: bold;} -.adminnotice {color: #0000ff;} -.unconscious {color: #0000ff; font-weight: bold;} -.suicide {color: #ff5050; font-style: italic;} -.green {color: #03ff39;} -.shadowling {color: #3b2769;} -.cult {color: #960000;} -.cultitalic {color: #960000; font-style: italic;} -.cultlarge {color: #960000; font-weight: bold; font-size: 3;} -.narsie {color: #960000; font-weight: bold; font-size: 125px;} -.narsiesmall {color: #960000; font-weight: bold; font-size: 6;} -.colossus {color: #7F282A; font-size: 5;} -.hierophant {color: #660099; font-weight: bold; font-style: italic;} -.hierophant_warning {color: #660099; font-style: italic;} -.purple {color: #5e2d79;} -.holoparasite {color: #35333a;} -.holoparasitebold {color: #35333a; font-weight: bold;} - -.revennotice {color: #1d2953;} -.revenboldnotice {color: #1d2953; font-weight: bold;} -.revenbignotice {color: #1d2953; font-weight: bold; font-size: 3;} -.revenminor {color: #823abb} -.revenwarning {color: #760fbb; font-style: italic;} -.revendanger {color: #760fbb; font-weight: bold; font-size: 3;} -.umbra {color: #5000A0;} -.umbra_bold {color: #5000A0; font-weight: bold;} -.umbra_italics {color: #5000A0; font-style: italic;} -.umbra_emphasis {color: #5000A0; font-weight: bold; font-style: italic;} -.umbra_large {color: #5000A0; font-size: 3;} - -.brass {color: #BE8700;} -.heavy_brass {color: #BE8700; font-weight: bold; font-style: italic;} -.large_brass {color: #BE8700; font-size: 3;} -.big_brass {color: #BE8700; font-size: 3; font-weight: bold; font-style: italic;} -.ratvar {color: #BE8700; font-size: 6; font-weight: bold; font-style: italic;} -.alloy {color: #42474D;} -.heavy_alloy {color: #42474D; font-weight: bold; font-style: italic;} -.large_alloy {color: #42474D; font-size: 3;} -.nezbere_large {color: #42474D; font-size: 3; font-weight: bold; font-style: italic;} -.nezbere {color: #42474D; font-weight: bold; font-style: italic;} -.nezbere_small {color: #42474D;} -.sevtug_large {color: #AF0AAF; font-size: 3; font-weight: bold; font-style: italic;} -.sevtug {color: #AF0AAF; font-weight: bold; font-style: italic;} -.sevtug_small {color: #AF0AAF;} -.inathneq_large {color: #1E8CE1; font-size: 3; font-weight: bold; font-style: italic;} -.inathneq {color: #1E8CE1; font-weight: bold; font-style: italic;} -.inathneq_small {color: #1E8CE1;} -.nzcrentr_large {color: #DAAA18; font-size: 3; font-weight: bold; font-style: italic;} -.nzcrentr {color: #DAAA18; font-weight: bold; font-style: italic;} -.nzcrentr_small {color: #DAAA18;} -.neovgre_large {color: #6E001A; font-size: 3; font-weight: bold; font-style: italic;} -.neovgre {color: #6E001A; font-weight: bold; font-style: italic;} -.neovgre_small {color: #6E001A;} - -.newscaster {color: #800000;} -.ghostalert {color: #5c00e6; font-style: italic; font-weight: bold;} - -.alien {color: #543354;} -.noticealien {color: #00c000;} -.alertalien {color: #00c000; font-weight: bold;} -.borer {color: #543354; font-style: italic;} -.changeling {color: #800080; font-style: italic;} - -.interface {color: #330033;} - -.sans {font-family: "Comic Sans MS", cursive, sans-serif;} -.papyrus {font-family: "Papyrus", cursive, sans-serif;} -.robot {font-family: "Courier New", cursive, sans-serif;} - -.command_headset {font-weight: bold; font-size: 3;} -.big {font-size: 3;} -.reallybig {font-size: 4;} -.greentext {color: #00FF00; font-size: 3;} -.redtext {color: #FF0000; font-size: 3;} -.clown {color: #FF69Bf; font-size: 3; font-family: "Comic Sans MS", cursive, sans-serif; font-weight: bold;} - -big img.icon {width: 32px; height: 32px;} - -.memo {color: #638500; text-align: center;} -.memoedit {text-align: center; font-size: 2;} -.abductor {color: #800080; font-style: italic;} - -.connectionClosed, .fatalError {background: red; color: white; padding: 5px;} -.connectionClosed.restored {background: green;} -.internal.boldnshit {color: blue; font-weight: bold;} - -/* HELPER CLASSES */ -.text-normal {font-weight: normal; font-style: normal;} -.hidden {display: none; visibility: hidden;} \ No newline at end of file diff --git a/goon/browserassets/css/font-awesome.css b/goon/browserassets/css/font-awesome.css deleted file mode 100644 index cc99d7b337..0000000000 --- a/goon/browserassets/css/font-awesome.css +++ /dev/null @@ -1,788 +0,0 @@ -@font-face{font-family:'FontAwesome';src:url('fontawesome-webfont.eot');src:url('fontawesome-webfont.eot') format('embedded-opentype'),url('fontawesome-webfont.woff') format('woff'),url('fontawesome-webfont.ttf') format('truetype'),url('fontawesome-webfont.svg') format('svg');font-weight:normal;font-style:normal;}[class^="icon-"],[class*=" icon-"]{font-family:FontAwesome;font-weight:normal;font-style:normal;text-decoration:inherit;-webkit-font-smoothing:antialiased;*margin-right:.3em;} -[class^="icon-"]:before,[class*=" icon-"]:before{text-decoration:inherit;display:inline-block;speak:none;} -.icon-large:before{vertical-align:-10%;font-size:1.3333333333333333em;} -a [class^="icon-"],a [class*=" icon-"]{display:inline;} -[class^="icon-"].icon-fixed-width,[class*=" icon-"].icon-fixed-width{display:inline-block;width:1.1428571428571428em;text-align:right;padding-right:0.2857142857142857em;}[class^="icon-"].icon-fixed-width.icon-large,[class*=" icon-"].icon-fixed-width.icon-large{width:1.4285714285714286em;} -.icons-ul{margin-left:2.142857142857143em;list-style-type:none;}.icons-ul>li{position:relative;} -.icons-ul .icon-li{position:absolute;left:-2.142857142857143em;width:2.142857142857143em;text-align:center;line-height:inherit;} -[class^="icon-"].hide,[class*=" icon-"].hide{display:none;} -.icon-muted{color:#eeeeee;} -.icon-light{color:#ffffff;} -.icon-dark{color:#333333;} -.icon-border{border:solid 1px #eeeeee;padding:.2em .25em .15em;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;} -.icon-2x{font-size:2em;}.icon-2x.icon-border{border-width:2px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;} -.icon-3x{font-size:3em;}.icon-3x.icon-border{border-width:3px;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px;} -.icon-4x{font-size:4em;}.icon-4x.icon-border{border-width:4px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;} -.icon-5x{font-size:5em;}.icon-5x.icon-border{border-width:5px;-webkit-border-radius:7px;-moz-border-radius:7px;border-radius:7px;} -.pull-right{float:right;} -.pull-left{float:left;} -[class^="icon-"].pull-left,[class*=" icon-"].pull-left{margin-right:.3em;} -[class^="icon-"].pull-right,[class*=" icon-"].pull-right{margin-left:.3em;} -[class^="icon-"],[class*=" icon-"]{display:inline;width:auto;height:auto;line-height:normal;vertical-align:baseline;background-image:none;background-position:0% 0%;background-repeat:repeat;margin-top:0;} -.icon-white,.nav-pills>.active>a>[class^="icon-"],.nav-pills>.active>a>[class*=" icon-"],.nav-list>.active>a>[class^="icon-"],.nav-list>.active>a>[class*=" icon-"],.navbar-inverse .nav>.active>a>[class^="icon-"],.navbar-inverse .nav>.active>a>[class*=" icon-"],.dropdown-menu>li>a:hover>[class^="icon-"],.dropdown-menu>li>a:hover>[class*=" icon-"],.dropdown-menu>.active>a>[class^="icon-"],.dropdown-menu>.active>a>[class*=" icon-"],.dropdown-submenu:hover>a>[class^="icon-"],.dropdown-submenu:hover>a>[class*=" icon-"]{background-image:none;} -.btn [class^="icon-"].icon-large,.nav [class^="icon-"].icon-large,.btn [class*=" icon-"].icon-large,.nav [class*=" icon-"].icon-large{line-height:.9em;} -.btn [class^="icon-"].icon-spin,.nav [class^="icon-"].icon-spin,.btn [class*=" icon-"].icon-spin,.nav [class*=" icon-"].icon-spin{display:inline-block;} -.nav-tabs [class^="icon-"],.nav-pills [class^="icon-"],.nav-tabs [class*=" icon-"],.nav-pills [class*=" icon-"],.nav-tabs [class^="icon-"].icon-large,.nav-pills [class^="icon-"].icon-large,.nav-tabs [class*=" icon-"].icon-large,.nav-pills [class*=" icon-"].icon-large{line-height:.9em;} -.btn [class^="icon-"].pull-left.icon-2x,.btn [class*=" icon-"].pull-left.icon-2x,.btn [class^="icon-"].pull-right.icon-2x,.btn [class*=" icon-"].pull-right.icon-2x{margin-top:.18em;} -.btn [class^="icon-"].icon-spin.icon-large,.btn [class*=" icon-"].icon-spin.icon-large{line-height:.8em;} -.btn.btn-small [class^="icon-"].pull-left.icon-2x,.btn.btn-small [class*=" icon-"].pull-left.icon-2x,.btn.btn-small [class^="icon-"].pull-right.icon-2x,.btn.btn-small [class*=" icon-"].pull-right.icon-2x{margin-top:.25em;} -.btn.btn-large [class^="icon-"],.btn.btn-large [class*=" icon-"]{margin-top:0;}.btn.btn-large [class^="icon-"].pull-left.icon-2x,.btn.btn-large [class*=" icon-"].pull-left.icon-2x,.btn.btn-large [class^="icon-"].pull-right.icon-2x,.btn.btn-large [class*=" icon-"].pull-right.icon-2x{margin-top:.05em;} -.btn.btn-large [class^="icon-"].pull-left.icon-2x,.btn.btn-large [class*=" icon-"].pull-left.icon-2x{margin-right:.2em;} -.btn.btn-large [class^="icon-"].pull-right.icon-2x,.btn.btn-large [class*=" icon-"].pull-right.icon-2x{margin-left:.2em;} -.nav-list [class^="icon-"],.nav-list [class*=" icon-"]{line-height:inherit;} -.icon-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:-35%;}.icon-stack [class^="icon-"],.icon-stack [class*=" icon-"]{display:block;text-align:center;position:absolute;width:100%;height:100%;font-size:1em;line-height:inherit;*line-height:2em;} -.icon-stack .icon-stack-base{font-size:2em;*line-height:1em;} -.icon-spin{display:inline-block;-moz-animation:spin 2s infinite linear;-o-animation:spin 2s infinite linear;-webkit-animation:spin 2s infinite linear;animation:spin 2s infinite linear;} -a .icon-stack,a .icon-spin{display:inline-block;text-decoration:none;} -@-moz-keyframes spin{0%{-moz-transform:rotate(0deg);} 100%{-moz-transform:rotate(359deg);}}@-webkit-keyframes spin{0%{-webkit-transform:rotate(0deg);} 100%{-webkit-transform:rotate(359deg);}}@-o-keyframes spin{0%{-o-transform:rotate(0deg);} 100%{-o-transform:rotate(359deg);}}@-ms-keyframes spin{0%{-ms-transform:rotate(0deg);} 100%{-ms-transform:rotate(359deg);}}@keyframes spin{0%{transform:rotate(0deg);} 100%{transform:rotate(359deg);}}.icon-rotate-90:before{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg);filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);} -.icon-rotate-180:before{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg);filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);} -.icon-rotate-270:before{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg);filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3);} -.icon-flip-horizontal:before{-webkit-transform:scale(-1, 1);-moz-transform:scale(-1, 1);-ms-transform:scale(-1, 1);-o-transform:scale(-1, 1);transform:scale(-1, 1);} -.icon-flip-vertical:before{-webkit-transform:scale(1, -1);-moz-transform:scale(1, -1);-ms-transform:scale(1, -1);-o-transform:scale(1, -1);transform:scale(1, -1);} -a .icon-rotate-90:before,a .icon-rotate-180:before,a .icon-rotate-270:before,a .icon-flip-horizontal:before,a .icon-flip-vertical:before{display:inline-block;} -.icon-glass:before{content:"\f000";} -.icon-music:before{content:"\f001";} -.icon-search:before{content:"\f002";} -.icon-envelope-alt:before{content:"\f003";} -.icon-heart:before{content:"\f004";} -.icon-star:before{content:"\f005";} -.icon-star-empty:before{content:"\f006";} -.icon-user:before{content:"\f007";} -.icon-film:before{content:"\f008";} -.icon-th-large:before{content:"\f009";} -.icon-th:before{content:"\f00a";} -.icon-th-list:before{content:"\f00b";} -.icon-ok:before{content:"\f00c";} -.icon-remove:before{content:"\f00d";} -.icon-zoom-in:before{content:"\f00e";} -.icon-zoom-out:before{content:"\f010";} -.icon-power-off:before,.icon-off:before{content:"\f011";} -.icon-signal:before{content:"\f012";} -.icon-gear:before,.icon-cog:before{content:"\f013";} -.icon-trash:before{content:"\f014";} -.icon-home:before{content:"\f015";} -.icon-file-alt:before{content:"\f016";} -.icon-time:before{content:"\f017";} -.icon-road:before{content:"\f018";} -.icon-download-alt:before{content:"\f019";} -.icon-download:before{content:"\f01a";} -.icon-upload:before{content:"\f01b";} -.icon-inbox:before{content:"\f01c";} -.icon-play-circle:before{content:"\f01d";} -.icon-rotate-right:before,.icon-repeat:before{content:"\f01e";} -.icon-refresh:before{content:"\f021";} -.icon-list-alt:before{content:"\f022";} -.icon-lock:before{content:"\f023";} -.icon-flag:before{content:"\f024";} -.icon-headphones:before{content:"\f025";} -.icon-volume-off:before{content:"\f026";} -.icon-volume-down:before{content:"\f027";} -.icon-volume-up:before{content:"\f028";} -.icon-qrcode:before{content:"\f029";} -.icon-barcode:before{content:"\f02a";} -.icon-tag:before{content:"\f02b";} -.icon-tags:before{content:"\f02c";} -.icon-book:before{content:"\f02d";} -.icon-bookmark:before{content:"\f02e";} -.icon-print:before{content:"\f02f";} -.icon-camera:before{content:"\f030";} -.icon-font:before{content:"\f031";} -.icon-bold:before{content:"\f032";} -.icon-italic:before{content:"\f033";} -.icon-text-height:before{content:"\f034";} -.icon-text-width:before{content:"\f035";} -.icon-align-left:before{content:"\f036";} -.icon-align-center:before{content:"\f037";} -.icon-align-right:before{content:"\f038";} -.icon-align-justify:before{content:"\f039";} -.icon-list:before{content:"\f03a";} -.icon-indent-left:before{content:"\f03b";} -.icon-indent-right:before{content:"\f03c";} -.icon-facetime-video:before{content:"\f03d";} -.icon-picture:before{content:"\f03e";} -.icon-pencil:before{content:"\f040";} -.icon-map-marker:before{content:"\f041";} -.icon-adjust:before{content:"\f042";} -.icon-tint:before{content:"\f043";} -.icon-edit:before{content:"\f044";} -.icon-share:before{content:"\f045";} -.icon-check:before{content:"\f046";} -.icon-move:before{content:"\f047";} -.icon-step-backward:before{content:"\f048";} -.icon-fast-backward:before{content:"\f049";} -.icon-backward:before{content:"\f04a";} -.icon-play:before{content:"\f04b";} -.icon-pause:before{content:"\f04c";} -.icon-stop:before{content:"\f04d";} -.icon-forward:before{content:"\f04e";} -.icon-fast-forward:before{content:"\f050";} -.icon-step-forward:before{content:"\f051";} -.icon-eject:before{content:"\f052";} -.icon-chevron-left:before{content:"\f053";} -.icon-chevron-right:before{content:"\f054";} -.icon-plus-sign:before{content:"\f055";} -.icon-minus-sign:before{content:"\f056";} -.icon-remove-sign:before{content:"\f057";} -.icon-ok-sign:before{content:"\f058";} -.icon-question-sign:before{content:"\f059";} -.icon-info-sign:before{content:"\f05a";} -.icon-screenshot:before{content:"\f05b";} -.icon-remove-circle:before{content:"\f05c";} -.icon-ok-circle:before{content:"\f05d";} -.icon-ban-circle:before{content:"\f05e";} -.icon-arrow-left:before{content:"\f060";} -.icon-arrow-right:before{content:"\f061";} -.icon-arrow-up:before{content:"\f062";} -.icon-arrow-down:before{content:"\f063";} -.icon-mail-forward:before,.icon-share-alt:before{content:"\f064";} -.icon-resize-full:before{content:"\f065";} -.icon-resize-small:before{content:"\f066";} -.icon-plus:before{content:"\f067";} -.icon-minus:before{content:"\f068";} -.icon-asterisk:before{content:"\f069";} -.icon-exclamation-sign:before{content:"\f06a";} -.icon-gift:before{content:"\f06b";} -.icon-leaf:before{content:"\f06c";} -.icon-fire:before{content:"\f06d";} -.icon-eye-open:before{content:"\f06e";} -.icon-eye-close:before{content:"\f070";} -.icon-warning-sign:before{content:"\f071";} -.icon-plane:before{content:"\f072";} -.icon-calendar:before{content:"\f073";} -.icon-random:before{content:"\f074";} -.icon-comment:before{content:"\f075";} -.icon-magnet:before{content:"\f076";} -.icon-chevron-up:before{content:"\f077";} -.icon-chevron-down:before{content:"\f078";} -.icon-retweet:before{content:"\f079";} -.icon-shopping-cart:before{content:"\f07a";} -.icon-folder-close:before{content:"\f07b";} -.icon-folder-open:before{content:"\f07c";} -.icon-resize-vertical:before{content:"\f07d";} -.icon-resize-horizontal:before{content:"\f07e";} -.icon-bar-chart:before{content:"\f080";} -.icon-twitter-sign:before{content:"\f081";} -.icon-facebook-sign:before{content:"\f082";} -.icon-camera-retro:before{content:"\f083";} -.icon-key:before{content:"\f084";} -.icon-gears:before,.icon-cogs:before{content:"\f085";} -.icon-comments:before{content:"\f086";} -.icon-thumbs-up-alt:before{content:"\f087";} -.icon-thumbs-down-alt:before{content:"\f088";} -.icon-star-half:before{content:"\f089";} -.icon-heart-empty:before{content:"\f08a";} -.icon-signout:before{content:"\f08b";} -.icon-linkedin-sign:before{content:"\f08c";} -.icon-pushpin:before{content:"\f08d";} -.icon-external-link:before{content:"\f08e";} -.icon-signin:before{content:"\f090";} -.icon-trophy:before{content:"\f091";} -.icon-github-sign:before{content:"\f092";} -.icon-upload-alt:before{content:"\f093";} -.icon-lemon:before{content:"\f094";} -.icon-phone:before{content:"\f095";} -.icon-unchecked:before,.icon-check-empty:before{content:"\f096";} -.icon-bookmark-empty:before{content:"\f097";} -.icon-phone-sign:before{content:"\f098";} -.icon-twitter:before{content:"\f099";} -.icon-facebook:before{content:"\f09a";} -.icon-github:before{content:"\f09b";} -.icon-unlock:before{content:"\f09c";} -.icon-credit-card:before{content:"\f09d";} -.icon-rss:before{content:"\f09e";} -.icon-hdd:before{content:"\f0a0";} -.icon-bullhorn:before{content:"\f0a1";} -.icon-bell:before{content:"\f0a2";} -.icon-certificate:before{content:"\f0a3";} -.icon-hand-right:before{content:"\f0a4";} -.icon-hand-left:before{content:"\f0a5";} -.icon-hand-up:before{content:"\f0a6";} -.icon-hand-down:before{content:"\f0a7";} -.icon-circle-arrow-left:before{content:"\f0a8";} -.icon-circle-arrow-right:before{content:"\f0a9";} -.icon-circle-arrow-up:before{content:"\f0aa";} -.icon-circle-arrow-down:before{content:"\f0ab";} -.icon-globe:before{content:"\f0ac";} -.icon-wrench:before{content:"\f0ad";} -.icon-tasks:before{content:"\f0ae";} -.icon-filter:before{content:"\f0b0";} -.icon-briefcase:before{content:"\f0b1";} -.icon-fullscreen:before{content:"\f0b2";} -.icon-group:before{content:"\f0c0";} -.icon-link:before{content:"\f0c1";} -.icon-cloud:before{content:"\f0c2";} -.icon-beaker:before{content:"\f0c3";} -.icon-cut:before{content:"\f0c4";} -.icon-copy:before{content:"\f0c5";} -.icon-paperclip:before,.icon-paper-clip:before{content:"\f0c6";} -.icon-save:before{content:"\f0c7";} -.icon-sign-blank:before{content:"\f0c8";} -.icon-reorder:before{content:"\f0c9";} -.icon-list-ul:before{content:"\f0ca";} -.icon-list-ol:before{content:"\f0cb";} -.icon-strikethrough:before{content:"\f0cc";} -.icon-underline:before{content:"\f0cd";} -.icon-table:before{content:"\f0ce";} -.icon-magic:before{content:"\f0d0";} -.icon-truck:before{content:"\f0d1";} -.icon-pinterest:before{content:"\f0d2";} -.icon-pinterest-sign:before{content:"\f0d3";} -.icon-google-plus-sign:before{content:"\f0d4";} -.icon-google-plus:before{content:"\f0d5";} -.icon-money:before{content:"\f0d6";} -.icon-caret-down:before{content:"\f0d7";} -.icon-caret-up:before{content:"\f0d8";} -.icon-caret-left:before{content:"\f0d9";} -.icon-caret-right:before{content:"\f0da";} -.icon-columns:before{content:"\f0db";} -.icon-sort:before{content:"\f0dc";} -.icon-sort-down:before{content:"\f0dd";} -.icon-sort-up:before{content:"\f0de";} -.icon-envelope:before{content:"\f0e0";} -.icon-linkedin:before{content:"\f0e1";} -.icon-rotate-left:before,.icon-undo:before{content:"\f0e2";} -.icon-legal:before{content:"\f0e3";} -.icon-dashboard:before{content:"\f0e4";} -.icon-comment-alt:before{content:"\f0e5";} -.icon-comments-alt:before{content:"\f0e6";} -.icon-bolt:before{content:"\f0e7";} -.icon-sitemap:before{content:"\f0e8";} -.icon-umbrella:before{content:"\f0e9";} -.icon-paste:before{content:"\f0ea";} -.icon-lightbulb:before{content:"\f0eb";} -.icon-exchange:before{content:"\f0ec";} -.icon-cloud-download:before{content:"\f0ed";} -.icon-cloud-upload:before{content:"\f0ee";} -.icon-user-md:before{content:"\f0f0";} -.icon-stethoscope:before{content:"\f0f1";} -.icon-suitcase:before{content:"\f0f2";} -.icon-bell-alt:before{content:"\f0f3";} -.icon-coffee:before{content:"\f0f4";} -.icon-food:before{content:"\f0f5";} -.icon-file-text-alt:before{content:"\f0f6";} -.icon-building:before{content:"\f0f7";} -.icon-hospital:before{content:"\f0f8";} -.icon-ambulance:before{content:"\f0f9";} -.icon-medkit:before{content:"\f0fa";} -.icon-fighter-jet:before{content:"\f0fb";} -.icon-beer:before{content:"\f0fc";} -.icon-h-sign:before{content:"\f0fd";} -.icon-plus-sign-alt:before{content:"\f0fe";} -.icon-double-angle-left:before{content:"\f100";} -.icon-double-angle-right:before{content:"\f101";} -.icon-double-angle-up:before{content:"\f102";} -.icon-double-angle-down:before{content:"\f103";} -.icon-angle-left:before{content:"\f104";} -.icon-angle-right:before{content:"\f105";} -.icon-angle-up:before{content:"\f106";} -.icon-angle-down:before{content:"\f107";} -.icon-desktop:before{content:"\f108";} -.icon-laptop:before{content:"\f109";} -.icon-tablet:before{content:"\f10a";} -.icon-mobile-phone:before{content:"\f10b";} -.icon-circle-blank:before{content:"\f10c";} -.icon-quote-left:before{content:"\f10d";} -.icon-quote-right:before{content:"\f10e";} -.icon-spinner:before{content:"\f110";} -.icon-circle:before{content:"\f111";} -.icon-mail-reply:before,.icon-reply:before{content:"\f112";} -.icon-github-alt:before{content:"\f113";} -.icon-folder-close-alt:before{content:"\f114";} -.icon-folder-open-alt:before{content:"\f115";} -.icon-expand-alt:before{content:"\f116";} -.icon-collapse-alt:before{content:"\f117";} -.icon-smile:before{content:"\f118";} -.icon-frown:before{content:"\f119";} -.icon-meh:before{content:"\f11a";} -.icon-gamepad:before{content:"\f11b";} -.icon-keyboard:before{content:"\f11c";} -.icon-flag-alt:before{content:"\f11d";} -.icon-flag-checkered:before{content:"\f11e";} -.icon-terminal:before{content:"\f120";} -.icon-code:before{content:"\f121";} -.icon-reply-all:before{content:"\f122";} -.icon-mail-reply-all:before{content:"\f122";} -.icon-star-half-full:before,.icon-star-half-empty:before{content:"\f123";} -.icon-location-arrow:before{content:"\f124";} -.icon-crop:before{content:"\f125";} -.icon-code-fork:before{content:"\f126";} -.icon-unlink:before{content:"\f127";} -.icon-question:before{content:"\f128";} -.icon-info:before{content:"\f129";} -.icon-exclamation:before{content:"\f12a";} -.icon-superscript:before{content:"\f12b";} -.icon-subscript:before{content:"\f12c";} -.icon-eraser:before{content:"\f12d";} -.icon-puzzle-piece:before{content:"\f12e";} -.icon-microphone:before{content:"\f130";} -.icon-microphone-off:before{content:"\f131";} -.icon-shield:before{content:"\f132";} -.icon-calendar-empty:before{content:"\f133";} -.icon-fire-extinguisher:before{content:"\f134";} -.icon-rocket:before{content:"\f135";} -.icon-maxcdn:before{content:"\f136";} -.icon-chevron-sign-left:before{content:"\f137";} -.icon-chevron-sign-right:before{content:"\f138";} -.icon-chevron-sign-up:before{content:"\f139";} -.icon-chevron-sign-down:before{content:"\f13a";} -.icon-html5:before{content:"\f13b";} -.icon-css3:before{content:"\f13c";} -.icon-anchor:before{content:"\f13d";} -.icon-unlock-alt:before{content:"\f13e";} -.icon-bullseye:before{content:"\f140";} -.icon-ellipsis-horizontal:before{content:"\f141";} -.icon-ellipsis-vertical:before{content:"\f142";} -.icon-rss-sign:before{content:"\f143";} -.icon-play-sign:before{content:"\f144";} -.icon-ticket:before{content:"\f145";} -.icon-minus-sign-alt:before{content:"\f146";} -.icon-check-minus:before{content:"\f147";} -.icon-level-up:before{content:"\f148";} -.icon-level-down:before{content:"\f149";} -.icon-check-sign:before{content:"\f14a";} -.icon-edit-sign:before{content:"\f14b";} -.icon-external-link-sign:before{content:"\f14c";} -.icon-share-sign:before{content:"\f14d";} -.icon-compass:before{content:"\f14e";} -.icon-collapse:before{content:"\f150";} -.icon-collapse-top:before{content:"\f151";} -.icon-expand:before{content:"\f152";} -.icon-euro:before,.icon-eur:before{content:"\f153";} -.icon-gbp:before{content:"\f154";} -.icon-dollar:before,.icon-usd:before{content:"\f155";} -.icon-rupee:before,.icon-inr:before{content:"\f156";} -.icon-yen:before,.icon-jpy:before{content:"\f157";} -.icon-renminbi:before,.icon-cny:before{content:"\f158";} -.icon-won:before,.icon-krw:before{content:"\f159";} -.icon-bitcoin:before,.icon-btc:before{content:"\f15a";} -.icon-file:before{content:"\f15b";} -.icon-file-text:before{content:"\f15c";} -.icon-sort-by-alphabet:before{content:"\f15d";} -.icon-sort-by-alphabet-alt:before{content:"\f15e";} -.icon-sort-by-attributes:before{content:"\f160";} -.icon-sort-by-attributes-alt:before{content:"\f161";} -.icon-sort-by-order:before{content:"\f162";} -.icon-sort-by-order-alt:before{content:"\f163";} -.icon-thumbs-up:before{content:"\f164";} -.icon-thumbs-down:before{content:"\f165";} -.icon-youtube-sign:before{content:"\f166";} -.icon-youtube:before{content:"\f167";} -.icon-xing:before{content:"\f168";} -.icon-xing-sign:before{content:"\f169";} -.icon-youtube-play:before{content:"\f16a";} -.icon-dropbox:before{content:"\f16b";} -.icon-stackexchange:before{content:"\f16c";} -.icon-instagram:before{content:"\f16d";} -.icon-flickr:before{content:"\f16e";} -.icon-adn:before{content:"\f170";} -.icon-bitbucket:before{content:"\f171";} -.icon-bitbucket-sign:before{content:"\f172";} -.icon-tumblr:before{content:"\f173";} -.icon-tumblr-sign:before{content:"\f174";} -.icon-long-arrow-down:before{content:"\f175";} -.icon-long-arrow-up:before{content:"\f176";} -.icon-long-arrow-left:before{content:"\f177";} -.icon-long-arrow-right:before{content:"\f178";} -.icon-apple:before{content:"\f179";} -.icon-windows:before{content:"\f17a";} -.icon-android:before{content:"\f17b";} -.icon-linux:before{content:"\f17c";} -.icon-dribbble:before{content:"\f17d";} -.icon-skype:before{content:"\f17e";} -.icon-foursquare:before{content:"\f180";} -.icon-trello:before{content:"\f181";} -.icon-female:before{content:"\f182";} -.icon-male:before{content:"\f183";} -.icon-gittip:before{content:"\f184";} -.icon-sun:before{content:"\f185";} -.icon-moon:before{content:"\f186";} -.icon-archive:before{content:"\f187";} -.icon-bug:before{content:"\f188";} -.icon-vk:before{content:"\f189";} -.icon-weibo:before{content:"\f18a";} -.icon-renren:before{content:"\f18b";} - -.icon-large{font-size:1.3333333333333333em;margin-top:-4px;padding-top:3px;margin-bottom:-4px;padding-bottom:3px;vertical-align:middle;} -.nav [class^="icon-"],.nav [class*=" icon-"]{vertical-align:inherit;margin-top:-4px;padding-top:3px;margin-bottom:-4px;padding-bottom:3px;}.nav [class^="icon-"].icon-large,.nav [class*=" icon-"].icon-large{vertical-align:-25%;} -.nav-pills [class^="icon-"].icon-large,.nav-tabs [class^="icon-"].icon-large,.nav-pills [class*=" icon-"].icon-large,.nav-tabs [class*=" icon-"].icon-large{line-height:.75em;margin-top:-7px;padding-top:5px;margin-bottom:-5px;padding-bottom:4px;} -.btn [class^="icon-"].pull-left,.btn [class*=" icon-"].pull-left,.btn [class^="icon-"].pull-right,.btn [class*=" icon-"].pull-right{vertical-align:inherit;} -.btn [class^="icon-"].icon-large,.btn [class*=" icon-"].icon-large{margin-top:-0.5em;} -a [class^="icon-"],a [class*=" icon-"]{cursor:pointer;} -.icon-glass{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-music{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-search{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-envelope-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-heart{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-star{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-star-empty{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-user{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-film{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-th-large{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-th{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-th-list{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-ok{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-remove{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-zoom-in{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-zoom-out{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-off{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-power-off{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-signal{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-cog{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-gear{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-trash{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-home{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-file-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-time{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-road{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-download-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-download{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-upload{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-inbox{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-play-circle{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-repeat{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-rotate-right{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-refresh{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-list-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-lock{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-flag{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-headphones{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-volume-off{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-volume-down{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-volume-up{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-qrcode{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-barcode{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-tag{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-tags{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-book{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-bookmark{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-print{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-camera{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-font{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-bold{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-italic{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-text-height{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-text-width{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-align-left{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-align-center{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-align-right{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-align-justify{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-list{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-indent-left{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-indent-right{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-facetime-video{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-picture{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-pencil{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-map-marker{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-adjust{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-tint{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-edit{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-share{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-check{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-move{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-step-backward{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-fast-backward{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-backward{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-play{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-pause{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-stop{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-forward{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-fast-forward{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-step-forward{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-eject{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-chevron-left{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-chevron-right{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-plus-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-minus-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-remove-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-ok-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-question-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-info-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-screenshot{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-remove-circle{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-ok-circle{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-ban-circle{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-arrow-left{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-arrow-right{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-arrow-up{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-arrow-down{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-share-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-mail-forward{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-resize-full{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-resize-small{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-plus{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-minus{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-asterisk{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-exclamation-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-gift{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-leaf{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-fire{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-eye-open{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-eye-close{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-warning-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-plane{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-calendar{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-random{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-comment{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-magnet{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-chevron-up{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-chevron-down{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-retweet{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-shopping-cart{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-folder-close{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-folder-open{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-resize-vertical{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-resize-horizontal{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-bar-chart{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-twitter-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-facebook-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-camera-retro{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-key{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-cogs{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-gears{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-comments{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-thumbs-up-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-thumbs-down-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-star-half{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-heart-empty{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-signout{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-linkedin-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-pushpin{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-external-link{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-signin{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-trophy{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-github-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-upload-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-lemon{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-phone{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-check-empty{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-unchecked{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-bookmark-empty{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-phone-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-twitter{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-facebook{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-github{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-unlock{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-credit-card{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-rss{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-hdd{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-bullhorn{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-bell{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-certificate{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-hand-right{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-hand-left{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-hand-up{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-hand-down{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-circle-arrow-left{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-circle-arrow-right{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-circle-arrow-up{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-circle-arrow-down{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-globe{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-wrench{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-tasks{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-filter{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-briefcase{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-fullscreen{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-group{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-link{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-cloud{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-beaker{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-cut{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-copy{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-paper-clip{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-paperclip{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-save{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-sign-blank{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-reorder{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-list-ul{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-list-ol{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-strikethrough{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-underline{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-table{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-magic{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-truck{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-pinterest{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-pinterest-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-google-plus-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-google-plus{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-money{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-caret-down{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-caret-up{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-caret-left{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-caret-right{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-columns{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-sort{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-sort-down{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-sort-up{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-envelope{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-linkedin{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-undo{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-rotate-left{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-legal{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-dashboard{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-comment-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-comments-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-bolt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-sitemap{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-umbrella{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-paste{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-lightbulb{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-exchange{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-cloud-download{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-cloud-upload{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-user-md{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-stethoscope{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-suitcase{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-bell-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-coffee{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-food{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-file-text-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-building{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-hospital{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-ambulance{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-medkit{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-fighter-jet{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-beer{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-h-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-plus-sign-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-double-angle-left{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-double-angle-right{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-double-angle-up{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-double-angle-down{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-angle-left{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-angle-right{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-angle-up{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-angle-down{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-desktop{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-laptop{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-tablet{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-mobile-phone{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-circle-blank{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-quote-left{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-quote-right{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-spinner{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-circle{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-reply{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-mail-reply{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-github-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-folder-close-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-folder-open-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-expand-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-collapse-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-smile{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-frown{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-meh{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-gamepad{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-keyboard{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-flag-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-flag-checkered{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-terminal{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-code{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-reply-all{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-mail-reply-all{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-star-half-empty{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-star-half-full{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-location-arrow{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-crop{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-code-fork{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-unlink{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-question{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-info{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-exclamation{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-superscript{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-subscript{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-eraser{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-puzzle-piece{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-microphone{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-microphone-off{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-shield{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-calendar-empty{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-fire-extinguisher{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-rocket{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-maxcdn{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-chevron-sign-left{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-chevron-sign-right{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-chevron-sign-up{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-chevron-sign-down{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-html5{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-css3{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-anchor{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-unlock-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-bullseye{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-ellipsis-horizontal{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-ellipsis-vertical{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-rss-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-play-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-ticket{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-minus-sign-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-check-minus{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-level-up{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-level-down{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-check-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-edit-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-external-link-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-share-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-compass{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-collapse{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-collapse-top{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-expand{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-eur{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-euro{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-gbp{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-usd{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-dollar{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-inr{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-rupee{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-jpy{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-yen{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-cny{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-renminbi{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-krw{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-won{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-btc{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-bitcoin{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-file{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-file-text{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-sort-by-alphabet{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-sort-by-alphabet-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-sort-by-attributes{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-sort-by-attributes-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-sort-by-order{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-sort-by-order-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-thumbs-up{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-thumbs-down{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-youtube-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-youtube{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-xing{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-xing-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-youtube-play{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-dropbox{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-stackexchange{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-instagram{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-flickr{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-adn{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-bitbucket{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-bitbucket-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-tumblr{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-tumblr-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-long-arrow-down{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-long-arrow-up{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-long-arrow-left{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-long-arrow-right{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-apple{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-windows{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-android{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-linux{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-dribbble{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-skype{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-foursquare{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-trello{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-female{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-male{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-gittip{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-sun{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-moon{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-archive{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-bug{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-vk{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-weibo{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-renren{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} \ No newline at end of file diff --git a/goon/browserassets/html/browserOutput.html b/goon/browserassets/html/browserOutput.html deleted file mode 100644 index 74212fd815..0000000000 --- a/goon/browserassets/html/browserOutput.html +++ /dev/null @@ -1,44 +0,0 @@ - - - - Chat - - - - - - - - -
- -
- Loading...

- If this takes longer than 30 seconds, it will automatically reload a maximum of 5 times.
- If it still doesn't work, use the bug report button at the top right of the window. -
-
-
- -
- - - - \ No newline at end of file diff --git a/goon/browserassets/js/browserOutput.js b/goon/browserassets/js/browserOutput.js deleted file mode 100644 index 0fb7386dd8..0000000000 --- a/goon/browserassets/js/browserOutput.js +++ /dev/null @@ -1,908 +0,0 @@ -/***************************************** -* -* FUNCTION AND VAR DECLARATIONS -* -******************************************/ - -//DEBUG STUFF -var escaper = encodeURIComponent || escape; -var decoder = decodeURIComponent || unescape; -window.onerror = function(msg, url, line, col, error) { - if (document.location.href.indexOf("proc=debug") <= 0) { - var extra = !col ? '' : ' | column: ' + col; - extra += !error ? '' : ' | error: ' + error; - extra += !navigator.userAgent ? '' : ' | user agent: ' + navigator.userAgent; - var debugLine = 'Error: ' + msg + ' | url: ' + url + ' | line: ' + line + extra; - window.location = '?_src_=chat&proc=debug¶m[error]='+escaper(debugLine); - } - return true; -}; - -//Globals -window.status = 'Output'; -var $messages, $subOptions, $contextMenu, $filterMessages; -var opts = { - //General - 'messageCount': 0, //A count...of messages... - 'messageLimit': 2053, //A limit...for the messages... - 'scrollSnapTolerance': 5, //If within x pixels of bottom - 'clickTolerance': 10, //Keep focus if outside x pixels of mousedown position on mouseup - 'popups': 0, //Amount of popups opened ever - 'wasd': false, //Is the user in wasd mode? - 'chatMode': 'default', //The mode the chat is in - 'priorChatHeight': 0, //Thing for height-resizing detection - 'restarting': false, //Is the round restarting? - - //Options menu - 'subOptionsLoop': null, //Contains the interval loop for closing the options menu - 'suppressOptionsClose': false, //Whether or not we should be hiding the suboptions menu - 'highlightTerms': [], - 'highlightLimit': 5, - 'highlightColor': '#FFFF00', //The color of the highlighted message - 'pingDisabled': false, //Has the user disabled the ping counter - - //Ping display - 'lastPang': 0, //Timestamp of the last response from the server. - 'pangLimit': 35000, - 'pingTime': 0, //Timestamp of when ping sent - 'pongTime': 0, //Timestamp of when ping received - 'noResponse': false, //Tracks the state of the previous ping request - 'noResponseCount': 0, //How many failed pings? - - //Clicks - 'mouseDownX': null, - 'mouseDownY': null, - 'preventFocus': false, //Prevents switching focus to the game window - - //Client Connection Data - 'clientDataLimit': 5, - 'clientData': [], - -}; - -function outerHTML(el) { - var wrap = document.createElement('div'); - wrap.appendChild(el.cloneNode(true)); - return wrap.innerHTML; -} - -//Polyfill for fucking date now because of course IE8 and below don't support it -if (!Date.now) { - Date.now = function now() { - return new Date().getTime(); - }; -} -//Polyfill for trim() (IE8 and below) -if (typeof String.prototype.trim !== 'function') { - String.prototype.trim = function () { - return this.replace(/^\s+|\s+$/g, ''); - }; -} - -//Shit fucking piece of crap that doesn't work god fuckin damn it -function linkify(text) { - var rex = /((?:'+$0+''; - } - else { - return $1 ? $0: ''+$0+''; - } - }); -} - -//Actually turns the highlight term match into appropriate html -function addHighlightMarkup(match) { - var extra = ''; - if (opts.highlightColor) { - extra += ' style="background-color: '+opts.highlightColor+'"'; - } - return ''+match+''; -} - -//Highlights words based on user settings -function highlightTerms(el) { - if (el.children.length > 0) { - for(var h = 0; h < el.children.length; h++){ - highlightTerms(el.children[h]); - } - } - - var hasTextNode = false; - for (var node = 0; node < el.childNodes.length; node++) - { - if (el.childNodes[node].nodeType === 3) - { - hasTextNode = true; - break; - } - } - - if (hasTextNode) { //If element actually has text - var newText = ''; - for (var c = 0; c < el.childNodes.length; c++) { //Each child element - if (el.childNodes[c].nodeType === 3) { //Is it text only? - var words = el.childNodes[c].data.split(' '); - for (var w = 0; w < words.length; w++) { //Each word in the text - var newWord = null; - for (var i = 0; i < opts.highlightTerms.length; i++) { //Each highlight term - if (opts.highlightTerms[i] && words[w].toLowerCase().indexOf(opts.highlightTerms[i].toLowerCase()) > -1) { //If a match is found - newWord = words[w].replace("<", "<").replace(new RegExp(opts.highlightTerms[i], 'gi'), addHighlightMarkup); - break; - } - console.log(newWord) - } - newText += newWord || words[w].replace("<", "<"); - newText += w >= words.length ? '' : ' '; - } - } else { //Every other type of element - newText += outerHTML(el.childNodes[c]); - } - } - el.innerHTML = newText; - } -} -//Send a message to the client -function output(message, flag) { - if (typeof message === 'undefined') { - return; - } - if (typeof flag === 'undefined') { - flag = ''; - } - - if (flag !== 'internal') - opts.lastPang = Date.now(); - - // Basically we url_encode twice server side so we can manually read the encoded version and actually do UTF-8. - // The replace for + is because FOR SOME REASON, BYOND replaces spaces with a + instead of %20, and a plus with %2b. - // Marvelous. - message = message.replace(/\+/g, "%20") - message = decoder(message) - - //The behemoth of filter-code (for Admin message filters) - //Note: This is proooobably hella inefficient - var filteredOut = false; - if (opts.hasOwnProperty('showMessagesFilters') && !opts.showMessagesFilters['All'].show) { - //Get this filter type (defined by class on message) - var messageHtml = $.parseHTML(message), - messageClasses; - if (opts.hasOwnProperty('filterHideAll') && opts.filterHideAll) { - var internal = false; - messageClasses = (!!$(messageHtml).attr('class') ? $(messageHtml).attr('class').split(/\s+/) : false); - if (messageClasses) { - for (var i = 0; i < messageClasses.length; i++) { //Every class - if (messageClasses[i] == 'internal') { - internal = true; - break; - } - } - } - if (!internal) { - filteredOut = 'All'; - } - } else { - //If the element or it's child have any classes - if (!!$(messageHtml).attr('class') || !!$(messageHtml).children().attr('class')) { - messageClasses = $(messageHtml).attr('class').split(/\s+/); - if (!!$(messageHtml).children().attr('class')) { - messageClasses = messageClasses.concat($(messageHtml).children().attr('class').split(/\s+/)); - } - var tempCount = 0; - for (var i = 0; i < messageClasses.length; i++) { //Every class - var thisClass = messageClasses[i]; - $.each(opts.showMessagesFilters, function(key, val) { //Every filter - if (key !== 'All' && val.show === false && typeof val.match != 'undefined') { - for (var i = 0; i < val.match.length; i++) { - var matchClass = val.match[i]; - if (matchClass == thisClass) { - filteredOut = key; - break; - } - } - } - if (filteredOut) return false; - }); - if (filteredOut) break; - tempCount++; - } - } else { - if (!opts.showMessagesFilters['Misc'].show) { - filteredOut = 'Misc'; - } - } - } - } - - //Stuff we do along with appending a message - var atBottom = false; - if (!filteredOut) { - var bodyHeight = $('body').height(); - var messagesHeight = $messages.outerHeight(); - var scrollPos = $('body,html').scrollTop(); - - //Should we snap the output to the bottom? - if (bodyHeight + scrollPos >= messagesHeight - opts.scrollSnapTolerance) { - atBottom = true; - if ($('#newMessages').length) { - $('#newMessages').remove(); - } - //If not, put the new messages box in - } else { - if ($('#newMessages').length) { - var messages = $('#newMessages .number').text(); - messages = parseInt(messages); - messages++; - $('#newMessages .number').text(messages); - if (messages == 2) { - $('#newMessages .messageWord').append('s'); - } - } else { - $messages.after('1 new message '); - } - } - } - - //Url stuff - if (message.length && flag != 'preventLink') { - message = linkify(message); - } - - opts.messageCount++; - - //Pop the top message off if history limit reached - if (opts.messageCount >= opts.messageLimit) { - $messages.children('div.entry:first-child').remove(); - opts.messageCount--; //I guess the count should only ever equal the limit - } - - //Actually append the message - var entry = document.createElement('div'); - entry.className = 'entry'; - - if (filteredOut) { - entry.className += ' hidden'; - entry.setAttribute('data-filter', filteredOut); - } - - entry.innerHTML = message.trim(); - $messages[0].appendChild(entry); - - //Actually do the snap - if (!filteredOut && atBottom) { - $('body,html').scrollTop($messages.outerHeight()); - } - - //Stuff we can do after the message shows can go here, in the interests of responsiveness - if (opts.highlightTerms && opts.highlightTerms.length > 0) { - highlightTerms(entry); - } -} - -function internalOutput(message, flag) -{ - output(escaper(message), flag) -} - -//Runs a route within byond, client or server side. Consider this "ehjax" for byond. -function runByond(uri) { - window.location = uri; -} - -function setCookie(cname, cvalue, exdays) { - cvalue = escaper(cvalue); - var d = new Date(); - d.setTime(d.getTime() + (exdays*24*60*60*1000)); - var expires = 'expires='+d.toUTCString(); - document.cookie = cname + '=' + cvalue + '; ' + expires; -} - -function getCookie(cname) { - var name = cname + '='; - var ca = document.cookie.split(';'); - for(var i=0; i < ca.length; i++) { - var c = ca[i]; - while (c.charAt(0)==' ') c = c.substring(1); - if (c.indexOf(name) === 0) { - return decoder(c.substring(name.length,c.length)); - } - } - return ''; -} - -function rgbToHex(R,G,B) {return toHex(R)+toHex(G)+toHex(B);} -function toHex(n) { - n = parseInt(n,10); - if (isNaN(n)) return "00"; - n = Math.max(0,Math.min(n,255)); - return "0123456789ABCDEF".charAt((n-n%16)/16) + "0123456789ABCDEF".charAt(n%16); -} - -function changeMode(mode) { - switch (mode) { - case 'geocities': - //switch in stylesheet - opts.chatMode = mode; - break; - case 'console': - - opts.chatMode = mode; - break; - case 'default': - default: - //remove loaded stylesheet/s - opts.chatMode = 'default'; - } -} - -function handleClientData(ckey, ip, compid) { - //byond sends player info to here - var currentData = {'ckey': ckey, 'ip': ip, 'compid': compid}; - if (opts.clientData && !$.isEmptyObject(opts.clientData)) { - runByond('?_src_=chat&proc=analyzeClientData¶m[cookie]='+JSON.stringify({'connData': opts.clientData})); - - for (var i = 0; i < opts.clientData.length; i++) { - var saved = opts.clientData[i]; - if (currentData.ckey == saved.ckey && currentData.ip == saved.ip && currentData.compid == saved.compid) { - return; //Record already exists - } - } - - if (opts.clientData.length >= opts.clientDataLimit) { - opts.clientData.shift(); - } - } else { - runByond('?_src_=chat&proc=analyzeClientData¶m[cookie]=none'); - } - - //Update the cookie with current details - opts.clientData.push(currentData); - setCookie('connData', JSON.stringify(opts.clientData), 365); -} - -//Server calls this on ehjax response -//Or, y'know, whenever really -function ehjaxCallback(data) { - opts.lastPang = Date.now(); - if (data == 'softPang') { - return; - } else if (data == 'pang') { - opts.pingCounter = 0; //reset - opts.pingTime = Date.now(); - runByond('?_src_=chat&proc=ping'); - - } else if (data == 'pong') { - if (opts.pingDisabled) {return;} - opts.pongTime = Date.now(); - var pingDuration = Math.ceil((opts.pongTime - opts.pingTime) / 2); - $('#pingMs').text(pingDuration+'ms'); - pingDuration = Math.min(pingDuration, 255); - var red = pingDuration; - var green = 255 - pingDuration; - var blue = 0; - var hex = rgbToHex(red, green, blue); - $('#pingDot').css('color', '#'+hex); - - } else if (data == 'roundrestart') { - opts.restarting = true; - internalOutput('
The connection has been closed because the server is restarting. Please wait while you automatically reconnect.
', 'internal'); - } else if (data == 'stopaudio') { - $('.dectalk').remove(); - } else { - //Oh we're actually being sent data instead of an instruction - var dataJ; - try { - dataJ = $.parseJSON(data); - } catch (e) { - //But...incorrect :sadtrombone: - window.onerror('JSON: '+e+'. '+data, 'browserOutput.html', 327); - return; - } - data = dataJ; - - if (data.clientData) { - if (opts.restarting) { - opts.restarting = false; - $('.connectionClosed.restarting:not(.restored)').addClass('restored').text('The round restarted and you successfully reconnected!'); - } - if (!data.clientData.ckey && !data.clientData.ip && !data.clientData.compid) { - //TODO: Call shutdown perhaps - return; - } else { - handleClientData(data.clientData.ckey, data.clientData.ip, data.clientData.compid); - } - } else if (data.modeChange) { - changeMode(data.modeChange); - } else if (data.firebug) { - if (data.trigger) { - internalOutput('Loading firebug console, triggered by '+data.trigger+'...', 'internal'); - } else { - internalOutput('Loading firebug console...', 'internal'); - } - var firebugEl = document.createElement('script'); - firebugEl.src = 'https://getfirebug.com/firebug-lite-debug.js'; - document.body.appendChild(firebugEl); - } else if (data.dectalk) { - var message = ''; - if (data.decTalkTrigger) { - message = ' '+ - 'You hear a strange robotic voice...' + message; - } - internalOutput(message, 'preventLink'); - } - } -} - -function createPopup(contents, width) { - opts.popups++; - $('body').append(''); - - //Attach close popup event - var $popup = $('#popup'+opts.popups); - var height = $popup.outerHeight(); - $popup.css({'height': height+'px', 'margin': '-'+(height/2)+'px 0 0 -'+(width/2)+'px'}); - - $popup.on('click', '.close', function(e) { - e.preventDefault(); - $popup.remove(); - }); -} - -function toggleWasd(state) { - opts.wasd = (state == 'on' ? true : false); -} - -/***************************************** -* -* DOM READY -* -******************************************/ - -if (typeof $ === 'undefined') { - var div = document.getElementById('loading').childNodes[1]; - div += '

ERROR: Jquery did not load.'; -} - -$(function() { - $messages = $('#messages'); - $subOptions = $('#subOptions'); - - //Hey look it's a controller loop! - setInterval(function() { - if (opts.lastPang + opts.pangLimit < Date.now() && !opts.restarting) { //Every pingLimit - if (!opts.noResponse) { //Only actually append a message if the previous ping didn't also fail (to prevent spam) - opts.noResponse = true; - opts.noResponseCount++; - internalOutput('
You are either AFK, experiencing lag or the connection has closed.
', 'internal'); - } - } else if (opts.noResponse) { //Previous ping attempt failed ohno - $('.connectionClosed[data-count="'+opts.noResponseCount+'"]:not(.restored)').addClass('restored').text('Your connection has been restored (probably)!'); - opts.noResponse = false; - } - }, 2000); //2 seconds - - - /***************************************** - * - * LOAD SAVED CONFIG - * - ******************************************/ - var savedConfig = { - 'sfontSize': getCookie('fontsize'), - 'sfontType': getCookie('fonttype'), - 'spingDisabled': getCookie('pingdisabled'), - 'shighlightTerms': getCookie('highlightterms'), - 'shighlightColor': getCookie('highlightcolor'), - }; - - if (savedConfig.sfontSize) { - $messages.css('font-size', savedConfig.sfontSize); - internalOutput('Loaded font size setting of: '+savedConfig.sfontSize+'', 'internal'); - } - if (savedConfig.sfontType) { - $messages.css('font-family', savedConfig.sfontType); - internalOutput('Loaded font type setting of: '+savedConfig.sfontType+'', 'internal'); - } - if (savedConfig.spingDisabled) { - if (savedConfig.spingDisabled == 'true') { - opts.pingDisabled = true; - $('#ping').hide(); - } - internalOutput('Loaded ping display of: '+(opts.pingDisabled ? 'hidden' : 'visible')+'', 'internal'); - } - if (savedConfig.shighlightTerms) { - var savedTerms = $.parseJSON(savedConfig.shighlightTerms); - var actualTerms = ''; - for (var i = 0; i < savedTerms.length; i++) { - if (savedTerms[i]) { - actualTerms += savedTerms[i] + ', '; - } - } - if (actualTerms) { - actualTerms = actualTerms.substring(0, actualTerms.length - 2); - internalOutput('Loaded highlight strings of: ' + actualTerms+'', 'internal'); - opts.highlightTerms = savedTerms; - } - } - if (savedConfig.shighlightColor) { - opts.highlightColor = savedConfig.shighlightColor; - internalOutput('Loaded highlight color of: '+savedConfig.shighlightColor+'', 'internal'); - } - - (function() { - var dataCookie = getCookie('connData'); - if (dataCookie) { - var dataJ; - try { - dataJ = $.parseJSON(dataCookie); - } catch (e) { - window.onerror('JSON '+e+'. '+dataCookie, 'browserOutput.html', 434); - return; - } - opts.clientData = dataJ; - } - })(); - - - /***************************************** - * - * BASE CHAT OUTPUT EVENTS - * - ******************************************/ - - $('body').on('click', 'a', function(e) { - e.preventDefault(); - }); - - $('body').on('mousedown', function(e) { - var $target = $(e.target); - - if ($contextMenu && opts.hasOwnProperty('contextMenuTarget') && opts.contextMenuTarget) { - hideContextMenu(); - return false; - } - - if ($target.is('a') || $target.parent('a').length || $target.is('input') || $target.is('textarea')) { - opts.preventFocus = true; - } else { - opts.preventFocus = false; - opts.mouseDownX = e.pageX; - opts.mouseDownY = e.pageY; - } - }); - - $messages.on('mousedown', function(e) { - if ($subOptions && $subOptions.is(':visible')) { - $subOptions.slideUp('fast', function() { - $(this).removeClass('scroll'); - $(this).css('height', ''); - }); - clearInterval(opts.subOptionsLoop); - } - }); - - $('body').on('mouseup', function(e) { - if (!opts.preventFocus && - (e.pageX >= opts.mouseDownX - opts.clickTolerance && e.pageX <= opts.mouseDownX + opts.clickTolerance) && - (e.pageY >= opts.mouseDownY - opts.clickTolerance && e.pageY <= opts.mouseDownY + opts.clickTolerance) - ) { - opts.mouseDownX = null; - opts.mouseDownY = null; - runByond('byond://winset?mapwindow.map.focus=true'); - } - }); - - $messages.on('click', 'a', function(e) { - var href = $(this).attr('href'); - $(this).addClass('visited'); - if (href[0] == '?' || (href.length >= 8 && href.substring(0,8) == 'byond://')) { - runByond(href); - } else { - href = escaper(href); - runByond('?action=openLink&link='+href); - } - }); - - //Fuck everything about this event. Will look into alternatives. - $('body').on('keydown', function(e) { - if (e.target.nodeName == 'INPUT' || e.target.nodeName == 'TEXTAREA') { - return; - } - - if (e.ctrlKey || e.altKey || e.shiftKey) { //Band-aid "fix" for allowing ctrl+c copy paste etc. Needs a proper fix. - return; - } - - e.preventDefault() - - var k = e.which; - var command; // Command to execute through winset. - - // Hardcoded because else there would be no feedback message. - if (k == 113) { // F2 - runByond('byond://winset?screenshot=auto'); - internalOutput('Screenshot taken', 'internal'); - } - - var c = ""; - switch (k) { - case 8: - c = 'BACK'; - case 9: - c = 'TAB'; - case 13: - c = 'ENTER'; - case 19: - c = 'PAUSE'; - case 27: - c = 'ESCAPE'; - case 33: // Page up - c = 'NORTHEAST'; - case 34: // Page down - c = 'SOUTHEAST'; - case 35: // End - c = 'SOUTHWEST'; - case 36: // Home - c = 'NORTHWEST'; - case 37: - c = 'WEST'; - case 38: - c = 'NORTH'; - case 39: - c = 'EAST'; - case 40: - c = 'SOUTH'; - case 45: - c = 'INSERT'; - case 46: - c = 'DELETE'; - case 93: // That weird thing to the right of alt gr. - c = 'APPS'; - - default: - c = String.fromCharCode(k); - } - -// if(opts.macros.hasOwnProperty(c.toUpperCase())) - // command = opts.macros[c]; - - if (command) { - runByond('byond://winset?mapwindow.map.focus=true;command='+command); - return false; - } - else if (c.length == 0) { - if (!e.shiftKey) { - c = c.toLowerCase(); - } - runByond('byond://winset?mapwindow.map.focus=true;mainwindow.input.text='+c); - return false; - } else { - runByond('byond://winset?mapwindow.map.focus=true'); - return false; - } - }); - - //Mildly hacky fix for scroll issues on mob change (interface gets resized sometimes, messing up snap-scroll) - $(window).on('resize', function(e) { - if ($(this).height() !== opts.priorChatHeight) { - $('body,html').scrollTop($messages.outerHeight()); - opts.priorChatHeight = $(this).height(); - } - }); - - //Audio sound prevention - $messages.on('click', '.stopAudio', function() { - var $audio = $(this).parent().children('audio'); - if ($audio) { - $audio.remove(); - } - }); - - - /***************************************** - * - * OPTIONS INTERFACE EVENTS - * - ******************************************/ - - $('body').on('click', '#newMessages', function(e) { - var messagesHeight = $messages.outerHeight(); - $('body,html').scrollTop(messagesHeight); - $('#newMessages').remove(); - runByond('byond://winset?mapwindow.map.focus=true'); - }); - - $('#toggleOptions').click(function(e) { - if ($subOptions.is(':visible')) { - $subOptions.slideUp('fast', function() { - $(this).removeClass('scroll'); - $(this).css('height', ''); - }); - clearInterval(opts.subOptionsLoop); - } else { - $subOptions.slideDown('fast', function() { - var windowHeight = $(window).height(); - var toggleHeight = $('#toggleOptions').outerHeight(); - var priorSubHeight = $subOptions.outerHeight(); - var newSubHeight = windowHeight - toggleHeight; - $(this).height(newSubHeight); - if (priorSubHeight > (windowHeight - toggleHeight)) { - $(this).addClass('scroll'); - } - }); - opts.subOptionsLoop = setInterval(function() { - if (!opts.suppressOptionsClose && $('#subOptions').is(':visible')) { - $subOptions.slideUp('fast', function() { - $(this).removeClass('scroll'); - $(this).css('height', ''); - }); - clearInterval(opts.subOptionsLoop); - } - }, 5000); //Every 5 seconds - } - }); - - $('#subOptions, #toggleOptions').mouseenter(function() { - opts.suppressOptionsClose = true; - }); - - $('#subOptions, #toggleOptions').mouseleave(function() { - opts.suppressOptionsClose = false; - }); - - $('#decreaseFont').click(function(e) { - var fontSize = parseInt($messages.css('font-size')); - fontSize = fontSize - 1 + 'px'; - $messages.css({'font-size': fontSize}); - setCookie('fontsize', fontSize, 365); - internalOutput('Font size set to '+fontSize+'', 'internal'); - }); - - $('#increaseFont').click(function(e) { - var fontSize = parseInt($messages.css('font-size')); - fontSize = fontSize + 1 + 'px'; - $messages.css({'font-size': fontSize}); - setCookie('fontsize', fontSize, 365); - internalOutput('Font size set to '+fontSize+'', 'internal'); - }); - - $('#chooseFont').click(function(e) { - if ($('.popup .changeFont').is(':visible')) {return;} - var popupContent = '
Change Font
' + - ''; - createPopup(popupContent, 200); - }); - - $('body').on('click', '#changeFont a', function(e) { - var font = $(this).attr('data-font'); - $messages.css('font-family', font); - setCookie('fonttype', font, 365); - }); - - $('#togglePing').click(function(e) { - if (opts.pingDisabled) { - $('#ping').slideDown('fast'); - opts.pingDisabled = false; - } else { - $('#ping').slideUp('fast'); - opts.pingDisabled = true; - } - setCookie('pingdisabled', (opts.pingDisabled ? 'true' : 'false'), 365); - }); - - $('#saveLog').click(function(e) { - var saved = ''; - - if (window.XMLHtpRequest) { - xmlHttp = new XMLHttpRequest(); - } else { - xmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); - } - xmlHttp.open('GET', 'browserOutput.css', false); - xmlHttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded'); - xmlHttp.send(); - saved += ''; - - saved += $messages.html(); - saved = saved.replace(/&/g, '&'); - saved = saved.replace(/'; - } - var popupContent = '
String Highlighting
' + - '
' + - '
Choose up to '+opts.highlightLimit+' strings that will highlight the line when they appear in chat.
' + - '
' + - termInputs + - '
' + - '
' + - '
' + - '
'; - createPopup(popupContent, 250); - }); - - $('body').on('keyup', '#highlightColor', function() { - var color = $('#highlightColor').val(); - color = color.trim(); - if (!color || color.charAt(0) != '#') return; - $('#highlightColor').css('background-color', color); - }); - - $('body').on('submit', '#highlightTermForm', function(e) { - e.preventDefault(); - - var count = 0; - while (count < opts.highlightLimit) { - var term = $('#highlightTermInput'+count).val(); - if (term) { - term = term.trim(); - if (term === '') { - opts.highlightTerms[count] = null; - } else { - opts.highlightTerms[count] = term.toLowerCase(); - } - } else { - opts.highlightTerms[count] = null; - } - count++; - } - - var color = $('#highlightColor').val(); - color = color.trim(); - if (color == '' || color.charAt(0) != '#') { - opts.highlightColor = '#FFFF00'; - } else { - opts.highlightColor = color; - } - var $popup = $('#highlightPopup').closest('.popup'); - $popup.remove(); - - setCookie('highlightterms', JSON.stringify(opts.highlightTerms), 365); - setCookie('highlightcolor', opts.highlightColor, 365); - }); - - $('#clearMessages').click(function() { - $messages.empty(); - opts.messageCount = 0; - }); - - - /***************************************** - * - * KICK EVERYTHING OFF - * - ******************************************/ - - runByond('?_src_=chat&proc=doneLoading'); - if ($('#loading').is(':visible')) { - $('#loading').remove(); - } - $('#userBar').show(); - opts.priorChatHeight = $(window).height(); -}); \ No newline at end of file diff --git a/goon/browserassets/js/json2.min.js b/goon/browserassets/js/json2.min.js deleted file mode 100644 index d867407f26..0000000000 --- a/goon/browserassets/js/json2.min.js +++ /dev/null @@ -1 +0,0 @@ -"object"!=typeof JSON&&(JSON={}),function(){"use strict";function f(t){return 10>t?"0"+t:t}function this_value(){return this.valueOf()}function quote(t){return rx_escapable.lastIndex=0,rx_escapable.test(t)?'"'+t.replace(rx_escapable,function(t){var e=meta[t];return"string"==typeof e?e:"\\u"+("0000"+t.charCodeAt(0).toString(16)).slice(-4)})+'"':'"'+t+'"'}function str(t,e){var r,n,o,u,f,a=gap,i=e[t];switch(i&&"object"==typeof i&&"function"==typeof i.toJSON&&(i=i.toJSON(t)),"function"==typeof rep&&(i=rep.call(e,t,i)),typeof i){case"string":return quote(i);case"number":return isFinite(i)?String(i):"null";case"boolean":case"null":return String(i);case"object":if(!i)return"null";if(gap+=indent,f=[],"[object Array]"===Object.prototype.toString.apply(i)){for(u=i.length,r=0;u>r;r+=1)f[r]=str(r,i)||"null";return o=0===f.length?"[]":gap?"[\n"+gap+f.join(",\n"+gap)+"\n"+a+"]":"["+f.join(",")+"]",gap=a,o}if(rep&&"object"==typeof rep)for(u=rep.length,r=0;u>r;r+=1)"string"==typeof rep[r]&&(n=rep[r],o=str(n,i),o&&f.push(quote(n)+(gap?": ":":")+o));else for(n in i)Object.prototype.hasOwnProperty.call(i,n)&&(o=str(n,i),o&&f.push(quote(n)+(gap?": ":":")+o));return o=0===f.length?"{}":gap?"{\n"+gap+f.join(",\n"+gap)+"\n"+a+"}":"{"+f.join(",")+"}",gap=a,o}}var rx_one=/^[\],:{}\s]*$/,rx_two=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,rx_three=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,rx_four=/(?:^|:|,)(?:\s*\[)+/g,rx_escapable=/[\\\"\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,rx_dangerous=/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;"function"!=typeof Date.prototype.toJSON&&(Date.prototype.toJSON=function(){return isFinite(this.valueOf())?this.getUTCFullYear()+"-"+f(this.getUTCMonth()+1)+"-"+f(this.getUTCDate())+"T"+f(this.getUTCHours())+":"+f(this.getUTCMinutes())+":"+f(this.getUTCSeconds())+"Z":null},Boolean.prototype.toJSON=this_value,Number.prototype.toJSON=this_value,String.prototype.toJSON=this_value);var gap,indent,meta,rep;"function"!=typeof JSON.stringify&&(meta={"\b":"\\b"," ":"\\t","\n":"\\n","\f":"\\f","\r":"\\r",'"':'\\"',"\\":"\\\\"},JSON.stringify=function(t,e,r){var n;if(gap="",indent="","number"==typeof r)for(n=0;r>n;n+=1)indent+=" ";else"string"==typeof r&&(indent=r);if(rep=e,e&&"function"!=typeof e&&("object"!=typeof e||"number"!=typeof e.length))throw new Error("JSON.stringify");return str("",{"":t})}),"function"!=typeof JSON.parse&&(JSON.parse=function(text,reviver){function walk(t,e){var r,n,o=t[e];if(o&&"object"==typeof o)for(r in o)Object.prototype.hasOwnProperty.call(o,r)&&(n=walk(o,r),void 0!==n?o[r]=n:delete o[r]);return reviver.call(t,e,o)}var j;if(text=String(text),rx_dangerous.lastIndex=0,rx_dangerous.test(text)&&(text=text.replace(rx_dangerous,function(t){return"\\u"+("0000"+t.charCodeAt(0).toString(16)).slice(-4)})),rx_one.test(text.replace(rx_two,"@").replace(rx_three,"]").replace(rx_four,"")))return j=eval("("+text+")"),"function"==typeof reviver?walk({"":j},""):j;throw new SyntaxError("JSON.parse")})}(); \ No newline at end of file diff --git a/goon/code/datums/browserOutput.dm b/goon/code/datums/browserOutput.dm deleted file mode 100644 index d928397728..0000000000 --- a/goon/code/datums/browserOutput.dm +++ /dev/null @@ -1,289 +0,0 @@ -/********************************* -For the main html chat area -*********************************/ - -//Precaching a bunch of shit -GLOBAL_DATUM_INIT(iconCache, /savefile, new("data/iconCache.sav")) //Cache of icons for the browser output - -//On client, created on login -/datum/chatOutput - var/client/owner //client ref - var/loaded = FALSE // Has the client loaded the browser output area? - var/list/messageQueue //If they haven't loaded chat, this is where messages will go until they do - var/cookieSent = FALSE // Has the client sent a cookie for analysis - var/list/connectionHistory //Contains the connection history passed from chat cookie - var/broken = FALSE - -/datum/chatOutput/New(client/C) - owner = C - messageQueue = list() - connectionHistory = list() - // log_world("chatOutput: New()") - -/datum/chatOutput/proc/start() - //Check for existing chat - if(!owner) - return FALSE - - if(!winexists(owner, "browseroutput")) // Oh goddamnit. - alert(owner.mob, "Updated chat window does not exist. If you are using a custom skin file please allow the game to update.") - broken = TRUE - return FALSE - - if(winget(owner, "browseroutput", "is-disabled") == "false") //Already setup - doneLoading() - - else //Not setup - load() - - return TRUE - -/datum/chatOutput/proc/load() - set waitfor = FALSE - if(!owner) - return - - var/static/list/chatResources = list( - "code/modules/html_interface/js/jquery.min.js", - "goon/browserassets/js/json2.min.js", - "goon/browserassets/js/browserOutput.js", - "tgui/assets/fonts/fontawesome-webfont.eot", - "tgui/assets/fonts/fontawesome-webfont.svg", - "tgui/assets/fonts/fontawesome-webfont.ttf", - "tgui/assets/fonts/fontawesome-webfont.woff", - "goon/browserassets/css/font-awesome.css", - "goon/browserassets/css/browserOutput.css" - ) - - // to_chat(world.log, "chatOutput: load()") - for(var/attempts in 1 to 5) - for(var/asset in chatResources) - owner << browse_rsc(file(asset)) - - //log_world("Sending main chat window to client [owner.ckey]") - owner << browse(file("goon/browserassets/html/browserOutput.html"), "window=browseroutput") - sleep(14 + (chatResources.len * 7)) - if(!owner || loaded) - break - - if(owner && !loaded) - doneLoading() // try doing this manually - CRASH("[owner] failed to load chat. Attempting doneLoading() manually") - // log_world("chatOutput: [owner.ckey] load() completed") - -/datum/chatOutput/Topic(href, list/href_list) - if(usr.client != owner) - return TRUE - - // Build arguments. - // Arguments are in the form "param[paramname]=thing" - var/list/params = list() - for(var/key in href_list) - if(length(key) > 7 && findtext(key, "param")) // 7 is the amount of characters in the basic param key template. - var/param_name = copytext(key, 7, -1) - var/item = href_list[key] - - params[param_name] = item - - var/data // Data to be sent back to the chat. - switch(href_list["proc"]) - if("doneLoading") - data = doneLoading(arglist(params)) - - if("debug") - data = debug(arglist(params)) - - if("ping") - data = ping(arglist(params)) - - if("analyzeClientData") - data = analyzeClientData(arglist(params)) - - if(data) - ehjax_send(data = data) - -//Called on chat output done-loading by JS. -/datum/chatOutput/proc/doneLoading() - if(loaded) - return - - loaded = TRUE - winset(owner, "browseroutput", "is-disabled=false") - for(var/message in messageQueue) - to_chat(owner, message) - - messageQueue = null - sendClientData() - - pingLoop() - -/datum/chatOutput/proc/pingLoop() - set waitfor = FALSE - - while (owner) - ehjax_send(data = owner.is_afk(29) ? "softPang" : "pang") // SoftPang isn't handled anywhere but it'll always reset the opts.lastPang. - sleep(30) - -/datum/chatOutput/proc/ehjax_send(client/C = owner, window = "browseroutput", data) - if(islist(data)) - data = json_encode(data) - C << output("[data]", "[window]:ehjaxCallback") - -//Sends client connection details to the chat to handle and save -/datum/chatOutput/proc/sendClientData() - //Get dem deets - var/list/deets = list("clientData" = list()) - deets["clientData"]["ckey"] = owner.ckey - deets["clientData"]["ip"] = owner.address - deets["clientData"]["compid"] = owner.computer_id - var/data = json_encode(deets) - ehjax_send(data = data) - -//Called by client, sent data to investigate (cookie history so far) -/datum/chatOutput/proc/analyzeClientData(cookie = "") - if(!cookie) - return - - if(cookie != "none") - var/list/connData = json_decode(cookie) - if (connData && islist(connData) && connData.len > 0 && connData["connData"]) - connectionHistory = connData["connData"] //lol fuck - var/list/found = new() - for(var/i in connectionHistory.len to 1 step -1) - var/list/row = src.connectionHistory[i] - if (!row || row.len < 3 || (!row["ckey"] && !row["compid"] && !row["ip"])) //Passed malformed history object - return - if (world.IsBanned(row["ckey"], row["compid"], row["ip"])) - found = row - break - - //Uh oh this fucker has a history of playing on a banned account!! - if (found.len > 0) - //TODO: add a new evasion ban for the CURRENT client details, using the matched row details - message_admins("[key_name(src.owner)] has a cookie from a banned account! (Matched: [found["ckey"]], [found["ip"]], [found["compid"]])") - log_admin("[key_name(src.owner)] has a cookie from a banned account! (Matched: [found["ckey"]], [found["ip"]], [found["compid"]])") - - cookieSent = TRUE - -//Called by js client every 60 seconds -/datum/chatOutput/proc/ping() - return "pong" - -//Called by js client on js error -/datum/chatOutput/proc/debug(error) - log_world("\[[time2text(world.realtime, "YYYY-MM-DD hh:mm:ss")]\] Client: [(src.owner.key ? src.owner.key : src.owner)] triggered JS error: [error]") - -#ifdef TESTING -/client/verb/debug_chat() - set hidden = TRUE - chatOutput.ehjax_send(data = list("firebug" = TRUE)) -#endif -//Global chat procs - -GLOBAL_LIST_EMPTY(bicon_cache) - -//Converts an icon to base64. Operates by putting the icon in the iconCache savefile, -// exporting it as text, and then parsing the base64 from that. -// (This relies on byond automatically storing icons in savefiles as base64) -/proc/icon2base64(icon/icon, iconKey = "misc") - if (!isicon(icon)) - return FALSE - GLOB.iconCache[iconKey] << icon - var/iconData = GLOB.iconCache.ExportText(iconKey) - var/list/partial = splittext(iconData, "{") - return replacetext(copytext(partial[2], 3, -5), "\n", "") - -/proc/bicon(obj) - if (!obj) - return - - if (isicon(obj)) - //Icons get pooled constantly, references are no good here. - /*if (!bicon_cache["\ref[obj]"]) // Doesn't exist yet, make it. - bicon_cache["\ref[obj]"] = icon2base64(obj) - return ""*/ - return "" - - // Either an atom or somebody fucked up and is gonna get a runtime, which I'm fine with. - var/atom/A = obj - var/key = "[istype(A.icon, /icon) ? "\ref[A.icon]" : A.icon]:[A.icon_state]" - if (!GLOB.bicon_cache[key]) // Doesn't exist, make it. - var/icon/I = icon(A.icon, A.icon_state, SOUTH, 1) - if (ishuman(obj)) // Shitty workaround for a BYOND issue. - var/icon/temp = I - I = icon() - I.Insert(temp, dir = SOUTH) - GLOB.bicon_cache[key] = icon2base64(I, key) - - return "" - -//Costlier version of bicon() that uses getFlatIcon() to account for overlays, underlays, etc. Use with extreme moderation, ESPECIALLY on mobs. -/proc/costly_bicon(obj) - if (!obj) - return - - if (isicon(obj)) - return bicon(obj) - - var/icon/I = getFlatIcon(obj) - return bicon(I) - -/proc/to_chat(target, message) - if(isnull(target)) - return - //Ok so I did my best but I accept that some calls to this will be for shit like sound and images - //It stands that we PROBABLY don't want to output those to the browser output so just handle them here - if (istype(message, /image) || istype(message, /sound) || istype(target, /savefile) || !(ismob(target) || islist(target) || istype(target, /client) || istype(target, /datum/log) || target == world)) - target << message - if (!istype(target, /atom)) // Really easy to mix these up, and not having to make sure things are mobs makes the code cleaner. - CRASH("DEBUG: Boutput called with invalid message") - return - - //Otherwise, we're good to throw it at the user - else if (istext(message)) - if (istext(target)) - return - - //Some macros remain in the string even after parsing and fuck up the eventual output - if (findtext(message, "\improper")) - message = replacetext(message, "\improper", "") - if (findtext(message, "\proper")) - message = replacetext(message, "\proper", "") - - //Grab us a client if possible - var/client/C = grab_client(target) - - if (C && C.chatOutput) - if(C.chatOutput.broken) // A player who hasn't updated his skin file. - to_chat(C, message) - return TRUE - if(!C.chatOutput.loaded && C.chatOutput.messageQueue && islist(C.chatOutput.messageQueue)) - //Client sucks at loading things, put their messages in a queue - C.chatOutput.messageQueue.Add(message) - return - - if(istype(target, /datum/log)) - var/datum/log/L = target - L.log += (message + "\n") - return - - message = replacetext(message, "\n", "
") - message = replacetext(message, "\t", "    ") - - // url_encode it TWICE, this way any UTF-8 characters are able to be decoded by the Javascript. - target << output(url_encode(url_encode(message)), "browseroutput:output") - -/proc/grab_client(target) - if(istype(target, /client)) - return target - else if(istype(target, /mob)) - var/mob/M = target - if(M.client) - return M.client - else if(istype(target, /datum/mind)) - var/datum/mind/M = target - if(M.current && M.current.client) - return M.current.client - -/datum/log //exists purely to capture to_chat() output - var/log = "" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-8416.yml b/html/changelogs/AutoChangeLog-pr-8416.yml new file mode 100644 index 0000000000..34bac362be --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8416.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - rscadd: "adds the sec jetpack to sec hardsuit storge" diff --git a/html/changelogs/AutoChangeLog-pr-8497.yml b/html/changelogs/AutoChangeLog-pr-8497.yml new file mode 100644 index 0000000000..4c42899313 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8497.yml @@ -0,0 +1,5 @@ +author: "BurgerBB" +delete-after: True +changes: + - rscadd: "Adds clockwork reflectors, a fragile anti-laser reflection shield object that can be constructed for 10 brass sheets. Upon firing on the object in the direction where it is shielded, it ricochets the bullet off of it relative to the shooting angle." + - tweak: "Renames some windows in the build menu for consistency." diff --git a/html/changelogs/AutoChangeLog-pr-8505.yml b/html/changelogs/AutoChangeLog-pr-8505.yml new file mode 100644 index 0000000000..57d6399680 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8505.yml @@ -0,0 +1,4 @@ +author: "BurgerBB" +delete-after: True +changes: + - balance: "Clockwork Cult walls can no longer be deconstructed by RCDs when heated." diff --git a/html/changelogs/AutoChangeLog-pr-8561.yml b/html/changelogs/AutoChangeLog-pr-8561.yml new file mode 100644 index 0000000000..dca2bff2ff --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8561.yml @@ -0,0 +1,4 @@ +author: "Ghommie (Original PR by JJRcop)" +delete-after: True +changes: + - rscadd: "Ports in more emojis, including : flushed :" diff --git a/html/changelogs/AutoChangeLog-pr-8570.yml b/html/changelogs/AutoChangeLog-pr-8570.yml new file mode 100644 index 0000000000..787b486685 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8570.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - rscadd: "origami" diff --git a/html/changelogs/AutoChangeLog-pr-8578.yml b/html/changelogs/AutoChangeLog-pr-8578.yml new file mode 100644 index 0000000000..39ded33f2d --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8578.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - spellcheck: "Properly rewords the extinguisher's instructions on how to empty it on the floor since it was changed to be a screwdriver action instead of Alt Click a while ago." diff --git a/html/changelogs/AutoChangeLog-pr-8579.yml b/html/changelogs/AutoChangeLog-pr-8579.yml new file mode 100644 index 0000000000..56ecea119f --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8579.yml @@ -0,0 +1,5 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - rscadd: "gang tower shield" + - tweak: "costs of boots" diff --git a/html/changelogs/AutoChangeLog-pr-8584.yml b/html/changelogs/AutoChangeLog-pr-8584.yml new file mode 100644 index 0000000000..2621812d64 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8584.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - rscadd: "organ box" diff --git a/html/changelogs/AutoChangeLog-pr-8602.yml b/html/changelogs/AutoChangeLog-pr-8602.yml new file mode 100644 index 0000000000..4974c1ae79 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8602.yml @@ -0,0 +1,5 @@ +author: "Poojawa" +delete-after: True +changes: + - rscadd: "Added an underwear toggle button under 'Object' tab" + - tweak: "Genitals now layer under underwear. Hide these if they're too obnoxious." diff --git a/html/changelogs/AutoChangeLog-pr-8614.yml b/html/changelogs/AutoChangeLog-pr-8614.yml new file mode 100644 index 0000000000..e9473181fb --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8614.yml @@ -0,0 +1,4 @@ +author: "Ghommie (original PR by SpaceManiac)" +delete-after: True +changes: + - bugfix: "Disassembling a chem dispenser for the first time will no longer always yield a fully-charged cell." diff --git a/html/changelogs/AutoChangeLog-pr-8618.yml b/html/changelogs/AutoChangeLog-pr-8618.yml new file mode 100644 index 0000000000..77ba2439a1 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8618.yml @@ -0,0 +1,7 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - rscadd: "New cargo crate for tech-slugs!" + - rscadd: "Ammo to each fitting crate" + - bugfix: "Cat-code" + - spellcheck: "fixed a few typos - Again my bad" diff --git a/html/changelogs/AutoChangeLog-pr-8643.yml b/html/changelogs/AutoChangeLog-pr-8643.yml new file mode 100644 index 0000000000..b172071e2e --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8643.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - bugfix: "The sacrificial target icon will now display onto the cult objective ui alert once again." diff --git a/html/changelogs/AutoChangeLog-pr-8648.yml b/html/changelogs/AutoChangeLog-pr-8648.yml new file mode 100644 index 0000000000..8d0f9d20c8 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8648.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - balance: "makes uplink kits more usefull for the risk" diff --git a/html/changelogs/AutoChangeLog-pr-8652.yml b/html/changelogs/AutoChangeLog-pr-8652.yml new file mode 100644 index 0000000000..b788c5785c --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8652.yml @@ -0,0 +1,4 @@ +author: "Ghommie (Original PR by Dennok)" +delete-after: True +changes: + - bugfix: "Now areas_in_z get areas spawned by templates and blueprints." diff --git a/html/changelogs/AutoChangeLog-pr-8658.yml b/html/changelogs/AutoChangeLog-pr-8658.yml new file mode 100644 index 0000000000..ad35118c3f --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8658.yml @@ -0,0 +1,5 @@ +author: "Ghommie" +delete-after: True +changes: + - tweak: "Moving some tablecrafting recipes to the appropriate categories: Kitty ears and lizard cloche hats to \"clothing\"; Hot dogs to \"Sandwichs\"; Cuban carb, fish and chips and fish fingers to \"Fish\"." + - bugfix: "Fixes the not-a-sandwich recipe being M.I.A." diff --git a/html/changelogs/AutoChangeLog-pr-8659.yml b/html/changelogs/AutoChangeLog-pr-8659.yml new file mode 100644 index 0000000000..6287f1307f --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8659.yml @@ -0,0 +1,4 @@ +author: "Ghommie (original PR by ninjanomnom)" +delete-after: True +changes: + - bugfix: "Orbiting is a little more aggressive about staying in orbit. The wisp as a result now correctly follows you over shuttle moves." diff --git a/html/changelogs/AutoChangeLog-pr-8665.yml b/html/changelogs/AutoChangeLog-pr-8665.yml new file mode 100644 index 0000000000..fc34f9ac3e --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8665.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - balance: "Buffed wizard and artificier's Magic Missile, wizard and xeno queen's Repulse and juggernaut's Gauntlet Echo." diff --git a/html/changelogs/AutoChangeLog-pr-8666.yml b/html/changelogs/AutoChangeLog-pr-8666.yml new file mode 100644 index 0000000000..df2e2e3af0 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8666.yml @@ -0,0 +1,4 @@ +author: "Ghommie (original PR by YPOQ)" +delete-after: True +changes: + - bugfix: "Fixing roffle waffle, mushroom halluginogen and some invalid reagents." diff --git a/html/changelogs/AutoChangeLog-pr-8667.yml b/html/changelogs/AutoChangeLog-pr-8667.yml new file mode 100644 index 0000000000..1f80a2917d --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8667.yml @@ -0,0 +1,4 @@ +author: "Ghommie (original PR by Anturk)" +delete-after: True +changes: + - rscadd: "Recipe for fabled secret sauce can now be found in the deepest reaches of space." diff --git a/html/changelogs/AutoChangeLog-pr-8669.yml b/html/changelogs/AutoChangeLog-pr-8669.yml new file mode 100644 index 0000000000..20770e8cc2 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8669.yml @@ -0,0 +1,5 @@ +author: "Ghommie (original PRs by Denton and Skoglol)" +delete-after: True +changes: + - tweak: "Reorganized the syndicate uplinks. Items are now mostly alphabetical, some misplaced items moved to more fitting categories. Bundles, random item and TC have been moved into a new category called \"Bundles and Telecrystals\". Gloves of the North Star and Box of Throwing Weapons have been moved to Conspicuous and Dangerous Weapons. Combat Gloves Plus have been moved to Stealthy and Inconspicuous Weapons. Moved all implants into the Implants category." + - tweak: "Added a new category to the uplink: Grenades and Explosives." diff --git a/html/changelogs/AutoChangeLog-pr-8671.yml b/html/changelogs/AutoChangeLog-pr-8671.yml new file mode 100644 index 0000000000..bb01481d5c --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8671.yml @@ -0,0 +1,4 @@ +author: "Ghommie (original PR by wesoda25)" +delete-after: True +changes: + - balance: "disembowelment no longer works on mobs that aren't dead or in critical condition" diff --git a/html/changelogs/AutoChangeLog-pr-8674.yml b/html/changelogs/AutoChangeLog-pr-8674.yml new file mode 100644 index 0000000000..3277946844 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8674.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - bugfix: "fixing cat code that dosnt work, my bad" diff --git a/html/changelogs/AutoChangeLog-pr-8675.yml b/html/changelogs/AutoChangeLog-pr-8675.yml new file mode 100644 index 0000000000..170a44ca25 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8675.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - bugfix: "Arcades stealing from noodles" diff --git a/html/changelogs/AutoChangeLog-pr-8677.yml b/html/changelogs/AutoChangeLog-pr-8677.yml new file mode 100644 index 0000000000..181f6d2932 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8677.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - tweak: "speedy quirk" diff --git a/html/changelogs/AutoChangeLog-pr-8687.yml b/html/changelogs/AutoChangeLog-pr-8687.yml new file mode 100644 index 0000000000..65347093ef --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8687.yml @@ -0,0 +1,4 @@ +author: "Ghommie (original PR by monster860)" +delete-after: True +changes: + - bugfix: "fixes advanced proccall" diff --git a/html/changelogs/AutoChangeLog-pr-8688.yml b/html/changelogs/AutoChangeLog-pr-8688.yml new file mode 100644 index 0000000000..b22c2c52fd --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8688.yml @@ -0,0 +1,5 @@ +author: "Ghommie (Original PR by nemvar)" +delete-after: True +changes: + - rscadd: "Botanists can now get beeplushies (or cultivator and bucket) as an heirloom." + - bugfix: "Clowns and mimes will now properly pick either a can of paint or their brand as heirloom now." diff --git a/html/changelogs/AutoChangeLog-pr-8689.yml b/html/changelogs/AutoChangeLog-pr-8689.yml new file mode 100644 index 0000000000..bf44770c76 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8689.yml @@ -0,0 +1,4 @@ +author: "Fermis" +delete-after: True +changes: + - rscadd: "Added a panda simplemob" diff --git a/html/changelogs/AutoChangeLog-pr-8690.yml b/html/changelogs/AutoChangeLog-pr-8690.yml new file mode 100644 index 0000000000..3ac76333a2 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8690.yml @@ -0,0 +1,4 @@ +author: "Fermis" +delete-after: True +changes: + - bugfix: "fixes empathy exploit." diff --git a/html/changelogs/AutoChangeLog-pr-8691.yml b/html/changelogs/AutoChangeLog-pr-8691.yml new file mode 100644 index 0000000000..680904cc5c --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8691.yml @@ -0,0 +1,4 @@ +author: "Ghommie (Original PRs by nemvar and Rowell)" +delete-after: True +changes: + - rscadd: "Added beekini bras and panties, thigh-high and knee-high bee socks." diff --git a/html/changelogs/AutoChangeLog-pr-8692.yml b/html/changelogs/AutoChangeLog-pr-8692.yml new file mode 100644 index 0000000000..f1d87676ab --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8692.yml @@ -0,0 +1,7 @@ +author: "Ghommie (original PRs by ShizCalev)" +delete-after: True +changes: + - bugfix: "Fixed a bug that allowed you to teleport an ID in your possession to a PDA anywhere ingame." + - bugfix: "Fixed an exploit allowing you to steal ID's/pens from PDA's not in your possession." + - bugfix: "Fixed an exploit allowing you unlimited control of a PDA's interface even if it wasn't near you/in your possession." + - bugfix: "Fixed Pride Mirror exploits." diff --git a/html/changelogs/AutoChangeLog-pr-8695.yml b/html/changelogs/AutoChangeLog-pr-8695.yml new file mode 100644 index 0000000000..671eaa519e --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8695.yml @@ -0,0 +1,6 @@ +author: "Ghommie (original PRs by grandpawalton and Mickyan)" +delete-after: True +changes: + - tweak: "the contents on the smartfridge icon now change depending on how many items it contains" + - bugfix: "opening the maintenance panel of smartfridges now correctly updates the icon" + - bugfix: "Screwing a disk compartmentalizer no longer makes it look like a smartfridge." diff --git a/html/changelogs/AutoChangeLog-pr-8698.yml b/html/changelogs/AutoChangeLog-pr-8698.yml new file mode 100644 index 0000000000..464f74427e --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8698.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - bugfix: "Fixes flashlights being unable to be used for rudimentary eyes and mouth exams." diff --git a/html/changelogs/AutoChangeLog-pr-8711.yml b/html/changelogs/AutoChangeLog-pr-8711.yml new file mode 100644 index 0000000000..f836783659 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8711.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - rscadd: "Adds in a grey jumpsuit to the loadout choices, restricted to Assistants." diff --git a/html/changelogs/AutoChangeLog-pr-8715.yml b/html/changelogs/AutoChangeLog-pr-8715.yml new file mode 100644 index 0000000000..b99309cdd9 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8715.yml @@ -0,0 +1,5 @@ +author: "Sishen1542" +delete-after: True +changes: + - rscadd: "Pentetic Jelly, new chemical made through mixing 1:1 slime jelly and pentetic acid." + - tweak: "Anatomic panacea now gives pent jelly instead of pent acid. Medbeams now have TRUE tox healing to heal TOXINLOVER as well." diff --git a/html/changelogs/AutoChangeLog-pr-8718.yml b/html/changelogs/AutoChangeLog-pr-8718.yml new file mode 100644 index 0000000000..102fbd4f23 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8718.yml @@ -0,0 +1,4 @@ +author: "Linzolle" +delete-after: True +changes: + - rscadd: "ability to quickly max sensors" diff --git a/html/changelogs/AutoChangeLog-pr-8721.yml b/html/changelogs/AutoChangeLog-pr-8721.yml new file mode 100644 index 0000000000..4b616e9923 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8721.yml @@ -0,0 +1,4 @@ +author: "Ghommie (original PR by XDTM)" +delete-after: True +changes: + - bugfix: "Reagents now stop their passive effects (for example, stun immunity) if the liver stops working while they're active." diff --git a/html/changelogs/AutoChangeLog-pr-8722.yml b/html/changelogs/AutoChangeLog-pr-8722.yml new file mode 100644 index 0000000000..fe858768af --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8722.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - bugfix: "I didn't code it right it in the first place" diff --git a/html/changelogs/AutoChangeLog-pr-8732.yml b/html/changelogs/AutoChangeLog-pr-8732.yml new file mode 100644 index 0000000000..69a79b93ac --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8732.yml @@ -0,0 +1,4 @@ +author: "Ghommie (original PR by Nicjh)" +delete-after: True +changes: + - rscadd: "Abductor console's select disguise option now uses a radial" diff --git a/html/changelogs/AutoChangeLog-pr-8733.yml b/html/changelogs/AutoChangeLog-pr-8733.yml new file mode 100644 index 0000000000..593c06bd90 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8733.yml @@ -0,0 +1,4 @@ +author: "Ghommie (original PR by Swindly)" +delete-after: True +changes: + - rscadd: "Arm-mounted implants that contain more than one item use a radial menu instead of a list menu." diff --git a/html/changelogs/AutoChangeLog-pr-8736.yml b/html/changelogs/AutoChangeLog-pr-8736.yml new file mode 100644 index 0000000000..68d64e2410 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8736.yml @@ -0,0 +1,6 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - rscadd: "gear harness and a conflict merg" + - rscdel: "Nudity permits" + - bugfix: "nothing" diff --git a/icons/emoji.dmi b/icons/emoji.dmi index f0286dd33c..128a3b243c 100644 Binary files a/icons/emoji.dmi and b/icons/emoji.dmi differ diff --git a/icons/mob/actions.dmi b/icons/mob/actions.dmi index 31c6b56f47..391ac8e987 100644 Binary files a/icons/mob/actions.dmi and b/icons/mob/actions.dmi differ diff --git a/icons/mob/custom_w.dmi b/icons/mob/custom_w.dmi index e9bbbc4d45..5f6cfe5234 100644 Binary files a/icons/mob/custom_w.dmi and b/icons/mob/custom_w.dmi differ diff --git a/icons/mob/neck.dmi b/icons/mob/neck.dmi index 3c126daba6..3463065bc7 100644 Binary files a/icons/mob/neck.dmi and b/icons/mob/neck.dmi differ diff --git a/icons/mob/pets.dmi b/icons/mob/pets.dmi index 45b0ab1f04..fe0146ccc4 100644 Binary files a/icons/mob/pets.dmi and b/icons/mob/pets.dmi differ diff --git a/icons/mob/underwear.dmi b/icons/mob/underwear.dmi index cf16eb9e32..25e7d2c6d0 100644 Binary files a/icons/mob/underwear.dmi and b/icons/mob/underwear.dmi differ diff --git a/icons/mob/uniform.dmi b/icons/mob/uniform.dmi index 2ed1783941..3d281606de 100644 Binary files a/icons/mob/uniform.dmi and b/icons/mob/uniform.dmi differ diff --git a/icons/obj/clockwork_objects.dmi b/icons/obj/clockwork_objects.dmi index 56cfdf468b..1948bb605c 100644 Binary files a/icons/obj/clockwork_objects.dmi and b/icons/obj/clockwork_objects.dmi differ diff --git a/icons/obj/clothing/belts.dmi b/icons/obj/clothing/belts.dmi index dc5dde9cb6..3e56574fbf 100644 Binary files a/icons/obj/clothing/belts.dmi and b/icons/obj/clothing/belts.dmi differ diff --git a/icons/obj/clothing/uniforms.dmi b/icons/obj/clothing/uniforms.dmi index 84155bfe43..3e3a1cefcb 100644 Binary files a/icons/obj/clothing/uniforms.dmi and b/icons/obj/clothing/uniforms.dmi differ diff --git a/icons/obj/custom.dmi b/icons/obj/custom.dmi index 0a426f2d79..f9660c6b38 100644 Binary files a/icons/obj/custom.dmi and b/icons/obj/custom.dmi differ diff --git a/icons/obj/dart.dmi b/icons/obj/dart.dmi new file mode 100644 index 0000000000..50ba4fc1ab Binary files /dev/null and b/icons/obj/dart.dmi differ diff --git a/icons/obj/guns/projectile.dmi b/icons/obj/guns/projectile.dmi index e4a39903b3..7d44d35f55 100644 Binary files a/icons/obj/guns/projectile.dmi and b/icons/obj/guns/projectile.dmi differ diff --git a/icons/obj/library.dmi b/icons/obj/library.dmi index fbb55434d1..140f6a4d9e 100644 Binary files a/icons/obj/library.dmi and b/icons/obj/library.dmi differ diff --git a/icons/obj/plushes.dmi b/icons/obj/plushes.dmi index 8e845d9710..586bca61aa 100644 Binary files a/icons/obj/plushes.dmi and b/icons/obj/plushes.dmi differ diff --git a/icons/obj/projectiles.dmi b/icons/obj/projectiles.dmi index d276655ae8..bff1b631c3 100644 Binary files a/icons/obj/projectiles.dmi and b/icons/obj/projectiles.dmi differ diff --git a/icons/obj/syringe.dmi b/icons/obj/syringe.dmi index f77735fc3e..80e681399a 100644 Binary files a/icons/obj/syringe.dmi and b/icons/obj/syringe.dmi differ diff --git a/icons/obj/vehicles.dmi b/icons/obj/vehicles.dmi index 5e3757cedd..67079de3e2 100644 Binary files a/icons/obj/vehicles.dmi and b/icons/obj/vehicles.dmi differ diff --git a/icons/obj/vending.dmi b/icons/obj/vending.dmi index e5d474f01d..553336115b 100644 Binary files a/icons/obj/vending.dmi and b/icons/obj/vending.dmi differ diff --git a/modular_citadel/code/datums/uplink_items_cit.dm b/modular_citadel/code/datums/uplink_items_cit.dm deleted file mode 100644 index 16130de96d..0000000000 --- a/modular_citadel/code/datums/uplink_items_cit.dm +++ /dev/null @@ -1,177 +0,0 @@ -/*/datum/uplink_item/stealthy_tools/syndi_borer - name = "Syndicate Brain Slug" - desc = "A small cortical borer, modified to be completely loyal to the owner. \ - Genetically infertile, these brain slugs can assist medically in a support role, or take direct action \ - to assist their host." - item = /obj/item/antag_spawner/syndi_borer - refundable = TRUE - cost = 10 - surplus = 20 //Let's not have this be too common - exclude_modes = list(/datum/game_mode/nuclear) */ - -/datum/uplink_item/stealthy_tools/holoparasite - name="Holoparasite Injector" - desc="An injector containing a swarm of holographic parasites. \ - They mimic the function of the guardians employed by the Space Wizard Federation, and their form can be selected upon application \ - NOTE: The precise nature of the symbiosis required by the parasites renders them incompatible with changelings" //updated to actually describe what they do and warn traitorchans not to buy it - item = /obj/item/storage/box/syndie_kit/holoparasite - refundable = TRUE - cant_discount = TRUE - cost = 15 - surplus = 20 //Nobody needs a ton of parasites - exclude_modes = list(/datum/game_mode/nuclear) - refund_path = /obj/item/guardiancreator/tech/choose/traitor - - -/obj/item/storage/box/syndie_kit/holoparasite - name = "box" - -/obj/item/storage/box/syndie_kit/holoparasite/PopulateContents() - new /obj/item/guardiancreator/tech/choose/traitor(src) - new /obj/item/paper/guides/antag/guardian(src) - -/datum/uplink_item/dangerous/antitank - name = "Anti Tank Pistol" - desc = "Essentially amounting to a sniper rifle with no stock and barrel (or indeed, any rifling at all), \ - this extremely dubious pistol is guaranteed to dislocate your wrists and hit the broad side of a barn! \ - Uses sniper ammo. \ - Bullets tend to veer off-course. We are not responsible for any unintentional damage or injury resulting from inaacuracy." - item = /obj/item/gun/ballistic/automatic/pistol/antitank/syndicate - cost = 14 - surplus = 25 - include_modes = list(/datum/game_mode/nuclear) - -/* Commented out due to introduction of reskinnable stetchkins. May still have a niche if people decide it somehow has value. -/datum/uplink_item/dangerous/stealthpistol - name = "Stealth Pistol" - desc = "A compact, easily concealable bullpup pistol that fires 10mm auto rounds in 8 round magazines. \ - Has an integrated suppressor." - item = /obj/item/gun/ballistic/automatic/pistol/stealth - cost = 10 - surplus = 30 -*/ - -///Soporific 10mm mags/// - -/datum/uplink_item/ammo/pistolzzz - name = "10mm Soporific Magazine" - desc = "An additional 8-round 10mm magazine; compatible with the Stechkin Pistol. Loaded with soporific rounds that put the target to sleep. \ - NOTE: Soporific is not instant acting due to the constraints of the round's scale. Will usually require three shots to take effect." - item = /obj/item/ammo_box/magazine/m10mm/soporific - cost = 2 - -///flechette memes/// - -/datum/uplink_item/dangerous/flechettegun - name = "Flechette Launcher" - desc = "A compact bullpup that fires micro-flechettes.\ - Flechettes have very poor performance idividually, but can be very deadly in numbers. \ - Pre-loaded with armor piercing flechettes that are capable of puncturing most kinds of armor." - item = /obj/item/gun/ballistic/automatic/flechette - cost = 12 - surplus = 30 - include_modes = list(/datum/game_mode/nuclear) - -/datum/uplink_item/ammo/flechetteap - name = "Armor Piercing Flechette Magazine" - desc = "An additional 40-round flechette magazine; compatible with the Flechette Launcer. \ - Loaded with armor piercing flechettes that very nearly ignore armor, but are not very effective agaisnt flesh." - item = /obj/item/ammo_box/magazine/flechette - cost = 2 - include_modes = list(/datum/game_mode/nuclear) - -/datum/uplink_item/ammo/flechettes - name = "Serrated Flechette Magazine" - desc = "An additional 40-round flechette magazine; compatible with the Flechette Launcer. \ - Loaded with serrated flechettes that shreds flesh, but is stopped dead in its tracks by armor. \ - These flechettes are highly likely to sever arteries, and even limbs." - item = /obj/item/ammo_box/magazine/flechette/s - cost = 2 - include_modes = list(/datum/game_mode/nuclear) - -///shredder/// - -/datum/uplink_item/nukeoffer/shredder - name = "Shredder bundle" - desc = "A truly horrific weapon designed simply to maim its victim, the CX Shredder is banned by several intergalactic treaties. \ - You'll get two of them with this. And spare ammo to boot. And we'll throw in an extra elite hardsuit and chest rig to hold them all!" - item = /obj/item/storage/backpack/duffelbag/syndie/shredderbundle - cost = 30 // normally 41 - -///Modular Pistols/// - -/datum/uplink_item/bundle/modular - name="Modular Pistol Kit" - desc="A heavy briefcase containing one modular pistol (chambered in 10mm), one supressor, and spare ammunition, including a box of soporific ammo. \ - Includes a suit jacket that is padded with a robust liner." - item = /obj/item/storage/briefcase/modularbundle - cost = 12 - -//////Bundle stuff////// - -///bundle category/// - -/datum/uplink_item/bundle - category = "Bundles" - surplus = 0 - cant_discount = TRUE - -///place bundle storage items here I guess/// - -/obj/item/storage/briefcase/modularbundle - name = "briefcase" - desc = "It's label reads genuine hardened Captain leather, but suspiciously has no other tags or branding." - icon_state = "briefcase" - flags_1 = CONDUCT_1 - force = 10 - hitsound = "swing_hit" - throw_speed = 2 - throw_range = 4 - w_class = WEIGHT_CLASS_BULKY - attack_verb = list("bashed", "battered", "bludgeoned", "thrashed", "whacked") - resistance_flags = FLAMMABLE - max_integrity = 150 - -/obj/item/storage/briefcase/modularbundle/PopulateContents() - new /obj/item/gun/ballistic/automatic/pistol/modular(src) - new /obj/item/suppressor(src) - new /obj/item/ammo_box/magazine/m10mm(src) - new /obj/item/ammo_box/magazine/m10mm/soporific(src) - new /obj/item/ammo_box/c10mm/soporific(src) - new /obj/item/clothing/under/lawyer/blacksuit(src) - new /obj/item/clothing/accessory/waistcoat(src) - new /obj/item/clothing/suit/toggle/lawyer/black/syndie(src) - -/obj/item/clothing/suit/toggle/lawyer/black/syndie - desc = "A snappy dress jacket. Suspiciously has no tags or branding." - armor = list(melee = 10, bullet = 10, laser = 10, energy = 10, bomb = 10) - -/obj/item/storage/backpack/duffelbag/syndie/shredderbundle - desc = "A large duffel bag containing two CX Shredders, some magazines, an elite hardsuit, and a chest rig." - -/obj/item/storage/backpack/duffelbag/syndie/shredderbundle/PopulateContents() - new /obj/item/ammo_box/magazine/flechette/shredder(src) - new /obj/item/ammo_box/magazine/flechette/shredder(src) - new /obj/item/ammo_box/magazine/flechette/shredder(src) - new /obj/item/ammo_box/magazine/flechette/shredder(src) - new /obj/item/gun/ballistic/automatic/flechette/shredder(src) - new /obj/item/gun/ballistic/automatic/flechette/shredder(src) - new /obj/item/storage/belt/military(src) - new /obj/item/clothing/suit/space/hardsuit/syndi/elite(src) - -///End of Bundle stuff/// - - -/*///////////////////////////////////////////////////////////////////////// -///////////// The TRUE Energy Sword /////////////////////////// -*////////////////////////////////////////////////////////////////////////// - -/datum/uplink_item/dangerous/cxneb - name = "Dragon's Tooth Non-Eutactic Blade" - desc = "An illegal modification of a weapon that is functionally identical to the energy sword, \ - the Non-Eutactic Blade (NEB) forges a hardlight blade on-demand, \ - generating an extremely sharp, unbreakable edge that is guaranteed to satisfy your every need. \ - This particular model has a polychromic hardlight generator, allowing you to murder in style! \ - The illegal modifications bring this weapon up to par with the classic energy sword, and also gives it the energy sword's distinctive sounds." - item = /obj/item/melee/transforming/energy/sword/cx/traitor - cost = 8 \ No newline at end of file diff --git a/modular_citadel/code/game/gamemodes/gangs/gang_items.dm b/modular_citadel/code/game/gamemodes/gangs/gang_items.dm index 0f16b6462b..2e9ca4dcc0 100644 --- a/modular_citadel/code/game/gamemodes/gangs/gang_items.dm +++ b/modular_citadel/code/game/gamemodes/gangs/gang_items.dm @@ -83,14 +83,12 @@ return return TRUE - /datum/gang_item/clothing/hat name = "Pimp Hat" id = "hat" cost = 16 item_path = /obj/item/clothing/head/collectable/petehat/gang - /obj/item/clothing/head/collectable/petehat/gang name = "pimpin' hat" desc = "The undisputed king of style." @@ -109,7 +107,7 @@ /datum/gang_item/clothing/shoes name = "Bling Boots" id = "boots" - cost = 22 + cost = 20 item_path = /obj/item/clothing/shoes/gang /obj/item/clothing/shoes/gang @@ -258,7 +256,6 @@ datum/gang_item/clothing/shades //Addition: Why not have cool shades on a gang m /datum/gang_item/equipment category = "Purchase Equipment:" - /datum/gang_item/equipment/spraycan name = "Territory Spraycan" id = "spraycan" @@ -275,7 +272,6 @@ datum/gang_item/clothing/shades //Addition: Why not have cool shades on a gang m cost = 3 item_path = /obj/item/sharpener - /datum/gang_item/equipment/emp name = "EMP Grenade" id = "EMP" @@ -329,6 +325,12 @@ datum/gang_item/equipment/shield cost = 25 item_path = /obj/item/shield/riot +datum/gang_item/equipment/gangsheild + name = "Tower Shield" + id = "metal" + cost = 45 //High block of melee and even higher for bullets + item_path = /obj/item/shield/riot/tower + /datum/gang_item/equipment/pen name = "Recruitment Pen" id = "pen" @@ -352,7 +354,6 @@ datum/gang_item/equipment/shield return "(GET ONE FREE)" return ..() - /datum/gang_item/equipment/gangtool id = "gangtool" cost = 5 @@ -413,4 +414,4 @@ datum/gang_item/equipment/shield /datum/gang_item/equipment/dominator/spawn_item(mob/living/carbon/user, datum/team/gang/gang, obj/item/device/gangtool/gangtool) new item_path(user.loc) - to_chat(user, spawn_msg) \ No newline at end of file + to_chat(user, spawn_msg) diff --git a/modular_citadel/code/game/objects/items/devices/flashlight.dm b/modular_citadel/code/game/objects/items/devices/flashlight.dm deleted file mode 100644 index 3a373c9277..0000000000 --- a/modular_citadel/code/game/objects/items/devices/flashlight.dm +++ /dev/null @@ -1,31 +0,0 @@ -/obj/item/flashlight - light_color = "#FFCC66" - flashlight_power = 0.8 - -/obj/item/flashlight/pen - light_color = "#FFDDCC" - flashlight_power = 0.3 - -/obj/item/flashlight/seclite - light_color = "#CDDDFF" - flashlight_power = 0.9 - -/obj/item/flashlight/lamp - light_color = "#FFDDBB" - flashlight_power = 0.8 - -/obj/item/flashlight/flare - light_color = "#FA421A" - flashlight_power = 0.8 - -/obj/item/flashlight/flare/torch - light_color = "#FAA44B" - flashlight_power = 0.8 - -/obj/item/flashlight/lantern - light_color = "#FFAA44" - flashlight_power = 0.75 - -/obj/item/flashlight/slime - light_color = "#FFEEAA" - flashlight_power = 0.6 diff --git a/modular_citadel/code/modules/arousal/arousal.dm b/modular_citadel/code/modules/arousal/arousal.dm index 846a8cff62..27f7576e7f 100644 --- a/modular_citadel/code/modules/arousal/arousal.dm +++ b/modular_citadel/code/modules/arousal/arousal.dm @@ -14,6 +14,10 @@ var/saved_underwear = ""//saves their underwear so it can be toggled later var/saved_undershirt = "" + var/saved_socks = "" + var/hidden_underwear = FALSE + var/hidden_undershirt = FALSE + var/hidden_socks = FALSE /mob/living/carbon/human/New() ..() @@ -29,6 +33,33 @@ var/list/femcum_fluids = list("femcum") //Mob procs +/mob/living/carbon/human/proc/underwear_toggle() + set name = "Toggle undergarments" + set category = "Object" + if(ishuman(src)) + var/mob/living/carbon/human/humz = src + var/confirm = input(src, "Select what part of your form to alter", "Undergarment Toggling", "Cancel") in list("Top", "Bottom", "Socks", "All", "Cancel") + if(confirm == "Top") + humz.hidden_undershirt = !humz.hidden_undershirt + + if(confirm == "Bottom") + humz.hidden_underwear = !humz.hidden_underwear + + if(confirm == "Socks") + humz.hidden_socks = !humz.hidden_socks + + if(confirm == "All") + humz.hidden_undershirt = !humz.hidden_undershirt + humz.hidden_underwear = !humz.hidden_underwear + humz.hidden_socks = !humz.hidden_socks + + if(confirm == "Cancel") + return + src.update_body() + + else + to_chat(src, "Humans only. How the fuck did you get this verb anyway.") + /mob/living/proc/handle_arousal() diff --git a/modular_citadel/code/modules/arousal/organs/genitals.dm b/modular_citadel/code/modules/arousal/organs/genitals.dm index 52508d7803..63d6834409 100644 --- a/modular_citadel/code/modules/arousal/organs/genitals.dm +++ b/modular_citadel/code/modules/arousal/organs/genitals.dm @@ -73,7 +73,7 @@ owner.exposed_genitals += src if("Hidden by clothes") through_clothes = FALSE - hidden = FALSE + hidden = TRUE if(src in owner.exposed_genitals) owner.exposed_genitals -= src if("Always hidden") @@ -303,6 +303,8 @@ for(var/obj/item/organ/O in H.internal_organs) if(isgenital(O)) var/obj/item/organ/genital/G = O + if(G.hidden) + return //we're gunna just hijack this for updates. if(G.is_exposed()) //Checks appropriate clothing slot and if it's through_clothes genitals_to_add += H.getorganslot(G.slot) //Now we added all genitals that aren't internal and should be rendered diff --git a/modular_citadel/code/modules/client/loadout/__donator.dm b/modular_citadel/code/modules/client/loadout/__donator.dm index 1e17736380..d8168d01a6 100644 --- a/modular_citadel/code/modules/client/loadout/__donator.dm +++ b/modular_citadel/code/modules/client/loadout/__donator.dm @@ -397,4 +397,10 @@ datum/gear/darksabresheath name = "Kimono" category = SLOT_WEAR_SUIT path = /obj/item/clothing/suit/kimono - ckeywhitelist = list("sfox63") \ No newline at end of file + ckeywhitelist = list("sfox63") + +/datum/gear/commjacket + name = "Dusty Commisar's Cloak" + category = SLOT_WEAR_SUIT + path = /obj/item/clothing/suit/commjacket + ckeywhitelist = list("sadisticbatter") diff --git a/modular_citadel/code/modules/client/loadout/_service.dm b/modular_citadel/code/modules/client/loadout/_service.dm index 9b508bb93f..062e22f966 100644 --- a/modular_citadel/code/modules/client/loadout/_service.dm +++ b/modular_citadel/code/modules/client/loadout/_service.dm @@ -1,3 +1,9 @@ +/datum/gear/greytidestationwide + name = "Grey jumpsuit" + category = SLOT_W_UNIFORM + path = /obj/item/clothing/under/color/grey + restricted_roles = list("Assistant") + /datum/gear/plushvar name = "Ratvar Plushie" category = SLOT_IN_BACKPACK diff --git a/modular_citadel/code/modules/client/loadout/uniform.dm b/modular_citadel/code/modules/client/loadout/uniform.dm index 4172230dbf..abdf8e3a24 100644 --- a/modular_citadel/code/modules/client/loadout/uniform.dm +++ b/modular_citadel/code/modules/client/loadout/uniform.dm @@ -309,8 +309,8 @@ restricted_desc = "Engineering and Security" restricted_roles = list("Chief Engineer","Atmospheric Technician","Station Engineer","Warden","Detective","Security Officer","Head of Security","Cargo Technician", "Shaft Miner", "Quartermaster") -//memes -/datum/gear/nudepermit - name = "Nudity Permit" +//Memes +/datum/gear/gear_harnesses + name = "Gear Harness" category = SLOT_W_UNIFORM - path = /obj/item/clothing/under/permit \ No newline at end of file + path = /obj/item/clothing/under/gear_harness \ No newline at end of file diff --git a/modular_citadel/code/modules/custom_loadout/custom_items.dm b/modular_citadel/code/modules/custom_loadout/custom_items.dm index c43b8f3ce1..0338a4f48e 100644 --- a/modular_citadel/code/modules/custom_loadout/custom_items.dm +++ b/modular_citadel/code/modules/custom_loadout/custom_items.dm @@ -494,3 +494,14 @@ icon = 'icons/obj/custom.dmi' alternate_worn_icon = 'icons/mob/custom_w.dmi' mutantrace_variation = NO_MUTANTRACE_VARIATION + +/obj/item/clothing/suit/commjacket + name = "Dusty Commisar's Cloak" + desc = "An Imperial Commisar's Coat, straight from the frontline of battle, filled with dirt, bulletholes, and dozens of little pockets. Alongside a curious golden eagle sitting on it's left breast, the marking '200th Venoland' is clearly visible on the inner workings of the coat. It certainly holds an imposing flair, however." + icon_state = "commjacket" + item_state = "commjacket" + icon = 'icons/obj/custom.dmi' + alternate_worn_icon = 'icons/mob/custom_w.dmi' + mutantrace_variation = NO_MUTANTRACE_VARIATION + + diff --git a/modular_citadel/code/modules/mob/cit_emotes.dm b/modular_citadel/code/modules/mob/cit_emotes.dm index a314baa852..aff1739ae4 100644 --- a/modular_citadel/code/modules/mob/cit_emotes.dm +++ b/modular_citadel/code/modules/mob/cit_emotes.dm @@ -183,6 +183,7 @@ key_third_person = "suddenly hits a dab" message = "suddenly hits a dab!" emote_type = EMOTE_AUDIBLE + restraint_check = TRUE diff --git a/modular_citadel/code/modules/mob/dead/new_player/sprite_accessories.dm b/modular_citadel/code/modules/mob/dead/new_player/sprite_accessories.dm index e552c2cbdd..bf811b777c 100644 --- a/modular_citadel/code/modules/mob/dead/new_player/sprite_accessories.dm +++ b/modular_citadel/code/modules/mob/dead/new_player/sprite_accessories.dm @@ -191,6 +191,32 @@ icon = 'modular_citadel/icons/mob/mam_ears.dmi' color_src = MATRIXED +/datum/sprite_accessory/ears/human/bigwolf + name = "Big Wolf" + icon_state = "bigwolf" + icon = 'modular_citadel/icons/mob/mam_ears.dmi' + color_src = MATRIXED + +/datum/sprite_accessory/ears/human/bigwolfinner + name = "Big Wolf (ALT)" + icon_state = "bigwolfinner" + hasinner = 1 + icon = 'modular_citadel/icons/mob/mam_ears.dmi' + color_src = MATRIXED + +/datum/sprite_accessory/ears/human/bigwolfdark + name = "Dark Big Wolf" + icon_state = "bigwolfdark" + icon = 'modular_citadel/icons/mob/mam_ears.dmi' + color_src = MATRIXED + +/datum/sprite_accessory/ears/human/bigwolfinnerdark + name = "Dark Big Wolf (ALT)" + icon_state = "bigwolfinnerdark" + hasinner = 1 + icon = 'modular_citadel/icons/mob/mam_ears.dmi' + color_src = MATRIXED + /datum/sprite_accessory/ears/human/cow name = "Cow" icon_state = "cow" diff --git a/modular_citadel/code/modules/reagents/chemistry/reagents/other_reagents.dm b/modular_citadel/code/modules/reagents/chemistry/reagents/other_reagents.dm index 0f71a71add..00063c22d4 100644 --- a/modular_citadel/code/modules/reagents/chemistry/reagents/other_reagents.dm +++ b/modular_citadel/code/modules/reagents/chemistry/reagents/other_reagents.dm @@ -17,13 +17,13 @@ M.adjustStaminaLoss(-5*REM) . = ..() -/datum/reagent/syndicateadrenals/on_mob_add(mob/living/M) +/datum/reagent/syndicateadrenals/on_mob_metabolize(mob/living/M) . = ..() if(istype(M)) M.next_move_modifier *= 0.5 to_chat(M, "You feel an intense surge of energy rushing through your veins.") -/datum/reagent/syndicateadrenals/on_mob_delete(mob/living/M) +/datum/reagent/syndicateadrenals/on_mob_end_metabolize(mob/living/M) . = ..() if(istype(M)) M.next_move_modifier *= 2 diff --git a/modular_citadel/code/modules/uplink/uplink_items.dm b/modular_citadel/code/modules/uplink/uplink_items.dm deleted file mode 100644 index df076c3994..0000000000 --- a/modular_citadel/code/modules/uplink/uplink_items.dm +++ /dev/null @@ -1,18 +0,0 @@ -/* -// PUT ALL YOUR NEW UPLINK STUFF HERE, OVERRIDES GO IN HERE TOO -*/ - -/datum/uplink_item/device_tools/emagrecharge - name = "Electromagnet Charging Device" - desc = "A small device intended for recharging Cryptographic Sequencers. Using it will add five extra charges to the Cryptographic Sequencer." - item = /obj/item/emagrecharge - cost = 2 - -/datum/uplink_item/dangerous/revolver - item = /obj/item/gun/ballistic/revolver/syndie - -/datum/uplink_item/dangerous/phantomthief - name = "Syndicate Mask" - desc = "A cheap plastic mask fitted with an adrenaline autoinjector, which can be used by simply tensing your muscles" - item = /obj/item/clothing/glasses/phantomthief/syndicate - cost = 2 diff --git a/modular_citadel/icons/mob/clothing/trek_item_icon.dmi b/modular_citadel/icons/mob/clothing/trek_item_icon.dmi deleted file mode 100644 index ed3286615b..0000000000 Binary files a/modular_citadel/icons/mob/clothing/trek_item_icon.dmi and /dev/null differ diff --git a/modular_citadel/icons/mob/uniform_digi.dmi b/modular_citadel/icons/mob/uniform_digi.dmi index 9513f82c9c..5ff291f400 100644 Binary files a/modular_citadel/icons/mob/uniform_digi.dmi and b/modular_citadel/icons/mob/uniform_digi.dmi differ diff --git a/modular_citadel/icons/obj/clothing/trek_item_icon.dmi b/modular_citadel/icons/obj/clothing/trek_item_icon.dmi index 86afe16b03..ed3286615b 100644 Binary files a/modular_citadel/icons/obj/clothing/trek_item_icon.dmi and b/modular_citadel/icons/obj/clothing/trek_item_icon.dmi differ diff --git a/modular_citadel/icons/obj/genitals/breasts_onmob.dmi b/modular_citadel/icons/obj/genitals/breasts_onmob.dmi index 69a531bd11..c4b75b1172 100644 Binary files a/modular_citadel/icons/obj/genitals/breasts_onmob.dmi and b/modular_citadel/icons/obj/genitals/breasts_onmob.dmi differ diff --git a/modular_citadel/icons/obj/genitals/penis_onmob.dmi b/modular_citadel/icons/obj/genitals/penis_onmob.dmi index 2457759b73..434f171e22 100644 Binary files a/modular_citadel/icons/obj/genitals/penis_onmob.dmi and b/modular_citadel/icons/obj/genitals/penis_onmob.dmi differ diff --git a/modular_citadel/icons/obj/genitals/testicles_onmob.dmi b/modular_citadel/icons/obj/genitals/testicles_onmob.dmi index 581bcb0583..33659cf13c 100644 Binary files a/modular_citadel/icons/obj/genitals/testicles_onmob.dmi and b/modular_citadel/icons/obj/genitals/testicles_onmob.dmi differ diff --git a/modular_citadel/icons/obj/genitals/vagina_onmob.dmi b/modular_citadel/icons/obj/genitals/vagina_onmob.dmi index f5daa3fea1..c4cf891eac 100644 Binary files a/modular_citadel/icons/obj/genitals/vagina_onmob.dmi and b/modular_citadel/icons/obj/genitals/vagina_onmob.dmi differ diff --git a/tgstation.dme b/tgstation.dme index 2cd047cac6..31169e9f1b 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -130,6 +130,7 @@ #include "code\__HELPERS\qdel.dm" #include "code\__HELPERS\radiation.dm" #include "code\__HELPERS\radio.dm" +#include "code\__HELPERS\reagents.dm" #include "code\__HELPERS\roundend.dm" #include "code\__HELPERS\sanitize_values.dm" #include "code\__HELPERS\shell.dm" @@ -247,7 +248,6 @@ #include "code\controllers\subsystem\moods.dm" #include "code\controllers\subsystem\nightshift.dm" #include "code\controllers\subsystem\npcpool.dm" -#include "code\controllers\subsystem\orbit.dm" #include "code\controllers\subsystem\overlays.dm" #include "code\controllers\subsystem\pai.dm" #include "code\controllers\subsystem\parallax.dm" @@ -360,6 +360,7 @@ #include "code\datums\components\mood.dm" #include "code\datums\components\nanites.dm" #include "code\datums\components\ntnet_interface.dm" +#include "code\datums\components\orbiter.dm" #include "code\datums\components\paintable.dm" #include "code\datums\components\rad_insulation.dm" #include "code\datums\components\radioactive.dm" @@ -1236,6 +1237,7 @@ #include "code\modules\antagonists\clockcult\clock_structures\mania_motor.dm" #include "code\modules\antagonists\clockcult\clock_structures\ocular_warden.dm" #include "code\modules\antagonists\clockcult\clock_structures\ratvar_the_clockwork_justicar.dm" +#include "code\modules\antagonists\clockcult\clock_structures\reflector.dm" #include "code\modules\antagonists\clockcult\clock_structures\stargazer.dm" #include "code\modules\antagonists\clockcult\clock_structures\taunting_trail.dm" #include "code\modules\antagonists\clockcult\clock_structures\wall_gear.dm" @@ -2102,6 +2104,7 @@ #include "code\modules\mob\living\simple_animal\friendly\gondola.dm" #include "code\modules\mob\living\simple_animal\friendly\lizard.dm" #include "code\modules\mob\living\simple_animal\friendly\mouse.dm" +#include "code\modules\mob\living\simple_animal\friendly\panda.dm" #include "code\modules\mob\living\simple_animal\friendly\penguin.dm" #include "code\modules\mob\living\simple_animal\friendly\pet.dm" #include "code\modules\mob\living\simple_animal\friendly\sloth.dm" @@ -2263,7 +2266,6 @@ #include "code\modules\NTNet\network.dm" #include "code\modules\NTNet\relays.dm" #include "code\modules\NTNet\services\_service.dm" -#include "code\modules\orbit\orbit.dm" #include "code\modules\paperwork\clipboard.dm" #include "code\modules\paperwork\contract.dm" #include "code\modules\paperwork\filingcabinet.dm" @@ -2479,6 +2481,7 @@ #include "code\modules\reagents\chemistry\recipes\others.dm" #include "code\modules\reagents\chemistry\recipes\pyrotechnics.dm" #include "code\modules\reagents\chemistry\recipes\slime_extracts.dm" +#include "code\modules\reagents\chemistry\recipes\special.dm" #include "code\modules\reagents\chemistry\recipes\toxins.dm" #include "code\modules\reagents\reagent_containers\blood_pack.dm" #include "code\modules\reagents\reagent_containers\borghydro.dm" @@ -2773,6 +2776,7 @@ #include "code\modules\vehicles\speedbike.dm" #include "code\modules\vehicles\vehicle_actions.dm" #include "code\modules\vehicles\vehicle_key.dm" +#include "code\modules\vehicles\wheelchair.dm" #include "code\modules\vehicles\cars\car.dm" #include "code\modules\vehicles\cars\clowncar.dm" #include "code\modules\vending\_vending.dm" @@ -2824,7 +2828,6 @@ #include "modular_citadel\code\controllers\configuration\entries\general.dm" #include "modular_citadel\code\controllers\subsystem\job.dm" #include "modular_citadel\code\controllers\subsystem\shuttle.dm" -#include "modular_citadel\code\datums\uplink_items_cit.dm" #include "modular_citadel\code\datums\components\material_container.dm" #include "modular_citadel\code\datums\components\phantomthief.dm" #include "modular_citadel\code\datums\components\souldeath.dm" @@ -2879,7 +2882,6 @@ #include "modular_citadel\code\game\objects\items\vending_items.dm" #include "modular_citadel\code\game\objects\items\circuitboards\machine_circuitboards.dm" #include "modular_citadel\code\game\objects\items\devices\aicard.dm" -#include "modular_citadel\code\game\objects\items\devices\flashlight.dm" #include "modular_citadel\code\game\objects\items\devices\PDA\PDA.dm" #include "modular_citadel\code\game\objects\items\devices\radio\encryptionkey.dm" #include "modular_citadel\code\game\objects\items\devices\radio\headset.dm" @@ -3035,7 +3037,6 @@ #include "modular_citadel\code\modules\research\techweb\_techweb.dm" #include "modular_citadel\code\modules\research\techweb\all_nodes.dm" #include "modular_citadel\code\modules\research\xenobiology\xenobio_camera.dm" -#include "modular_citadel\code\modules\uplink\uplink_items.dm" #include "modular_citadel\code\modules\vehicles\secway.dm" #include "modular_citadel\code\modules\vore\hook-defs_vr.dm" #include "modular_citadel\code\modules\vore\persistence.dm"