diff --git a/_maps/RandomRuins/SpaceRuins/deepstorage.dmm b/_maps/RandomRuins/SpaceRuins/deepstorage.dmm
new file mode 100644
index 0000000000..785d2e9456
--- /dev/null
+++ b/_maps/RandomRuins/SpaceRuins/deepstorage.dmm
@@ -0,0 +1,6741 @@
+//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/closed/wall/mineral/iron,
+/area/ruin/deepstorage)
+"ad" = (
+/obj/structure/closet/cardboard,
+/obj/item/stack/sheet/mineral/silver,
+/obj/item/stack/sheet/mineral/gold,
+/obj/item/stack/sheet/mineral/silver,
+/obj/item/stack/sheet/mineral/silver,
+/obj/item/stack/sheet/mineral/gold,
+/obj/item/stack/sheet/mineral/gold,
+/turf/open/floor/plasteel/floorgrime,
+/area/ruin/deepstorage)
+"ae" = (
+/obj/structure/closet/cardboard,
+/obj/item/weapon/storage/box/monkeycubes,
+/obj/item/weapon/storage/box/monkeycubes,
+/obj/item/weapon/storage/box/monkeycubes,
+/obj/item/weapon/storage/toolbox/drone,
+/obj/item/weapon/storage/toolbox/drone,
+/turf/open/floor/plasteel/floorgrime,
+/area/ruin/deepstorage)
+"af" = (
+/obj/structure/closet/cardboard,
+/obj/item/stack/sheet/cardboard,
+/obj/item/stack/cable_coil,
+/obj/item/stack/sheet/mineral/wood,
+/obj/item/stack/sheet/mineral/wood,
+/obj/item/stack/packageWrap,
+/turf/open/floor/plasteel/floorgrime,
+/area/ruin/deepstorage)
+"ag" = (
+/obj/structure/closet/cardboard,
+/obj/item/weapon/storage/box/mousetraps,
+/obj/item/weapon/storage/box/mousetraps,
+/obj/item/weapon/storage/box/drinkingglasses,
+/obj/item/weapon/storage/box/zipties,
+/obj/item/weapon/switchblade,
+/turf/open/floor/plasteel/floorgrime,
+/area/ruin/deepstorage)
+"ah" = (
+/obj/structure/closet/cardboard,
+/obj/item/stack/sheet/metal{
+ amount = 50;
+ pixel_x = 2;
+ pixel_y = 2
+ },
+/obj/item/stack/sheet/metal{
+ amount = 50;
+ pixel_x = 2;
+ pixel_y = 2
+ },
+/obj/item/stack/sheet/metal{
+ amount = 50;
+ pixel_x = 2;
+ pixel_y = 2
+ },
+/obj/item/stack/sheet/metal{
+ amount = 50;
+ pixel_x = 2;
+ pixel_y = 2
+ },
+/obj/item/stack/rods{
+ amount = 50
+ },
+/obj/item/stack/rods{
+ amount = 50
+ },
+/obj/item/stack/rods{
+ amount = 50
+ },
+/obj/item/stack/rods{
+ amount = 50
+ },
+/turf/open/floor/plasteel/floorgrime,
+/area/ruin/deepstorage)
+"ai" = (
+/obj/structure/closet/cardboard,
+/obj/item/stack/sheet/glass{
+ amount = 50
+ },
+/obj/item/stack/sheet/glass{
+ amount = 50
+ },
+/obj/item/stack/sheet/glass{
+ amount = 50
+ },
+/obj/item/stack/sheet/glass{
+ amount = 50
+ },
+/obj/item/stack/sheet/plasteel{
+ amount = 10
+ },
+/obj/item/stack/sheet/plasteel{
+ amount = 10
+ },
+/obj/item/stack/sheet/plasteel{
+ amount = 10
+ },
+/obj/item/stack/sheet/plasteel{
+ amount = 10
+ },
+/obj/item/clothing/shoes/combat,
+/obj/item/clothing/shoes/combat,
+/turf/open/floor/plasteel/floorgrime,
+/area/ruin/deepstorage)
+"aj" = (
+/obj/structure/closet/cardboard,
+/obj/machinery/light{
+ icon_state = "tube1";
+ dir = 8
+ },
+/obj/item/device/flashlight/flare,
+/obj/item/device/flashlight/flare,
+/obj/item/device/flashlight/flare,
+/obj/item/device/flashlight/flare,
+/obj/item/device/flashlight/flare,
+/obj/item/device/flashlight/flare,
+/obj/item/device/flashlight,
+/obj/item/device/flashlight,
+/obj/item/device/flashlight,
+/obj/item/weapon/shovel,
+/obj/item/weapon/pickaxe/drill,
+/obj/item/weapon/pickaxe/drill,
+/obj/item/weapon/pickaxe/drill,
+/turf/open/floor/plasteel/floorgrime,
+/area/ruin/deepstorage)
+"ak" = (
+/obj/structure/closet/cardboard,
+/obj/item/device/flashlight/lantern,
+/obj/item/device/flashlight/lantern,
+/obj/item/device/flashlight/lantern,
+/obj/item/device/tape/random,
+/obj/item/device/tape/random,
+/obj/item/device/tape/random,
+/obj/item/weapon/storage/box/rxglasses,
+/obj/item/weapon/extinguisher,
+/obj/item/weapon/extinguisher,
+/obj/item/clothing/glasses/night,
+/obj/item/clothing/glasses/night,
+/turf/open/floor/plasteel/floorgrime,
+/area/ruin/deepstorage)
+"al" = (
+/obj/structure/closet/cardboard,
+/obj/item/weapon/storage/box/syringes,
+/obj/item/weapon/storage/box/syringes,
+/obj/item/weapon/storage/box/beakers,
+/obj/item/weapon/storage/box/beakers,
+/obj/item/weapon/storage/box/matches,
+/obj/item/weapon/storage/box/bodybags,
+/obj/item/clothing/glasses/meson/engine,
+/obj/item/clothing/glasses/meson/engine,
+/turf/open/floor/plasteel/floorgrime,
+/area/ruin/deepstorage)
+"am" = (
+/obj/structure/closet/cardboard,
+/obj/item/weapon/kitchen/knife,
+/obj/item/weapon/kitchen/knife,
+/obj/item/weapon/cultivator,
+/obj/item/weapon/hatchet,
+/obj/item/weapon/kitchen/rollingpin,
+/turf/open/floor/plasteel/floorgrime,
+/area/ruin/deepstorage)
+"an" = (
+/obj/structure/closet/cardboard,
+/obj/item/weapon/defibrillator,
+/obj/item/weapon/storage/box/medipens,
+/turf/open/floor/plasteel/floorgrime,
+/area/ruin/deepstorage)
+"ao" = (
+/obj/structure/closet/cardboard,
+/obj/machinery/light{
+ dir = 4;
+ icon_state = "tube1"
+ },
+/obj/item/ammo_box/c9mm,
+/obj/item/ammo_box/c9mm,
+/obj/item/ammo_box/c9mm,
+/obj/item/ammo_box/c9mm,
+/obj/item/ammo_box/c9mm,
+/obj/item/ammo_box/c9mm,
+/turf/open/floor/plasteel/floorgrime,
+/area/ruin/deepstorage)
+"ap" = (
+/obj/structure/closet/crate/freezer,
+/obj/item/weapon/reagent_containers/blood/OMinus,
+/obj/item/weapon/reagent_containers/blood/OMinus,
+/obj/item/weapon/reagent_containers/blood/OMinus,
+/obj/item/weapon/reagent_containers/blood/OMinus,
+/obj/item/weapon/reagent_containers/blood/OMinus,
+/obj/item/weapon/reagent_containers/blood/random,
+/obj/item/weapon/reagent_containers/blood/random,
+/obj/item/weapon/reagent_containers/blood/random,
+/obj/item/weapon/reagent_containers/blood/random,
+/obj/item/weapon/reagent_containers/blood/random,
+/obj/item/weapon/reagent_containers/blood/random,
+/turf/open/floor/plasteel/floorgrime,
+/area/ruin/deepstorage)
+"aq" = (
+/obj/machinery/iv_drip,
+/turf/open/floor/plasteel/floorgrime,
+/area/ruin/deepstorage)
+"ar" = (
+/turf/open/floor/plasteel/floorgrime,
+/area/ruin/deepstorage)
+"as" = (
+/obj/machinery/portable_atmospherics/canister/oxygen,
+/turf/open/floor/plasteel/floorgrime,
+/area/ruin/deepstorage)
+"at" = (
+/obj/machinery/portable_atmospherics/canister/air,
+/turf/open/floor/plasteel/floorgrime,
+/area/ruin/deepstorage)
+"au" = (
+/obj/machinery/door/airlock/highsecurity{
+ name = "Bunker"
+ },
+/turf/open/floor/plasteel,
+/area/ruin/deepstorage)
+"av" = (
+/obj/structure/toilet{
+ dir = 4
+ },
+/turf/open/floor/plasteel/freezer,
+/area/ruin/deepstorage)
+"aw" = (
+/obj/structure/mirror{
+ pixel_x = 30
+ },
+/obj/structure/sink{
+ dir = 4;
+ icon_state = "sink";
+ pixel_x = 11;
+ pixel_y = 0
+ },
+/turf/open/floor/plasteel/freezer,
+/area/ruin/deepstorage)
+"ax" = (
+/obj/structure/table,
+/obj/item/weapon/storage/toolbox/drone,
+/obj/item/device/flashlight,
+/obj/item/device/flashlight,
+/turf/open/floor/plasteel,
+/area/ruin/deepstorage)
+"ay" = (
+/obj/structure/table,
+/obj/item/weapon/gun/ballistic/automatic/wt550{
+ pixel_x = -3;
+ pixel_y = 6
+ },
+/obj/item/weapon/gun/ballistic/automatic/wt550{
+ pixel_x = 2;
+ pixel_y = 0
+ },
+/obj/structure/reagent_dispensers/peppertank{
+ pixel_y = 30
+ },
+/turf/open/floor/plasteel/floorgrime,
+/area/ruin/deepstorage)
+"az" = (
+/obj/structure/table,
+/obj/item/weapon/storage/backpack/dufflebag/sec{
+ contents = newlist(/obj/item/weapon/scalpel,/obj/item/weapon/hemostat,/obj/item/weapon/retractor,/obj/item/weapon/cautery,/obj/item/weapon/circular_saw,/obj/item/weapon/surgical_drapes,/obj/item/clothing/mask/surgical);
+ desc = "A large dufflebag for holding extra supplies - this one has a material inlay with space for various sharp-looking tools.";
+ name = "dufflebag";
+ pixel_y = 5
+ },
+/turf/open/floor/plasteel,
+/area/ruin/deepstorage)
+"aA" = (
+/obj/structure/table,
+/obj/item/device/radio{
+ pixel_x = -4
+ },
+/obj/item/device/radio,
+/obj/item/device/radio{
+ pixel_x = 4
+ },
+/turf/open/floor/plasteel,
+/area/ruin/deepstorage)
+"aB" = (
+/obj/structure/table,
+/obj/item/stack/sheet/metal{
+ amount = 50;
+ pixel_x = 2;
+ pixel_y = 2
+ },
+/obj/item/stack/rods{
+ amount = 50
+ },
+/obj/item/stack/cable_coil,
+/obj/item/stack/cable_coil,
+/turf/open/floor/plasteel,
+/area/ruin/deepstorage)
+"aC" = (
+/obj/structure/table,
+/obj/item/weapon/storage/firstaid/brute{
+ pixel_x = 4;
+ pixel_y = 4
+ },
+/obj/item/weapon/storage/firstaid/brute,
+/turf/open/floor/plasteel,
+/area/ruin/deepstorage)
+"aD" = (
+/obj/structure/table,
+/obj/item/weapon/storage/firstaid/regular{
+ pixel_x = 4;
+ pixel_y = 4
+ },
+/obj/item/weapon/storage/firstaid/regular,
+/obj/machinery/light/small{
+ dir = 4
+ },
+/turf/open/floor/plasteel,
+/area/ruin/deepstorage)
+"aE" = (
+/obj/structure/closet/crate/radiation,
+/turf/open/floor/plasteel,
+/area/ruin/deepstorage)
+"aF" = (
+/obj/structure/closet/cardboard,
+/obj/item/weapon/reagent_containers/food/snacks/beans,
+/obj/item/weapon/reagent_containers/food/snacks/beans,
+/obj/item/weapon/reagent_containers/food/snacks/beans,
+/obj/item/weapon/reagent_containers/food/snacks/beans,
+/obj/item/weapon/reagent_containers/food/snacks/beans,
+/turf/open/floor/plasteel/floorgrime,
+/area/ruin/deepstorage)
+"aG" = (
+/obj/structure/closet/cardboard,
+/obj/item/weapon/reagent_containers/food/snacks/beans,
+/obj/item/weapon/reagent_containers/food/snacks/beans,
+/obj/item/weapon/reagent_containers/food/snacks/beans,
+/obj/machinery/light{
+ dir = 4;
+ icon_state = "tube1"
+ },
+/obj/item/weapon/reagent_containers/food/snacks/beans,
+/obj/item/weapon/reagent_containers/food/snacks/beans,
+/turf/open/floor/plasteel/floorgrime,
+/area/ruin/deepstorage)
+"aH" = (
+/obj/structure/closet/cardboard,
+/obj/item/weapon/reagent_containers/glass/beaker/waterbottle/large,
+/obj/item/weapon/reagent_containers/glass/beaker/waterbottle/large,
+/obj/item/weapon/reagent_containers/glass/beaker/waterbottle/large,
+/obj/item/weapon/reagent_containers/glass/beaker/waterbottle/large,
+/obj/item/weapon/reagent_containers/glass/beaker/waterbottle/large,
+/turf/open/floor/plasteel,
+/area/ruin/deepstorage)
+"aI" = (
+/obj/machinery/vending/clothing,
+/turf/open/floor/wood,
+/area/ruin/deepstorage)
+"aJ" = (
+/turf/open/floor/wood{
+ icon_state = "wood-broken3"
+ },
+/area/ruin/deepstorage)
+"aK" = (
+/obj/structure/bed,
+/turf/open/floor/wood,
+/area/ruin/deepstorage)
+"aL" = (
+/turf/open/floor/plasteel/freezer,
+/area/ruin/deepstorage)
+"aM" = (
+/obj/machinery/light/small{
+ dir = 4
+ },
+/turf/open/floor/plasteel/freezer,
+/area/ruin/deepstorage)
+"aN" = (
+/obj/structure/table,
+/obj/item/clothing/gloves/combat{
+ pixel_x = -3;
+ pixel_y = 4
+ },
+/obj/item/clothing/gloves/combat{
+ pixel_x = 3;
+ pixel_y = -2
+ },
+/obj/item/clothing/mask/gas,
+/obj/item/clothing/mask/gas,
+/obj/item/clothing/mask/gas,
+/turf/open/floor/plasteel/floorgrime,
+/area/ruin/deepstorage)
+"aO" = (
+/turf/open/floor/plasteel,
+/area/ruin/deepstorage)
+"aP" = (
+/obj/structure/table,
+/obj/item/device/mass_spectrometer/adv,
+/obj/item/device/mass_spectrometer/adv,
+/obj/item/device/healthanalyzer,
+/obj/item/device/healthanalyzer,
+/obj/item/stack/medical/gauze,
+/obj/item/stack/medical/gauze,
+/turf/open/floor/plasteel/floorgrime,
+/area/ruin/deepstorage)
+"aQ" = (
+/obj/structure/closet/radiation,
+/obj/machinery/light{
+ icon_state = "tube1";
+ dir = 8
+ },
+/turf/open/floor/plasteel,
+/area/ruin/deepstorage)
+"aR" = (
+/obj/structure/closet/cardboard,
+/obj/item/weapon/reagent_containers/food/snacks/beans,
+/obj/item/weapon/reagent_containers/food/snacks/beans,
+/obj/item/weapon/reagent_containers/food/snacks/beans,
+/obj/item/weapon/reagent_containers/food/snacks/beans,
+/obj/item/weapon/reagent_containers/food/snacks/beans,
+/turf/open/floor/plasteel,
+/area/ruin/deepstorage)
+"aS" = (
+/obj/structure/closet/cardboard,
+/obj/item/weapon/reagent_containers/glass/beaker/waterbottle/large,
+/obj/item/weapon/reagent_containers/glass/beaker/waterbottle/large,
+/obj/item/weapon/reagent_containers/glass/beaker/waterbottle/large,
+/obj/item/weapon/reagent_containers/glass/beaker/waterbottle/large,
+/obj/item/weapon/reagent_containers/glass/beaker/waterbottle/large,
+/turf/open/floor/plasteel/floorgrime,
+/area/ruin/deepstorage)
+"aT" = (
+/obj/structure/closet/wardrobe/pink,
+/turf/open/floor/wood{
+ icon_state = "wood-broken"
+ },
+/area/ruin/deepstorage)
+"aU" = (
+/turf/open/floor/wood,
+/area/ruin/deepstorage)
+"aV" = (
+/obj/structure/bed,
+/turf/open/floor/wood{
+ icon_state = "wood-broken7"
+ },
+/area/ruin/deepstorage)
+"aW" = (
+/obj/machinery/shower{
+ dir = 4
+ },
+/turf/open/floor/plasteel/freezer,
+/area/ruin/deepstorage)
+"aX" = (
+/obj/machinery/shower{
+ dir = 8
+ },
+/turf/open/floor/plasteel/freezer,
+/area/ruin/deepstorage)
+"aY" = (
+/obj/machinery/light/small{
+ dir = 8
+ },
+/obj/structure/table,
+/obj/item/weapon/storage/firstaid/toxin{
+ pixel_x = 4;
+ pixel_y = 4
+ },
+/obj/item/weapon/storage/firstaid/toxin,
+/obj/item/weapon/storage/pill_bottle/charcoal,
+/turf/open/floor/plasteel,
+/area/ruin/deepstorage)
+"aZ" = (
+/obj/structure/table,
+/obj/item/device/flashlight/flare,
+/obj/item/device/flashlight/flare,
+/obj/item/device/flashlight/flare,
+/obj/item/device/flashlight/flare{
+ pixel_y = 6
+ },
+/obj/item/device/flashlight/flare,
+/obj/item/weapon/crowbar/red,
+/turf/open/floor/plasteel,
+/area/ruin/deepstorage)
+"ba" = (
+/obj/machinery/suit_storage_unit/standard_unit,
+/turf/open/floor/plasteel,
+/area/ruin/deepstorage)
+"bb" = (
+/obj/structure/closet/wardrobe/pjs,
+/obj/machinery/light/small{
+ dir = 8
+ },
+/turf/open/floor/wood,
+/area/ruin/deepstorage)
+"bc" = (
+/turf/open/floor/wood{
+ icon_state = "wood-broken4"
+ },
+/area/ruin/deepstorage)
+"bd" = (
+/obj/structure/bed,
+/turf/open/floor/wood{
+ icon_state = "wood-broken3"
+ },
+/area/ruin/deepstorage)
+"be" = (
+/obj/machinery/shower{
+ dir = 4
+ },
+/obj/item/weapon/soap,
+/turf/open/floor/plasteel/freezer,
+/area/ruin/deepstorage)
+"bf" = (
+/obj/structure/grille,
+/obj/structure/window/reinforced/fulltile,
+/turf/open/floor/plating,
+/area/ruin/deepstorage)
+"bg" = (
+/obj/structure/closet/cardboard,
+/obj/item/weapon/storage/box/donkpockets,
+/obj/item/weapon/storage/box/donkpockets,
+/obj/item/weapon/storage/box/donkpockets,
+/obj/item/weapon/storage/box/donkpockets,
+/obj/item/weapon/storage/box/donkpockets,
+/turf/open/floor/plasteel/floorgrime,
+/area/ruin/deepstorage)
+"bh" = (
+/obj/structure/closet/cardboard,
+/obj/item/weapon/storage/box/donkpockets,
+/obj/item/weapon/storage/box/donkpockets,
+/obj/item/weapon/storage/box/donkpockets,
+/obj/item/weapon/storage/box/donkpockets,
+/obj/item/weapon/storage/box/donkpockets,
+/turf/open/floor/plasteel,
+/area/ruin/deepstorage)
+"bi" = (
+/obj/machinery/door/airlock/highsecurity{
+ name = "Bunker"
+ },
+/turf/open/floor/wood,
+/area/ruin/deepstorage)
+"bj" = (
+/obj/machinery/door/airlock/highsecurity{
+ name = "Bunker"
+ },
+/turf/open/floor/plasteel/freezer,
+/area/ruin/deepstorage)
+"bk" = (
+/obj/structure/fireaxecabinet{
+ pixel_y = 30
+ },
+/turf/open/floor/plasteel,
+/area/ruin/deepstorage)
+"bl" = (
+/obj/machinery/sleeper{
+ icon_state = "sleeper-open";
+ dir = 4
+ },
+/obj/machinery/light/small{
+ dir = 8
+ },
+/turf/open/floor/plasteel/floorgrime,
+/area/ruin/deepstorage)
+"bm" = (
+/obj/machinery/light/small{
+ dir = 1
+ },
+/turf/open/floor/plasteel/floorgrime,
+/area/ruin/deepstorage)
+"bn" = (
+/obj/machinery/light/small{
+ dir = 4
+ },
+/turf/open/floor/plasteel/floorgrime,
+/area/ruin/deepstorage)
+"bo" = (
+/obj/machinery/sleeper{
+ icon_state = "sleeper-open";
+ dir = 4
+ },
+/turf/open/floor/plasteel/floorgrime,
+/area/ruin/deepstorage)
+"bp" = (
+/obj/machinery/door/airlock/highsecurity{
+ name = "Bunker"
+ },
+/turf/open/floor/plasteel/floorgrime,
+/area/ruin/deepstorage)
+"bq" = (
+/obj/machinery/processor{
+ name = "processor"
+ },
+/turf/open/floor/plasteel,
+/area/ruin/deepstorage)
+"br" = (
+/obj/structure/table,
+/obj/item/weapon/storage/box/matches,
+/turf/open/floor/plasteel,
+/area/ruin/deepstorage)
+"bs" = (
+/obj/structure/table,
+/obj/machinery/reagentgrinder,
+/turf/open/floor/plasteel/floorgrime,
+/area/ruin/deepstorage)
+"bt" = (
+/obj/structure/table,
+/obj/machinery/recharger,
+/turf/open/floor/plasteel/floorgrime,
+/area/ruin/deepstorage)
+"bu" = (
+/obj/machinery/light{
+ dir = 1
+ },
+/obj/machinery/hydroponics/constructable,
+/turf/open/floor/light,
+/area/ruin/deepstorage)
+"bv" = (
+/obj/machinery/hydroponics/constructable,
+/turf/open/floor/light,
+/area/ruin/deepstorage)
+"bw" = (
+/obj/machinery/blackbox_recorder,
+/turf/open/floor/plasteel,
+/area/ruin/deepstorage)
+"bx" = (
+/obj/structure/cable{
+ icon_state = "0-4";
+ d2 = 4
+ },
+/obj/machinery/power/port_gen/pacman,
+/turf/open/floor/plasteel,
+/area/ruin/deepstorage)
+"by" = (
+/obj/machinery/power/smes/magical{
+ desc = "A high-capacity superconducting magnetic energy storage (SMES) unit.";
+ name = "power storage unit"
+ },
+/obj/structure/cable,
+/obj/structure/cable{
+ icon_state = "0-2";
+ pixel_y = 1;
+ d2 = 2
+ },
+/obj/structure/cable{
+ d1 = 2;
+ d2 = 8;
+ icon_state = "2-8"
+ },
+/turf/open/floor/plasteel/floorgrime,
+/area/ruin/deepstorage)
+"bz" = (
+/obj/machinery/telecomms/relay/preset/telecomms,
+/turf/open/floor/plasteel,
+/area/ruin/deepstorage)
+"bA" = (
+/obj/machinery/light/small{
+ dir = 1
+ },
+/obj/structure/tank_dispenser/oxygen,
+/turf/open/floor/plasteel,
+/area/ruin/deepstorage)
+"bB" = (
+/obj/machinery/biogenerator,
+/turf/open/floor/plasteel,
+/area/ruin/deepstorage)
+"bC" = (
+/obj/machinery/light,
+/obj/machinery/hydroponics/constructable,
+/turf/open/floor/light,
+/area/ruin/deepstorage)
+"bD" = (
+/obj/machinery/autolathe,
+/turf/open/floor/plasteel,
+/area/ruin/deepstorage)
+"bE" = (
+/obj/structure/cable{
+ d1 = 1;
+ d2 = 2;
+ icon_state = "1-2"
+ },
+/obj/machinery/power/terminal{
+ icon_state = "term";
+ dir = 1
+ },
+/turf/open/floor/plasteel,
+/area/ruin/deepstorage)
+"bF" = (
+/obj/structure/reagent_dispensers/fueltank,
+/turf/open/floor/plasteel/floorgrime,
+/area/ruin/deepstorage)
+"bG" = (
+/obj/structure/table,
+/obj/machinery/microwave,
+/turf/open/floor/plasteel/bar,
+/area/ruin/deepstorage)
+"bH" = (
+/turf/open/floor/plasteel/bar,
+/area/ruin/deepstorage)
+"bI" = (
+/obj/structure/table,
+/obj/item/weapon/storage/box/donkpockets,
+/turf/open/floor/plasteel/bar,
+/area/ruin/deepstorage)
+"bJ" = (
+/obj/structure/table,
+/obj/item/weapon/reagent_containers/food/snacks/beans,
+/turf/open/floor/plasteel/bar,
+/area/ruin/deepstorage)
+"bK" = (
+/obj/structure/chair{
+ dir = 8
+ },
+/turf/open/floor/plasteel/bar,
+/area/ruin/deepstorage)
+"bL" = (
+/obj/machinery/seed_extractor,
+/turf/open/floor/plasteel,
+/area/ruin/deepstorage)
+"bM" = (
+/obj/machinery/power/apc{
+ dir = 8;
+ name = "Bunker APC";
+ pixel_x = -24;
+ pixel_y = 0
+ },
+/obj/structure/cable{
+ icon_state = "0-4";
+ d2 = 4
+ },
+/turf/open/floor/plasteel/floorgrime,
+/area/ruin/deepstorage)
+"bN" = (
+/obj/structure/cable{
+ d1 = 4;
+ d2 = 8;
+ icon_state = "4-8";
+ pixel_y = 0;
+ tag = ""
+ },
+/turf/open/floor/plasteel,
+/area/ruin/deepstorage)
+"bO" = (
+/obj/structure/cable{
+ d1 = 1;
+ d2 = 8;
+ icon_state = "1-8";
+ tag = ""
+ },
+/turf/open/floor/plasteel,
+/area/ruin/deepstorage)
+"bP" = (
+/obj/structure/reagent_dispensers/watertank,
+/turf/open/floor/plasteel/floorgrime,
+/area/ruin/deepstorage)
+"bQ" = (
+/obj/structure/table,
+/obj/item/weapon/kitchen/knife,
+/turf/open/floor/plasteel/bar,
+/area/ruin/deepstorage)
+"bR" = (
+/obj/structure/table,
+/turf/open/floor/plasteel/bar,
+/area/ruin/deepstorage)
+"bS" = (
+/obj/structure/table,
+/obj/item/weapon/kitchen/fork,
+/turf/open/floor/plasteel/bar,
+/area/ruin/deepstorage)
+"bT" = (
+/obj/machinery/vending/hydronutrients,
+/turf/open/floor/plasteel,
+/area/ruin/deepstorage)
+"bU" = (
+/obj/machinery/space_heater,
+/turf/open/floor/plasteel/floorgrime,
+/area/ruin/deepstorage)
+"bV" = (
+/obj/structure/chair/office/dark{
+ dir = 4
+ },
+/turf/open/floor/plasteel,
+/area/ruin/deepstorage)
+"bW" = (
+/obj/structure/table/reinforced,
+/turf/open/floor/plasteel,
+/area/ruin/deepstorage)
+"bX" = (
+/obj/machinery/smartfridge,
+/turf/open/floor/plasteel/bar,
+/area/ruin/deepstorage)
+"bY" = (
+/obj/machinery/light/small,
+/turf/open/floor/plasteel/bar,
+/area/ruin/deepstorage)
+"bZ" = (
+/obj/machinery/vending/hydroseeds{
+ slogan_delay = 700
+ },
+/turf/open/floor/plasteel,
+/area/ruin/deepstorage)
+"ca" = (
+/obj/machinery/light/small{
+ dir = 8
+ },
+/turf/open/floor/plasteel/floorgrime,
+/area/ruin/deepstorage)
+"cb" = (
+/obj/structure/chair/office/dark,
+/turf/open/floor/plasteel/floorgrime,
+/area/ruin/deepstorage)
+"cc" = (
+/obj/structure/frame/computer,
+/turf/open/floor/plasteel,
+/area/ruin/deepstorage)
+"cd" = (
+/obj/structure/table/reinforced,
+/obj/machinery/computer/security/telescreen{
+ dir = 1;
+ name = "Bunker Entrance";
+ network = list("Bunker1");
+ pixel_x = 0;
+ pixel_y = 2
+ },
+/turf/open/floor/plasteel,
+/area/ruin/deepstorage)
+"ce" = (
+/obj/structure/table/reinforced,
+/obj/machinery/button/door{
+ id = "bunker1";
+ name = "Inner Doors";
+ pixel_y = 6
+ },
+/obj/machinery/button/door{
+ id = "bunker2";
+ name = "Outer Doors";
+ pixel_y = -4
+ },
+/turf/open/floor/plasteel/floorgrime,
+/area/ruin/deepstorage)
+"cf" = (
+/obj/machinery/door/poddoor{
+ id = "bunker1";
+ name = "Bunker Door";
+ tag = "inner"
+ },
+/turf/open/floor/plating,
+/area/ruin/deepstorage)
+"cg" = (
+/turf/open/floor/plating,
+/area/ruin/deepstorage)
+"ch" = (
+/obj/machinery/camera{
+ network = list("Bunker1")
+ },
+/turf/open/floor/plating,
+/area/ruin/deepstorage)
+"ci" = (
+/obj/machinery/light/small{
+ dir = 4
+ },
+/turf/open/floor/plating,
+/area/ruin/deepstorage)
+"cj" = (
+/obj/machinery/door/poddoor{
+ id = "bunker2";
+ name = "Bunker Door";
+ tag = "outer"
+ },
+/turf/open/floor/plating,
+/area/ruin/deepstorage)
+"ck" = (
+/turf/open/floor/plating/asteroid/airless,
+/area/ruin/deepstorage)
+
+(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
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+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
+aa
+"}
+(2,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+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
+ab
+ab
+ab
+ab
+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
+"}
+(3,1,1) = {"
+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
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(4,1,1) = {"
+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
+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
+"}
+(5,1,1) = {"
+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
+ab
+ab
+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
+"}
+(6,1,1) = {"
+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
+ab
+ab
+ab
+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
+"}
+(7,1,1) = {"
+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
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aa
+aa
+ab
+ab
+ab
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(8,1,1) = {"
+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
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(9,1,1) = {"
+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
+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
+"}
+(10,1,1) = {"
+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
+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
+"}
+(11,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+ab
+ab
+ab
+ab
+ab
+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
+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
+"}
+(12,1,1) = {"
+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
+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
+ab
+ab
+ab
+ab
+ab
+ab
+aa
+aa
+"}
+(13,1,1) = {"
+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
+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
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aa
+"}
+(14,1,1) = {"
+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
+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
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aa
+"}
+(15,1,1) = {"
+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
+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
+"}
+(16,1,1) = {"
+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
+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
+"}
+(17,1,1) = {"
+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
+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
+ab
+aa
+"}
+(18,1,1) = {"
+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
+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
+ab
+ab
+ab
+"}
+(19,1,1) = {"
+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
+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
+ab
+ab
+ab
+"}
+(20,1,1) = {"
+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
+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
+ab
+ab
+ab
+"}
+(21,1,1) = {"
+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
+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
+ab
+ab
+ab
+"}
+(22,1,1) = {"
+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
+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
+ab
+ab
+ab
+"}
+(23,1,1) = {"
+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
+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
+ck
+ck
+ck
+ab
+ab
+ab
+ab
+ab
+"}
+(24,1,1) = {"
+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
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ac
+ac
+ac
+ac
+ac
+ac
+ac
+ac
+ac
+ac
+ac
+ac
+ac
+ac
+ab
+ck
+ck
+ck
+ck
+ck
+ck
+ck
+ck
+ab
+ab
+ab
+"}
+(25,1,1) = {"
+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
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ac
+bl
+bo
+ac
+bw
+bD
+bM
+bU
+ca
+ar
+cf
+cg
+cg
+ac
+ck
+ck
+ck
+ck
+ck
+ck
+ck
+ck
+ck
+ck
+ab
+ab
+"}
+(26,1,1) = {"
+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
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ac
+ar
+ar
+ac
+bx
+ar
+bN
+ar
+aO
+ar
+cf
+cg
+cg
+ac
+ck
+ck
+ck
+ck
+ck
+ck
+ck
+ck
+ck
+ck
+ck
+ck
+"}
+(27,1,1) = {"
+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
+ab
+ab
+ab
+ab
+ab
+ac
+ac
+ac
+ac
+ac
+ac
+bp
+ac
+by
+bE
+bO
+aO
+ar
+aO
+ac
+cg
+cg
+ac
+ck
+ck
+ck
+ck
+ck
+ck
+ck
+ck
+ck
+ck
+ck
+ck
+"}
+(28,1,1) = {"
+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
+ab
+ab
+ab
+ab
+ab
+ac
+aI
+aT
+bb
+ac
+ar
+aO
+ac
+bz
+aO
+aO
+ar
+aO
+cd
+ac
+ch
+cg
+cj
+ck
+ck
+ck
+ck
+ab
+ab
+ab
+ck
+ck
+ck
+ck
+ck
+"}
+(29,1,1) = {"
+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
+ab
+ab
+ab
+ab
+ab
+ac
+aJ
+aU
+bc
+bi
+ar
+ar
+ac
+aO
+ar
+aO
+ar
+cb
+cc
+ac
+ci
+cg
+cj
+ck
+ck
+ck
+ck
+ab
+ab
+ab
+ab
+ck
+ck
+ck
+ck
+"}
+(30,1,1) = {"
+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
+ab
+ab
+ab
+ab
+ab
+ac
+aK
+aV
+bd
+ac
+ar
+aO
+au
+ar
+ar
+aO
+bV
+aO
+ce
+ac
+ac
+ac
+ac
+ck
+ck
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ck
+ck
+"}
+(31,1,1) = {"
+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
+ab
+ab
+ab
+ab
+ac
+ac
+ac
+ac
+ac
+ac
+bm
+aO
+ac
+bA
+bF
+bP
+bW
+cc
+bW
+ac
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+"}
+(32,1,1) = {"
+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
+ab
+ab
+ab
+ab
+ac
+av
+aL
+aW
+be
+ac
+aO
+aO
+ac
+ac
+ac
+ac
+ac
+ac
+ac
+ac
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+"}
+(33,1,1) = {"
+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
+ab
+ab
+ab
+ab
+ac
+aw
+aM
+aX
+aX
+bj
+aO
+aO
+ar
+ar
+bG
+bQ
+bX
+ac
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aa
+"}
+(34,1,1) = {"
+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
+ab
+ab
+ab
+ab
+ac
+ac
+ac
+ac
+ac
+ac
+aO
+aO
+aO
+ar
+bH
+bH
+bY
+ac
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aa
+"}
+(35,1,1) = {"
+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
+ab
+ab
+ab
+ab
+ac
+ax
+aN
+aY
+ac
+bk
+ar
+bq
+ac
+ar
+bI
+bR
+bH
+ac
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aa
+"}
+(36,1,1) = {"
+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
+ab
+ab
+ab
+ac
+ay
+ar
+ar
+bf
+ar
+ar
+br
+ac
+aO
+bJ
+bS
+bH
+ac
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aa
+"}
+(37,1,1) = {"
+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
+ab
+ab
+ab
+ac
+az
+aO
+aO
+bf
+aO
+ar
+bs
+ac
+aO
+bK
+bK
+bH
+ac
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aa
+"}
+(38,1,1) = {"
+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
+ab
+ab
+ab
+ac
+aA
+ar
+aO
+au
+aO
+aO
+bt
+ac
+ar
+ar
+ar
+ar
+ac
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aa
+"}
+(39,1,1) = {"
+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
+ab
+ab
+ab
+ac
+aB
+ar
+aO
+bf
+aO
+aO
+aO
+aO
+aO
+ar
+ar
+aO
+ac
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aa
+aa
+"}
+(40,1,1) = {"
+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
+ab
+ab
+ab
+ac
+aC
+aO
+ar
+bf
+aO
+bn
+aO
+aO
+bB
+bL
+bT
+bZ
+ac
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aa
+aa
+"}
+(41,1,1) = {"
+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
+ac
+ac
+ac
+ac
+ac
+aD
+aP
+aZ
+ac
+au
+ac
+ac
+au
+ac
+ac
+ac
+ac
+ac
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aa
+aa
+"}
+(42,1,1) = {"
+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
+ac
+ad
+aj
+ap
+ac
+ac
+ac
+ac
+ac
+aO
+ac
+bu
+aO
+bC
+ac
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aa
+"}
+(43,1,1) = {"
+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
+ac
+ae
+ak
+aq
+ac
+aE
+aQ
+ba
+ba
+aO
+ac
+bv
+aO
+bv
+ac
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aa
+"}
+(44,1,1) = {"
+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
+ac
+af
+al
+ar
+au
+ar
+ar
+aO
+aO
+ar
+ac
+bv
+aO
+bv
+ac
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aa
+"}
+(45,1,1) = {"
+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
+ac
+ag
+am
+ar
+ac
+aF
+aR
+aR
+bg
+bg
+ac
+bu
+aO
+bC
+ac
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aa
+"}
+(46,1,1) = {"
+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
+ac
+ah
+an
+as
+ac
+aG
+aR
+aR
+bh
+bh
+ac
+ac
+ac
+ac
+ac
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aa
+"}
+(47,1,1) = {"
+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
+ac
+ai
+ao
+at
+ac
+aH
+aS
+aH
+aH
+aH
+ac
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aa
+"}
+(48,1,1) = {"
+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
+ac
+ac
+ac
+ac
+ac
+aH
+aH
+aH
+aH
+aH
+ac
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aa
+"}
+(49,1,1) = {"
+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
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ac
+ac
+ac
+ac
+ac
+ac
+ac
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aa
+"}
+(50,1,1) = {"
+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
+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
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+"}
+(51,1,1) = {"
+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
+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
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+"}
+(52,1,1) = {"
+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
+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
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+"}
+(53,1,1) = {"
+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
+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
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+"}
+(54,1,1) = {"
+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
+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
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+"}
+(55,1,1) = {"
+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
+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
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+"}
+(56,1,1) = {"
+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
+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
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+"}
+(57,1,1) = {"
+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
+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
+ab
+ab
+ab
+ab
+ab
+ab
+aa
+"}
+(58,1,1) = {"
+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
+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
+ab
+ab
+ab
+ab
+ab
+ab
+aa
+"}
+(59,1,1) = {"
+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
+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
+ab
+ab
+ab
+ab
+aa
+"}
+(60,1,1) = {"
+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
+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
+ab
+ab
+ab
+aa
+aa
+"}
+(61,1,1) = {"
+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
+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
+ab
+ab
+ab
+aa
+aa
+"}
+(62,1,1) = {"
+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
+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
+ab
+ab
+ab
+aa
+aa
+"}
+(63,1,1) = {"
+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
+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
+ab
+ab
+ab
+aa
+aa
+"}
+(64,1,1) = {"
+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
+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
+ab
+ab
+aa
+aa
+aa
+"}
+(65,1,1) = {"
+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
+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
+ab
+ab
+aa
+aa
+aa
+"}
+(66,1,1) = {"
+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
+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
+ab
+ab
+ab
+aa
+aa
+aa
+"}
+(67,1,1) = {"
+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
+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
+ab
+ab
+ab
+aa
+aa
+aa
+"}
+(68,1,1) = {"
+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
+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
+ab
+ab
+ab
+aa
+aa
+aa
+aa
+"}
+(69,1,1) = {"
+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
+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
+ab
+ab
+ab
+aa
+aa
+aa
+aa
+"}
+(70,1,1) = {"
+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
+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
+ab
+ab
+ab
+ab
+aa
+aa
+aa
+aa
+"}
+(71,1,1) = {"
+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
+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
+ab
+ab
+ab
+ab
+aa
+aa
+aa
+aa
+"}
+(72,1,1) = {"
+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
+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
+ab
+ab
+ab
+ab
+aa
+aa
+aa
+aa
+"}
+(73,1,1) = {"
+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
+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
+ab
+ab
+ab
+ab
+ab
+aa
+aa
+aa
+aa
+"}
+(74,1,1) = {"
+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
+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
+ab
+ab
+ab
+ab
+ab
+aa
+aa
+aa
+aa
+"}
+(75,1,1) = {"
+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
+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
+ab
+ab
+ab
+ab
+ab
+aa
+aa
+aa
+aa
+"}
+(76,1,1) = {"
+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
+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
+ab
+ab
+ab
+ab
+aa
+aa
+aa
+aa
+aa
+"}
+(77,1,1) = {"
+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
+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
+ab
+ab
+ab
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(78,1,1) = {"
+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
+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
+ab
+ab
+ab
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(79,1,1) = {"
+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
+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
+ab
+ab
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(80,1,1) = {"
+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
+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
+ab
+ab
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(81,1,1) = {"
+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
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+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
+"}
+(82,1,1) = {"
+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
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+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
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(83,1,1) = {"
+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
+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
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(84,1,1) = {"
+aa
+aa
+ab
+ab
+ab
+aa
+aa
+ab
+ab
+aa
+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
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(85,1,1) = {"
+aa
+aa
+ab
+ab
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aa
+aa
+aa
+aa
+aa
+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
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
diff --git a/_maps/map_files/generic/Centcomm.dmm b/_maps/map_files/generic/Centcomm.dmm
index 6782e4cce4..d36c5165dc 100644
--- a/_maps/map_files/generic/Centcomm.dmm
+++ b/_maps/map_files/generic/Centcomm.dmm
@@ -20,7 +20,7 @@
/turf/closed/indestructible/riveted,
/area/space)
"af" = (
-/turf/open/floor/holofloor/snow/cold,
+/turf/open/floor/holofloor/snow,
/area/holodeck/rec_center/winterwonderland)
"ag" = (
/obj/structure/window/reinforced{
@@ -141,7 +141,7 @@
/area/space)
"ax" = (
/obj/structure/flora/bush,
-/turf/open/floor/holofloor/snow/cold,
+/turf/open/floor/holofloor/snow,
/area/holodeck/rec_center/winterwonderland)
"ay" = (
/obj/item/toy/snowball{
@@ -155,7 +155,7 @@
/obj/item/toy/snowball{
pixel_x = -4
},
-/turf/open/floor/holofloor/snow/cold,
+/turf/open/floor/holofloor/snow,
/area/holodeck/rec_center/winterwonderland)
"az" = (
/turf/open/floor/holofloor{
@@ -216,7 +216,7 @@
/area/holodeck/rec_center/court)
"aI" = (
/obj/structure/flora/grass/brown,
-/turf/open/floor/holofloor/snow/cold,
+/turf/open/floor/holofloor/snow,
/area/holodeck/rec_center/winterwonderland)
"aJ" = (
/obj/structure/table,
@@ -268,7 +268,7 @@
/obj/structure/statue/snow/snowman{
anchored = 1
},
-/turf/open/floor/holofloor/snow/cold,
+/turf/open/floor/holofloor/snow,
/area/holodeck/rec_center/winterwonderland)
"aP" = (
/obj/structure/chair/wood/normal{
@@ -282,7 +282,7 @@
/area/holodeck/rec_center/lounge)
"aQ" = (
/obj/structure/chair/wood/wings,
-/turf/open/floor/holofloor/snow/cold,
+/turf/open/floor/holofloor/snow,
/area/holodeck/rec_center/winterwonderland)
"aR" = (
/obj/structure/window/reinforced/tinted{
@@ -303,11 +303,11 @@
/area/holodeck/rec_center/lounge)
"aT" = (
/obj/structure/flora/tree/pine,
-/turf/open/floor/holofloor/snow/cold,
+/turf/open/floor/holofloor/snow,
/area/holodeck/rec_center/winterwonderland)
"aU" = (
/obj/structure/chair/wood,
-/turf/open/floor/holofloor/snow/cold,
+/turf/open/floor/holofloor/snow,
/area/holodeck/rec_center/winterwonderland)
"aV" = (
/obj/structure/table/wood,
diff --git a/bot/config.py b/bot/config.py
index 8888753ab7..c0ffc55bed 100644
--- a/bot/config.py
+++ b/bot/config.py
@@ -1,6 +1,7 @@
# Configuration for the minibot.py bot starts here
server = "irc.rizon.net"
port = 6667
+nudge_port = 45678
channels = ["#asdfgbus", "#botbus"]
defaultchannel = "#asdfgbus"
diff --git a/bot/minibot.py b/bot/minibot.py
index 82e46722f8..cc5ac1a5b4 100644
--- a/bot/minibot.py
+++ b/bot/minibot.py
@@ -73,7 +73,7 @@ def setup_irc_socket():
def setup_nudge_socket():
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- s.bind(("", 45678)) # localhost:45678
+ s.bind(("", nudge_port)) # localhost:nudge_port
s.listen(5)
logger.info("Nudge socket up and listening")
return s
diff --git a/bot/nudge.py b/bot/nudge.py
index 7f195adae1..8a13c5636b 100644
--- a/bot/nudge.py
+++ b/bot/nudge.py
@@ -1,4 +1,5 @@
#!/usr/bin/env python3
+from config import *
import sys
import pickle
import socket
@@ -16,7 +17,7 @@ def pack():
def nudge(data):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- s.connect(("localhost", 45678))
+ s.connect(("localhost", nudge_port))
s.send(data)
s.close()
diff --git a/code/__DEFINES/antagonists.dm b/code/__DEFINES/antagonists.dm
new file mode 100644
index 0000000000..d30a2d098f
--- /dev/null
+++ b/code/__DEFINES/antagonists.dm
@@ -0,0 +1,3 @@
+#define ANTAG_DATUM_CULT /datum/antagonist/cult
+#define ANTAG_DATUM_CLOCKCULT /datum/antagonist/clockcult
+#define ANTAG_DATUM_CLOCKCULT_SILENT /datum/antagonist/clockcult/silent
\ No newline at end of file
diff --git a/code/__DEFINES/language.dm b/code/__DEFINES/language.dm
index 3f09f46817..e7818d7bf3 100644
--- a/code/__DEFINES/language.dm
+++ b/code/__DEFINES/language.dm
@@ -1,2 +1,4 @@
#define NO_STUTTER 1
#define TONGUELESS_SPEECH 2
+#define LANGUAGE_HIDE_ICON_IF_UNDERSTOOD 4
+#define LANGUAGE_HIDE_ICON_IF_NOT_UNDERSTOOD 8
diff --git a/code/__DEFINES/machines.dm b/code/__DEFINES/machines.dm
index 004ea378da..9524fc9a43 100644
--- a/code/__DEFINES/machines.dm
+++ b/code/__DEFINES/machines.dm
@@ -23,6 +23,7 @@
#define MECHFAB 16 //Remember, objects utilising this flag should have construction_time and construction_cost vars.
#define BIOGENERATOR 32 //Uses biomass
#define LIMBGROWER 64 //Uses synthetic flesh
+#define SMELTER 128 //uses various minerals
//Note: More then one of these can be added to a design but imprinter and lathe designs are incompatable.
//Modular computer/NTNet defines
diff --git a/code/__DEFINES/qdel.dm b/code/__DEFINES/qdel.dm
index fe19d7a559..041a6283e7 100644
--- a/code/__DEFINES/qdel.dm
+++ b/code/__DEFINES/qdel.dm
@@ -14,5 +14,6 @@
#define GC_QUEUED_FOR_HARD_DEL -2
#define GC_CURRENTLY_BEING_QDELETED -3
-#define QDELETED(X) (!X || X.gc_destroyed)
+#define QDELING(X) (X.gc_destroyed)
+#define QDELETED(X) (!X || QDELING(X))
#define QDESTROYING(X) (!X || X.gc_destroyed == GC_CURRENTLY_BEING_QDELETED)
diff --git a/code/__DEFINES/subsystems.dm b/code/__DEFINES/subsystems.dm
index 0b27e01326..c0b9a20d3b 100644
--- a/code/__DEFINES/subsystems.dm
+++ b/code/__DEFINES/subsystems.dm
@@ -20,6 +20,24 @@
#define FLIGHTSUIT_PROCESSING_NONE 0
#define FLIGHTSUIT_PROCESSING_FULL 1
+#define INITIALIZATION_INSSATOMS 0 //New should not call Initialize
+#define INITIALIZATION_INNEW_MAPLOAD 1 //New should call Initialize(TRUE)
+#define INITIALIZATION_INNEW_REGULAR 2 //New should call Initialize(FALSE)
+
+#define INITIALIZE_HINT_NORMAL 0 //Nothing happens
+#define INITIALIZE_HINT_LATELOAD 1 //Call LateInitialize
+#define INITIALIZE_HINT_QDEL 2 //Call qdel on the atom
+
+//type and all subtypes should always call Initialize in New()
+#define INITIALIZE_IMMEDIATE(X) ##X/New(loc, ...){\
+ ..();\
+ if(!initialized) {\
+ args[1] = TRUE;\
+ SSatoms.InitAtom(src, args);\
+ }\
+}
+
+
// Subsystem init_order, from highest priority to lowest priority
// The numbers just define the ordering, they are meaningless otherwise.
diff --git a/code/__HELPERS/icons.dm b/code/__HELPERS/icons.dm
index 48bf1f3ab9..31e67197a8 100644
--- a/code/__HELPERS/icons.dm
+++ b/code/__HELPERS/icons.dm
@@ -991,7 +991,7 @@ GLOBAL_LIST_EMPTY(friendly_animal_types)
SET_SECONDARY_FLAG(src, FROZEN)
//Assumes already frozed
-obj/proc/make_unfrozen()
+/obj/proc/make_unfrozen()
icon = initial(icon)
name = replacetext(name, "frozen ", "")
CLEAR_SECONDARY_FLAG(src, FROZEN)
diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm
index a7338a0c5d..1da1b50aa3 100644
--- a/code/__HELPERS/unsorted.dm
+++ b/code/__HELPERS/unsorted.dm
@@ -582,7 +582,7 @@ Turf and target are seperate in case you want to teleport some distance from a t
return 0
//Repopulates sortedAreas list
-/proc/SortAreas()
+/proc/repopulate_sorted_areas()
GLOB.sortedAreas = list()
for(var/area/A in world)
diff --git a/code/_globalvars/lists/mobs.dm b/code/_globalvars/lists/mobs.dm
index 32969dd5d8..e378970225 100644
--- a/code/_globalvars/lists/mobs.dm
+++ b/code/_globalvars/lists/mobs.dm
@@ -11,6 +11,7 @@ GLOBAL_LIST_EMPTY(stealthminID) //reference list with IDs that store ckeys,
GLOBAL_LIST_EMPTY(player_list) //all mobs **with clients attached**. Excludes /mob/dead/new_player
GLOBAL_LIST_EMPTY(mob_list) //all mobs, including clientless
+GLOBAL_LIST_EMPTY(mob_directory) //mob_id -> mob
GLOBAL_LIST_EMPTY(living_mob_list) //all alive mobs, including clientless. Excludes /mob/dead/new_player
GLOBAL_LIST_EMPTY(dead_mob_list) //all dead mobs, including clientless. Excludes /mob/dead/new_player
GLOBAL_LIST_EMPTY(joined_player_list) //all clients that have joined the game at round-start or as a latejoin.
diff --git a/code/_globalvars/lists/names.dm b/code/_globalvars/lists/names.dm
index 15a0867667..5726a1501d 100644
--- a/code/_globalvars/lists/names.dm
+++ b/code/_globalvars/lists/names.dm
@@ -1,23 +1,23 @@
-GLOBAL_LIST_INIT(ai_names, world.file2list("config/names/ai.txt"))
-GLOBAL_LIST_INIT(wizard_first, world.file2list("config/names/wizardfirst.txt"))
-GLOBAL_LIST_INIT(wizard_second, world.file2list("config/names/wizardsecond.txt"))
-GLOBAL_LIST_INIT(ninja_titles, world.file2list("config/names/ninjatitle.txt"))
-GLOBAL_LIST_INIT(ninja_names, world.file2list("config/names/ninjaname.txt"))
-GLOBAL_LIST_INIT(commando_names, world.file2list("config/names/death_commando.txt"))
-GLOBAL_LIST_INIT(first_names_male, world.file2list("config/names/first_male.txt"))
-GLOBAL_LIST_INIT(first_names_female, world.file2list("config/names/first_female.txt"))
-GLOBAL_LIST_INIT(last_names, world.file2list("config/names/last.txt"))
-GLOBAL_LIST_INIT(lizard_names_male, world.file2list("config/names/lizard_male.txt"))
-GLOBAL_LIST_INIT(lizard_names_female, world.file2list("config/names/lizard_female.txt"))
-GLOBAL_LIST_INIT(clown_names, world.file2list("config/names/clown.txt"))
-GLOBAL_LIST_INIT(mime_names, world.file2list("config/names/mime.txt"))
-GLOBAL_LIST_INIT(carp_names, world.file2list("config/names/carp.txt"))
-GLOBAL_LIST_INIT(golem_names, world.file2list("config/names/golem.txt"))
-GLOBAL_LIST_INIT(plasmaman_names, world.file2list("config/names/plasmaman.txt"))
-GLOBAL_LIST_INIT(posibrain_names, list("PBU","HIU","SINA","ARMA","OSI","HBL","MSO","RR","CHRI","CDB","HG","XSI","ORNG","GUN","KOR","MET","FRE","XIS","SLI","PKP","HOG","RZH","GOOF","MRPR","JJR","FIRC","INC","PHL","BGB","ANTR","MIW","WJ","JRD","CHOC","ANCL","JLLO","JNLG","KOS","TKRG","XAL","STLP","CBOS","DUNC","FXMC","DRSD","COI"))
+GLOBAL_LIST_INIT(ai_names, world.file2list("strings/names/ai.txt"))
+GLOBAL_LIST_INIT(wizard_first, world.file2list("strings/names/wizardfirst.txt"))
+GLOBAL_LIST_INIT(wizard_second, world.file2list("strings/names/wizardsecond.txt"))
+GLOBAL_LIST_INIT(ninja_titles, world.file2list("strings/names/ninjatitle.txt"))
+GLOBAL_LIST_INIT(ninja_names, world.file2list("strings/names/ninjaname.txt"))
+GLOBAL_LIST_INIT(commando_names, world.file2list("strings/names/death_commando.txt"))
+GLOBAL_LIST_INIT(first_names_male, world.file2list("strings/names/first_male.txt"))
+GLOBAL_LIST_INIT(first_names_female, world.file2list("strings/names/first_female.txt"))
+GLOBAL_LIST_INIT(last_names, world.file2list("strings/names/last.txt"))
+GLOBAL_LIST_INIT(lizard_names_male, world.file2list("strings/names/lizard_male.txt"))
+GLOBAL_LIST_INIT(lizard_names_female, world.file2list("strings/names/lizard_female.txt"))
+GLOBAL_LIST_INIT(clown_names, world.file2list("strings/names/clown.txt"))
+GLOBAL_LIST_INIT(mime_names, world.file2list("strings/names/mime.txt"))
+GLOBAL_LIST_INIT(carp_names, world.file2list("strings/names/carp.txt"))
+GLOBAL_LIST_INIT(golem_names, world.file2list("strings/names/golem.txt"))
+GLOBAL_LIST_INIT(plasmaman_names, world.file2list("strings/names/plasmaman.txt"))
+GLOBAL_LIST_INIT(posibrain_names, world.file2list("strings/names/posibrain.txt"))
-GLOBAL_LIST_INIT(verbs, world.file2list("config/names/verbs.txt"))
-GLOBAL_LIST_INIT(adjectives, world.file2list("config/names/adjectives.txt"))
+GLOBAL_LIST_INIT(verbs, world.file2list("strings/names/verbs.txt"))
+GLOBAL_LIST_INIT(adjectives, world.file2list("strings/names/adjectives.txt"))
//loaded on startup because of "
//would include in rsc if ' was used
diff --git a/code/_onclick/hud/screen_objects.dm b/code/_onclick/hud/screen_objects.dm
index a3a60b1f31..81754efc93 100644
--- a/code/_onclick/hud/screen_objects.dm
+++ b/code/_onclick/hud/screen_objects.dm
@@ -544,7 +544,7 @@
plane = SPLASHSCREEN_PLANE
var/client/holder
-/obj/screen/splash/New(client/C, visible, use_previous_title)
+/obj/screen/splash/New(client/C, visible, use_previous_title) //TODO: Make this use INITIALIZE_IMMEDIATE
holder = C
if(!visible)
diff --git a/code/citadel/_cit_helpers.dm b/code/citadel/_cit_helpers.dm
index 6e4ea762f1..db0626fa9c 100644
--- a/code/citadel/_cit_helpers.dm
+++ b/code/citadel/_cit_helpers.dm
@@ -117,7 +117,7 @@ GLOBAL_VAR_INIT(dlooc_allowed, 1)
prefs.chat_toggles ^= CHAT_LOOC
prefs.save_preferences()
src << "You will [(prefs.chat_toggles & CHAT_LOOC) ? "now" : "no longer"] see messages on the LOOC channel."
- feedback_add_details("admin_verb","TLOOC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+ SSblackbox.add_details("admin_verb","TLOOC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/datum/admins/proc/togglelooc()
set category = "Server"
@@ -126,7 +126,7 @@ GLOBAL_VAR_INIT(dlooc_allowed, 1)
toggle_looc()
log_admin("[key_name(usr)] toggled LOOC.")
message_admins("[key_name_admin(usr)] toggled LOOC.")
- feedback_add_details("admin_verb","TLOOC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+ SSblackbox.add_details("admin_verb","TLOOC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/proc/toggle_looc(toggle = null)
if(toggle != null) //if we're specifically en/disabling ooc
@@ -146,7 +146,7 @@ GLOBAL_VAR_INIT(dlooc_allowed, 1)
log_admin("[key_name(usr)] toggled Dead LOOC.")
message_admins("[key_name_admin(usr)] toggled Dead LOOC.")
- feedback_add_details("admin_verb","TDLOOC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+ SSblackbox.add_details("admin_verb","TDLOOC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/mob/living/carbon/proc/has_penis()
diff --git a/code/citadel/cit_guns.dm b/code/citadel/cit_guns.dm
index 820fd233d7..6a51ad4bd2 100644
--- a/code/citadel/cit_guns.dm
+++ b/code/citadel/cit_guns.dm
@@ -1,6 +1,7 @@
/obj/item/weapon/gun/energy/laser/carbine
name = "laser carbine"
desc = "A ruggedized laser carbine featuring much higher capacity and improved handling when compared to a normal laser gun."
+ icon = 'icons/obj/guns/cit_guns.dmi'
icon_state = "lasernew"
item_state = "laser"
origin_tech = "combat=4;magnets=4"
diff --git a/code/citadel/cit_vendors.dm b/code/citadel/cit_vendors.dm
index 32cd034b8b..7fee8705f1 100644
--- a/code/citadel/cit_vendors.dm
+++ b/code/citadel/cit_vendors.dm
@@ -76,6 +76,7 @@
refill_canister = /obj/item/weapon/vending_refill/soviet
+
#undef STANDARD_CHARGE
#undef CONTRABAND_CHARGE
#undef COIN_CHARGE
diff --git a/code/citadel/organs/genitals.dm b/code/citadel/organs/genitals.dm
index 4066295350..c129d8e8fa 100644
--- a/code/citadel/organs/genitals.dm
+++ b/code/citadel/organs/genitals.dm
@@ -16,7 +16,8 @@
/obj/item/organ/genital/Initialize()
. = ..()
- reagents = create_reagents(fluid_max_volume)
+ if(!reagents)
+ create_reagents(fluid_max_volume)
update()
/obj/item/organ/genital/Destroy()
diff --git a/code/controllers/admin.dm b/code/controllers/admin.dm
index 99f6a148a4..3565620c88 100644
--- a/code/controllers/admin.dm
+++ b/code/controllers/admin.dm
@@ -3,7 +3,9 @@
name = "Initializing..."
var/target
-/obj/effect/statclick/New(loc, text, target) //Don't port this to Initialize it's too critical
+INITIALIZE_IMMEDIATE(/obj/effect/statclick)
+
+/obj/effect/statclick/Initialize(mapload, text, target) //Don't port this to Initialize it's too critical
..()
name = text
src.target = target
@@ -43,9 +45,9 @@
switch(controller)
if("Master")
Recreate_MC()
- feedback_add_details("admin_verb","Restart Master Controller")
+ SSblackbox.add_details("admin_verb","Restart Master Controller")
if("Failsafe")
new /datum/controller/failsafe()
- feedback_add_details("admin_verb","Restart Failsafe Controller")
+ SSblackbox.add_details("admin_verb","Restart Failsafe Controller")
message_admins("Admin [key_name_admin(usr)] has restarted the [controller] controller.")
diff --git a/code/controllers/globals.dm b/code/controllers/globals.dm
index a1a0a3f838..cd86e0d97c 100644
--- a/code/controllers/globals.dm
+++ b/code/controllers/globals.dm
@@ -16,13 +16,14 @@ GLOBAL_REAL(GLOB, /datum/controller/global_vars)
gvars_datum_in_built_vars = exclude_these.vars + list("gvars_datum_protected_varlist", "gvars_datum_in_built_vars", "gvars_datum_init_order")
qdel(exclude_these)
+ log_world("[vars.len - gvars_datum_in_built_vars.len] global variables")
+
Initialize()
/datum/controller/global_vars/Destroy(force)
+ stack_trace("Some fucker qdel'd the global holder!")
if(!force)
return QDEL_HINT_LETMELIVE
-
- stack_trace("Some fucker deleted the global holder!")
QDEL_NULL(statclick)
gvars_datum_protected_varlist.Cut()
@@ -36,10 +37,7 @@ GLOBAL_REAL(GLOB, /datum/controller/global_vars)
if(!statclick)
statclick = new/obj/effect/statclick/debug(null, "Initializing...", src)
- var/static/num_globals
- if(!num_globals)
- num_globals = vars.len - gvars_datum_in_built_vars.len
- stat("Globals:", statclick.update("Count: [num_globals]"))
+ stat("Globals:", statclick.update("Edit"))
/datum/controller/global_vars/can_vv_get(var_name)
if(var_name in gvars_datum_protected_varlist)
diff --git a/code/controllers/subsystem/atoms.dm b/code/controllers/subsystem/atoms.dm
index c687a7b0e5..711da25889 100644
--- a/code/controllers/subsystem/atoms.dm
+++ b/code/controllers/subsystem/atoms.dm
@@ -1,111 +1,158 @@
-#define INITIALIZATION_INSSATOMS 0 //New should not call Initialize
-#define INITIALIZATION_INNEW_MAPLOAD 1 //New should call Initialize(TRUE)
-#define INITIALIZATION_INNEW_REGULAR 2 //New should call Initialize(FALSE)
-
-SUBSYSTEM_DEF(atoms)
- name = "Atoms"
+#define BAD_INIT_QDEL_BEFORE 1
+#define BAD_INIT_DIDNT_INIT 2
+#define BAD_INIT_SLEPT 4
+#define BAD_INIT_NO_HINT 8
+
+SUBSYSTEM_DEF(atoms)
+ name = "Atoms"
init_order = INIT_ORDER_ATOMS
- flags = SS_NO_FIRE
-
- var/initialized = INITIALIZATION_INSSATOMS
- var/old_initialized
-
- var/list/late_loaders
-
-/datum/controller/subsystem/atoms/Initialize(timeofday)
- GLOB.fire_overlay.appearance_flags = RESET_COLOR
- setupGenetics() //to set the mutations' place in structural enzymes, so monkey.initialize() knows where to put the monkey mutation.
- initialized = INITIALIZATION_INNEW_MAPLOAD
- InitializeAtoms()
- return ..()
-
-/datum/controller/subsystem/atoms/proc/InitializeAtoms(list/atoms = null)
- if(initialized == INITIALIZATION_INSSATOMS)
- return
-
- initialized = INITIALIZATION_INNEW_MAPLOAD
-
- var/static/list/NewQdelList = list()
-
- if(atoms)
- for(var/I in atoms)
- var/atom/A = I
- if(!A.initialized) //this check is to make sure we don't call it twice on an object that was created in a previous Initialize call
- if(QDELETED(A))
- if(!(NewQdelList[A.type]))
- WARNING("Found new qdeletion in type [A.type]!")
- NewQdelList[A.type] = TRUE
- continue
- var/start_tick = world.time
- if(A.Initialize(TRUE))
- LAZYADD(late_loaders, A)
- if(start_tick != world.time)
- WARNING("[A]: [A.type] slept during it's Initialize!")
- CHECK_TICK
- testing("Initialized [atoms.len] atoms")
- else
- #ifdef TESTING
- var/count = 0
- #endif
- for(var/atom/A in world)
- if(!A.initialized) //this check is to make sure we don't call it twice on an object that was created in a previous Initialize call
- if(QDELETED(A))
- if(!(NewQdelList[A.type]))
- WARNING("Found new qdeletion in type [A.type]!")
- NewQdelList[A.type] = TRUE
- continue
- var/start_tick = world.time
- if(A.Initialize(TRUE))
- LAZYADD(late_loaders, A)
- #ifdef TESTING
- else
- ++count
- #endif TESTING
- if(start_tick != world.time)
- WARNING("[A]: [A.type] slept during it's Initialize!")
- CHECK_TICK
- testing("Roundstart initialized [count] atoms")
-
- initialized = INITIALIZATION_INNEW_REGULAR
-
- for(var/I in late_loaders)
- var/atom/A = I
- var/start_tick = world.time
- A.Initialize(FALSE)
- if(start_tick != world.time)
- WARNING("[A]: [A.type] slept during it's Initialize!")
- CHECK_TICK
- testing("Late-initialized [LAZYLEN(late_loaders)] atoms")
- LAZYCLEARLIST(late_loaders)
-
-/datum/controller/subsystem/atoms/proc/map_loader_begin()
- old_initialized = initialized
- initialized = INITIALIZATION_INSSATOMS
-
-/datum/controller/subsystem/atoms/proc/map_loader_stop()
- initialized = old_initialized
-
-/datum/controller/subsystem/atoms/Recover()
- initialized = SSatoms.initialized
- if(initialized == INITIALIZATION_INNEW_MAPLOAD)
- InitializeAtoms()
- old_initialized = SSatoms.old_initialized
-
-/datum/controller/subsystem/atoms/proc/setupGenetics()
- var/list/avnums = new /list(DNA_STRUC_ENZYMES_BLOCKS)
- for(var/i=1, i<=DNA_STRUC_ENZYMES_BLOCKS, i++)
- avnums[i] = i
- CHECK_TICK
-
- for(var/A in subtypesof(/datum/mutation/human))
- var/datum/mutation/human/B = new A()
- if(B.dna_block == NON_SCANNABLE)
- continue
- B.dna_block = pick_n_take(avnums)
- if(B.quality == POSITIVE)
- GLOB.good_mutations |= B
- else if(B.quality == NEGATIVE)
- GLOB.bad_mutations |= B
- else if(B.quality == MINOR_NEGATIVE)
- GLOB.not_good_mutations |= B
- CHECK_TICK
+ flags = SS_NO_FIRE
+
+ var/initialized = INITIALIZATION_INSSATOMS
+ var/old_initialized
+
+ var/list/late_loaders
+ var/list/created_atoms
+
+ var/list/BadInitializeCalls = list()
+
+/datum/controller/subsystem/atoms/Initialize(timeofday)
+ GLOB.fire_overlay.appearance_flags = RESET_COLOR
+ setupGenetics() //to set the mutations' place in structural enzymes, so monkey.initialize() knows where to put the monkey mutation.
+ initialized = INITIALIZATION_INNEW_MAPLOAD
+ InitializeAtoms()
+ return ..()
+
+/datum/controller/subsystem/atoms/proc/InitializeAtoms(list/atoms)
+ if(initialized == INITIALIZATION_INSSATOMS)
+ return
+
+ initialized = INITIALIZATION_INNEW_MAPLOAD
+
+ LAZYINITLIST(late_loaders)
+
+ var/count
+ var/list/mapload_arg = list(TRUE)
+ if(atoms)
+ created_atoms = list()
+ count = atoms.len
+ for(var/I in atoms)
+ var/atom/A = I
+ if(!A.initialized)
+ if(InitAtom(I, mapload_arg))
+ atoms -= I
+ CHECK_TICK
+ else
+ count = 0
+ for(var/atom/A in world)
+ if(!A.initialized)
+ InitAtom(A, mapload_arg)
+ ++count
+ CHECK_TICK
+
+ log_world("Initialized [count] atoms")
+
+ initialized = INITIALIZATION_INNEW_REGULAR
+
+ if(late_loaders.len)
+ for(var/I in late_loaders)
+ var/atom/A = I
+ A.LateInitialize()
+ testing("Late initialized [late_loaders.len] atoms")
+ late_loaders.Cut()
+
+ if(atoms)
+ . = created_atoms + atoms
+ created_atoms = null
+
+/datum/controller/subsystem/atoms/proc/InitAtom(atom/A, list/arguments)
+ var/the_type = A.type
+ if(QDELING(A))
+ BadInitializeCalls[the_type] |= BAD_INIT_QDEL_BEFORE
+ return TRUE
+
+ var/start_tick = world.time
+
+ var/result = A.Initialize(arglist(arguments))
+
+ if(start_tick != world.time)
+ BadInitializeCalls[the_type] |= BAD_INIT_SLEPT
+
+ var/qdeleted = FALSE
+
+ if(result != INITIALIZE_HINT_NORMAL)
+ switch(result)
+ if(INITIALIZE_HINT_LATELOAD)
+ if(arguments[1]) //mapload
+ late_loaders += A
+ else
+ A.LateInitialize()
+ if(INITIALIZE_HINT_QDEL)
+ qdel(A)
+ qdeleted = TRUE
+ else
+ BadInitializeCalls[the_type] |= BAD_INIT_NO_HINT
+
+ if(!A) //possible harddel
+ qdeleted = TRUE
+ else if(!A.initialized)
+ BadInitializeCalls[the_type] |= BAD_INIT_DIDNT_INIT
+
+ return qdeleted || QDELETED(A)
+
+/datum/controller/subsystem/atoms/proc/map_loader_begin()
+ old_initialized = initialized
+ initialized = INITIALIZATION_INSSATOMS
+
+/datum/controller/subsystem/atoms/proc/map_loader_stop()
+ initialized = old_initialized
+
+/datum/controller/subsystem/atoms/Recover()
+ initialized = SSatoms.initialized
+ if(initialized == INITIALIZATION_INNEW_MAPLOAD)
+ InitializeAtoms()
+ old_initialized = SSatoms.old_initialized
+ BadInitializeCalls = SSatoms.BadInitializeCalls
+
+/datum/controller/subsystem/atoms/proc/setupGenetics()
+ var/list/avnums = new /list(DNA_STRUC_ENZYMES_BLOCKS)
+ for(var/i=1, i<=DNA_STRUC_ENZYMES_BLOCKS, i++)
+ avnums[i] = i
+ CHECK_TICK
+
+ for(var/A in subtypesof(/datum/mutation/human))
+ var/datum/mutation/human/B = new A()
+ if(B.dna_block == NON_SCANNABLE)
+ continue
+ B.dna_block = pick_n_take(avnums)
+ if(B.quality == POSITIVE)
+ GLOB.good_mutations |= B
+ else if(B.quality == NEGATIVE)
+ GLOB.bad_mutations |= B
+ else if(B.quality == MINOR_NEGATIVE)
+ GLOB.not_good_mutations |= B
+ CHECK_TICK
+
+/datum/controller/subsystem/atoms/proc/InitLog()
+ . = ""
+ for(var/path in BadInitializeCalls)
+ . += "Path : [path] \n"
+ var/fails = BadInitializeCalls[path]
+ if(fails & BAD_INIT_DIDNT_INIT)
+ . += "- Didn't call atom/Initialize()\n"
+ if(fails & BAD_INIT_NO_HINT)
+ . += "- Didn't return an Initialize hint\n"
+ if(fails & BAD_INIT_QDEL_BEFORE)
+ . += "- Qdel'd in New()\n"
+ if(fails & BAD_INIT_SLEPT)
+ . += "- Slept during Initialize()\n"
+
+/datum/controller/subsystem/atoms/Shutdown()
+ var/initlog = InitLog()
+ if(initlog)
+ log_world(initlog)
+
+#undef BAD_INIT_QDEL_BEFORE
+#undef BAD_INIT_DIDNT_INIT
+#undef BAD_INIT_SLEPT
+#undef BAD_INIT_NO_HINT
diff --git a/code/orphaned_procs/statistics.dm b/code/controllers/subsystem/blackbox.dm
similarity index 59%
rename from code/orphaned_procs/statistics.dm
rename to code/controllers/subsystem/blackbox.dm
index d6cdcda6c1..1b14b352df 100644
--- a/code/orphaned_procs/statistics.dm
+++ b/code/controllers/subsystem/blackbox.dm
@@ -1,9 +1,7 @@
-GLOBAL_DATUM_INIT(blackbox, /datum/feedback, new)
-
-//the feedback datum; stores all feedback
-/datum/feedback
- var/list/messages = list()
- var/list/messages_admin = list()
+SUBSYSTEM_DEF(blackbox)
+ name = "Blackbox"
+ wait = 6000
+ flags = SS_NO_TICK_CHECK
var/list/msg_common = list()
var/list/msg_science = list()
@@ -15,21 +13,47 @@ GLOBAL_DATUM_INIT(blackbox, /datum/feedback, new)
var/list/msg_syndicate = list()
var/list/msg_service = list()
var/list/msg_cargo = list()
+ var/list/msg_other = list()
- var/list/datum/feedback_variable/feedback = new()
+ var/list/feedback = list() //list of datum/feedback_variable
-/datum/feedback/proc/find_feedback_datum(variable)
- for (var/datum/feedback_variable/FV in feedback)
- if (FV.get_variable() == variable)
- return FV
- var/datum/feedback_variable/FV = new(variable)
- feedback += FV
- return FV
+//poll population
+/datum/controller/subsystem/blackbox/fire()
+ if(!SSdbcore.Connect())
+ return
+ var/playercount = 0
+ for(var/mob/M in GLOB.player_list)
+ if(M.client)
+ playercount += 1
+ var/admincount = GLOB.admins.len
+ var/datum/DBQuery/query_record_playercount = SSdbcore.NewQuery("INSERT INTO [format_table_name("legacy_population")] (playercount, admincount, time, server_ip, server_port) VALUES ([playercount], [admincount], '[SQLtime()]', INET_ATON('[world.internet_address]'), '[world.port]')")
+ query_record_playercount.Execute()
-/datum/feedback/proc/get_round_feedback()
- return feedback
+/datum/controller/subsystem/blackbox/Recover()
+ msg_common = SSblackbox.msg_common
+ msg_science = SSblackbox.msg_science
+ msg_command = SSblackbox.msg_command
+ msg_medical = SSblackbox.msg_medical
+ msg_engineering = SSblackbox.msg_engineering
+ msg_security = SSblackbox.msg_security
+ msg_deathsquad = SSblackbox.msg_deathsquad
+ msg_syndicate = SSblackbox.msg_syndicate
+ msg_service = SSblackbox.msg_service
+ msg_cargo = SSblackbox.msg_cargo
+ msg_other = SSblackbox.msg_other
-/datum/feedback/proc/round_end_data_gathering()
+ feedback = SSblackbox.feedback
+
+//no touchie
+/datum/controller/subsystem/blackbox/can_vv_get(var_name)
+ if(var_name == "feedback")
+ return FALSE
+ return ..()
+
+/datum/controller/subsystem/blackbox/vv_edit_var(var_name, var_value)
+ return FALSE
+
+/datum/controller/subsystem/blackbox/Shutdown()
var/pda_msg_amt = 0
var/rc_msg_amt = 0
@@ -39,30 +63,27 @@ GLOBAL_DATUM_INIT(blackbox, /datum/feedback, new)
if (MS.rc_msgs.len > rc_msg_amt)
rc_msg_amt = MS.rc_msgs.len
- feedback_set_details("radio_usage","")
+ set_details("radio_usage","")
- feedback_add_details("radio_usage","COM-[msg_common.len]")
- feedback_add_details("radio_usage","SCI-[msg_science.len]")
- feedback_add_details("radio_usage","HEA-[msg_command.len]")
- feedback_add_details("radio_usage","MED-[msg_medical.len]")
- feedback_add_details("radio_usage","ENG-[msg_engineering.len]")
- feedback_add_details("radio_usage","SEC-[msg_security.len]")
- feedback_add_details("radio_usage","DTH-[msg_deathsquad.len]")
- feedback_add_details("radio_usage","SYN-[msg_syndicate.len]")
- feedback_add_details("radio_usage","SRV-[msg_service.len]")
- feedback_add_details("radio_usage","CAR-[msg_cargo.len]")
- feedback_add_details("radio_usage","OTH-[messages.len]")
- feedback_add_details("radio_usage","PDA-[pda_msg_amt]")
- feedback_add_details("radio_usage","RC-[rc_msg_amt]")
+ add_details("radio_usage","COM-[msg_common.len]")
+ add_details("radio_usage","SCI-[msg_science.len]")
+ add_details("radio_usage","HEA-[msg_command.len]")
+ add_details("radio_usage","MED-[msg_medical.len]")
+ add_details("radio_usage","ENG-[msg_engineering.len]")
+ add_details("radio_usage","SEC-[msg_security.len]")
+ add_details("radio_usage","DTH-[msg_deathsquad.len]")
+ add_details("radio_usage","SYN-[msg_syndicate.len]")
+ add_details("radio_usage","SRV-[msg_service.len]")
+ add_details("radio_usage","CAR-[msg_cargo.len]")
+ add_details("radio_usage","OTH-[msg_other.len]")
+ add_details("radio_usage","PDA-[pda_msg_amt]")
+ add_details("radio_usage","RC-[rc_msg_amt]")
- feedback_set_details("round_end","[time2text(world.realtime)]") //This one MUST be the last one that gets set.
+ set_details("round_end","[time2text(world.realtime)]") //This one MUST be the last one that gets set.
-//This proc is only to be called at round end.
-/datum/feedback/proc/save_all_data_to_sql()
- if (!feedback) return
+ if (!SSdbcore.Connect())
+ return
- round_end_data_gathering() //round_end time logging and some other data processing
- if (!SSdbcore.Connect()) return
var/round_id
var/datum/DBQuery/query_feedback_max_id = SSdbcore.NewQuery("SELECT MAX(round_id) AS round_id FROM [format_table_name("feedback")]")
@@ -89,69 +110,99 @@ GLOBAL_DATUM_INIT(blackbox, /datum/feedback, new)
var/datum/DBQuery/query_feedback_save = SSdbcore.NewQuery("INSERT DELAYED IGNORE INTO [format_table_name("feedback")] VALUES " + sqlrowlist)
query_feedback_save.Execute()
+/datum/controller/subsystem/blackbox/proc/LogBroadcast(blackbox_msg, freq)
+ switch(freq)
+ if(1459)
+ msg_common += blackbox_msg
+ if(1351)
+ msg_science += blackbox_msg
+ if(1353)
+ msg_command += blackbox_msg
+ if(1355)
+ msg_medical += blackbox_msg
+ if(1357)
+ msg_engineering += blackbox_msg
+ if(1359)
+ msg_security += blackbox_msg
+ if(1441)
+ msg_deathsquad += blackbox_msg
+ if(1213)
+ msg_syndicate += blackbox_msg
+ if(1349)
+ msg_service += blackbox_msg
+ if(1347)
+ msg_cargo += blackbox_msg
+ else
+ msg_other += blackbox_msg
-/proc/feedback_set(variable,value)
- if(!GLOB.blackbox)
- return
+/datum/controller/subsystem/blackbox/proc/find_feedback_datum(variable)
+ for(var/datum/feedback_variable/FV in feedback)
+ if(FV.get_variable() == variable)
+ return FV
- var/datum/feedback_variable/FV = GLOB.blackbox.find_feedback_datum(variable)
-
- if(!FV)
- return
+ var/datum/feedback_variable/FV = new(variable)
+ feedback += FV
+ return FV
+/datum/controller/subsystem/blackbox/proc/set_val(variable, value)
+ var/datum/feedback_variable/FV = find_feedback_datum(variable)
FV.set_value(value)
-/proc/feedback_inc(variable,value)
- if(!GLOB.blackbox)
- return
-
- var/datum/feedback_variable/FV = GLOB.blackbox.find_feedback_datum(variable)
-
- if(!FV)
- return
-
+/datum/controller/subsystem/blackbox/proc/inc(variable, value)
+ var/datum/feedback_variable/FV = find_feedback_datum(variable)
FV.inc(value)
-/proc/feedback_dec(variable,value)
- if(!GLOB.blackbox)
- return
-
- var/datum/feedback_variable/FV = GLOB.blackbox.find_feedback_datum(variable)
-
- if(!FV)
- return
-
+/datum/controller/subsystem/blackbox/proc/dec(variable,value)
+ var/datum/feedback_variable/FV = find_feedback_datum(variable)
FV.dec(value)
-/proc/feedback_set_details(variable,details)
- if(!GLOB.blackbox)
- return
-
- var/datum/feedback_variable/FV = GLOB.blackbox.find_feedback_datum(variable)
-
- if(!FV)
- return
-
+/datum/controller/subsystem/blackbox/proc/set_details(variable,details)
+ var/datum/feedback_variable/FV = find_feedback_datum(variable)
FV.set_details(details)
-/proc/feedback_add_details(variable,details)
- if(!GLOB.blackbox)
- return
-
- var/datum/feedback_variable/FV = GLOB.blackbox.find_feedback_datum(variable)
-
- if(!FV)
- return
-
+/datum/controller/subsystem/blackbox/proc/add_details(variable,details)
+ var/datum/feedback_variable/FV = find_feedback_datum(variable)
FV.add_details(details)
+/datum/controller/subsystem/blackbox/proc/ReportDeath(mob/living/L)
+ if(!SSdbcore.Connect())
+ return
+ if(!L || !L.key || !L.mind)
+ return
+ var/turf/T = get_turf(L)
+ var/area/placeofdeath = get_area(T.loc)
+ var/sqlname = sanitizeSQL(L.real_name)
+ var/sqlkey = sanitizeSQL(L.ckey)
+ var/sqljob = sanitizeSQL(L.mind.assigned_role)
+ var/sqlspecial = sanitizeSQL(L.mind.special_role)
+ var/sqlpod = sanitizeSQL(placeofdeath.name)
+ var/laname
+ var/lakey
+ if(L.lastattacker && ismob(L.lastattacker))
+ var/mob/LA = L.lastattacker
+ laname = sanitizeSQL(LA.real_name)
+ lakey = sanitizeSQL(LA.key)
+ var/sqlgender = sanitizeSQL(L.gender)
+ var/sqlbrute = sanitizeSQL(L.getBruteLoss())
+ var/sqlfire = sanitizeSQL(L.getFireLoss())
+ var/sqlbrain = sanitizeSQL(L.getBrainLoss())
+ var/sqloxy = sanitizeSQL(L.getOxyLoss())
+ var/sqltox = sanitizeSQL(L.getStaminaLoss())
+ var/sqlclone = sanitizeSQL(L.getStaminaLoss())
+ var/sqlstamina = sanitizeSQL(L.getStaminaLoss())
+ var/coord = sanitizeSQL("[L.x], [L.y], [L.z]")
+ var/map = sanitizeSQL(SSmapping.config.map_name)
+ var/datum/DBQuery/query_report_death = SSdbcore.NewQuery("INSERT INTO [format_table_name("death")] (name, byondkey, job, special, pod, tod, laname, lakey, gender, bruteloss, fireloss, brainloss, oxyloss, toxloss, cloneloss, staminaloss, coord, mapname, server_ip, server_port) VALUES ('[sqlname]', '[sqlkey]', '[sqljob]', '[sqlspecial]', '[sqlpod]', '[SQLtime()]', '[laname]', '[lakey]', '[sqlgender]', [sqlbrute], [sqlfire], [sqlbrain], [sqloxy], [sqltox], [sqlclone], [sqlstamina], '[coord]', '[map]', INET_ATON('[world.internet_address]'), '[world.port]')")
+ query_report_death.Execute()
+
+
//feedback variable datum, for storing all kinds of data
/datum/feedback_variable
var/variable
var/value
var/details
-/datum/feedback_variable/New(var/param_variable,var/param_value = 0)
+/datum/feedback_variable/New(param_variable, param_value = 0)
variable = param_variable
value = param_value
@@ -204,50 +255,3 @@ GLOBAL_DATUM_INIT(blackbox, /datum/feedback, new)
/datum/feedback_variable/proc/get_parsed()
return list(variable,value,details)
-
-//sql reporting procs
-/proc/sql_poll_population()
- if(!config.sql_enabled)
- return
- if(!SSdbcore.Connect())
- return
- var/playercount = 0
- for(var/mob/M in GLOB.player_list)
- if(M.client)
- playercount += 1
- var/admincount = GLOB.admins.len
- var/datum/DBQuery/query_record_playercount = SSdbcore.NewQuery("INSERT INTO [format_table_name("legacy_population")] (playercount, admincount, time, server_ip, server_port) VALUES ([playercount], [admincount], '[SQLtime()]', INET_ATON('[world.internet_address]'), '[world.port]')")
- query_record_playercount.Execute()
-
-/proc/sql_report_death(mob/living/L)
- if(!config.sql_enabled)
- return
- if(!SSdbcore.Connect())
- return
- if(!L || !L.key || !L.mind)
- return
- var/turf/T = get_turf(L)
- var/area/placeofdeath = get_area(T.loc)
- var/sqlname = sanitizeSQL(L.real_name)
- var/sqlkey = sanitizeSQL(L.ckey)
- var/sqljob = sanitizeSQL(L.mind.assigned_role)
- var/sqlspecial = sanitizeSQL(L.mind.special_role)
- var/sqlpod = sanitizeSQL(placeofdeath.name)
- var/laname
- var/lakey
- if(L.lastattacker && ismob(L.lastattacker))
- var/mob/LA = L.lastattacker
- laname = sanitizeSQL(LA.real_name)
- lakey = sanitizeSQL(LA.key)
- var/sqlgender = sanitizeSQL(L.gender)
- var/sqlbrute = sanitizeSQL(L.getBruteLoss())
- var/sqlfire = sanitizeSQL(L.getFireLoss())
- var/sqlbrain = sanitizeSQL(L.getBrainLoss())
- var/sqloxy = sanitizeSQL(L.getOxyLoss())
- var/sqltox = sanitizeSQL(L.getStaminaLoss())
- var/sqlclone = sanitizeSQL(L.getStaminaLoss())
- var/sqlstamina = sanitizeSQL(L.getStaminaLoss())
- var/coord = sanitizeSQL("[L.x], [L.y], [L.z]")
- var/map = sanitizeSQL(SSmapping.config.map_name)
- var/datum/DBQuery/query_report_death = SSdbcore.NewQuery("INSERT INTO [format_table_name("death")] (name, byondkey, job, special, pod, tod, laname, lakey, gender, bruteloss, fireloss, brainloss, oxyloss, toxloss, cloneloss, staminaloss, coord, mapname, server_ip, server_port) VALUES ('[sqlname]', '[sqlkey]', '[sqljob]', '[sqlspecial]', '[sqlpod]', '[SQLtime()]', '[laname]', '[lakey]', '[sqlgender]', [sqlbrute], [sqlfire], [sqlbrain], [sqloxy], [sqltox], [sqlclone], [sqlstamina], '[coord]', '[map]', INET_ATON('[world.internet_address]'), '[world.port]')")
- query_report_death.Execute()
diff --git a/code/controllers/subsystem/blackbox.dm.rej b/code/controllers/subsystem/blackbox.dm.rej
new file mode 100644
index 0000000000..79c407851f
--- /dev/null
+++ b/code/controllers/subsystem/blackbox.dm.rej
@@ -0,0 +1,512 @@
+diff a/code/controllers/subsystem/blackbox.dm b/code/controllers/subsystem/blackbox.dm (rejected hunks)
+@@ -1,253 +1,257 @@
+-GLOBAL_DATUM_INIT(blackbox, /datum/feedback, new)
+-
+-//the feedback datum; stores all feedback
+-/datum/feedback
+- var/list/messages = list()
+- var/list/messages_admin = list()
+-
+- var/list/msg_common = list()
+- var/list/msg_science = list()
+- var/list/msg_command = list()
+- var/list/msg_medical = list()
+- var/list/msg_engineering = list()
+- var/list/msg_security = list()
+- var/list/msg_deathsquad = list()
+- var/list/msg_syndicate = list()
+- var/list/msg_service = list()
+- var/list/msg_cargo = list()
+-
+- var/list/datum/feedback_variable/feedback = new()
+-
+-/datum/feedback/proc/find_feedback_datum(variable)
+- for (var/datum/feedback_variable/FV in feedback)
+- if (FV.get_variable() == variable)
+- return FV
+- var/datum/feedback_variable/FV = new(variable)
+- feedback += FV
+- return FV
+-
+-/datum/feedback/proc/get_round_feedback()
+- return feedback
+-
+-/datum/feedback/proc/round_end_data_gathering()
+- var/pda_msg_amt = 0
+- var/rc_msg_amt = 0
+-
+- for (var/obj/machinery/message_server/MS in GLOB.message_servers)
+- if (MS.pda_msgs.len > pda_msg_amt)
+- pda_msg_amt = MS.pda_msgs.len
+- if (MS.rc_msgs.len > rc_msg_amt)
+- rc_msg_amt = MS.rc_msgs.len
+-
+- feedback_set_details("radio_usage","")
+-
+- feedback_add_details("radio_usage","COM-[msg_common.len]")
+- feedback_add_details("radio_usage","SCI-[msg_science.len]")
+- feedback_add_details("radio_usage","HEA-[msg_command.len]")
+- feedback_add_details("radio_usage","MED-[msg_medical.len]")
+- feedback_add_details("radio_usage","ENG-[msg_engineering.len]")
+- feedback_add_details("radio_usage","SEC-[msg_security.len]")
+- feedback_add_details("radio_usage","DTH-[msg_deathsquad.len]")
+- feedback_add_details("radio_usage","SYN-[msg_syndicate.len]")
+- feedback_add_details("radio_usage","SRV-[msg_service.len]")
+- feedback_add_details("radio_usage","CAR-[msg_cargo.len]")
+- feedback_add_details("radio_usage","OTH-[messages.len]")
+- feedback_add_details("radio_usage","PDA-[pda_msg_amt]")
+- feedback_add_details("radio_usage","RC-[rc_msg_amt]")
+-
+- feedback_set_details("round_end","[time2text(world.realtime)]") //This one MUST be the last one that gets set.
+-
+-//This proc is only to be called at round end.
+-/datum/feedback/proc/save_all_data_to_sql()
+- if (!feedback) return
+-
+- round_end_data_gathering() //round_end time logging and some other data processing
+- if (!GLOB.dbcon.Connect()) return
+- var/round_id
+-
+- var/DBQuery/query_feedback_max_id = GLOB.dbcon.NewQuery("SELECT MAX(round_id) AS round_id FROM [format_table_name("feedback")]")
+- if(!query_feedback_max_id.Execute())
+- return
+- while (query_feedback_max_id.NextRow())
+- round_id = query_feedback_max_id.item[1]
+-
+- if (!isnum(round_id))
+- round_id = text2num(round_id)
+- round_id++
+-
+- var/sqlrowlist = ""
+-
+- for (var/datum/feedback_variable/FV in feedback)
+- if (sqlrowlist != "")
+- sqlrowlist += ", " //a comma (,) at the start of the first row to insert will trigger a SQL error
+-
+- sqlrowlist += "(null, Now(), [round_id], \"[sanitizeSQL(FV.get_variable())]\", [FV.get_value()], \"[sanitizeSQL(FV.get_details())]\")"
+-
+- if (sqlrowlist == "")
+- return
+-
+- var/DBQuery/query_feedback_save = GLOB.dbcon.NewQuery("INSERT DELAYED IGNORE INTO [format_table_name("feedback")] VALUES " + sqlrowlist)
+- query_feedback_save.Execute()
+-
+-
+-/proc/feedback_set(variable,value)
+- if(!GLOB.blackbox)
+- return
+-
+- var/datum/feedback_variable/FV = GLOB.blackbox.find_feedback_datum(variable)
+-
+- if(!FV)
+- return
+-
+- FV.set_value(value)
+-
+-/proc/feedback_inc(variable,value)
+- if(!GLOB.blackbox)
+- return
+-
+- var/datum/feedback_variable/FV = GLOB.blackbox.find_feedback_datum(variable)
+-
+- if(!FV)
+- return
+-
+- FV.inc(value)
+-
+-/proc/feedback_dec(variable,value)
+- if(!GLOB.blackbox)
+- return
+-
+- var/datum/feedback_variable/FV = GLOB.blackbox.find_feedback_datum(variable)
+-
+- if(!FV)
+- return
+-
+- FV.dec(value)
+-
+-/proc/feedback_set_details(variable,details)
+- if(!GLOB.blackbox)
+- return
+-
+- var/datum/feedback_variable/FV = GLOB.blackbox.find_feedback_datum(variable)
+-
+- if(!FV)
+- return
+-
+- FV.set_details(details)
+-
+-/proc/feedback_add_details(variable,details)
+- if(!GLOB.blackbox)
+- return
+-
+- var/datum/feedback_variable/FV = GLOB.blackbox.find_feedback_datum(variable)
+-
+- if(!FV)
+- return
+-
+- FV.add_details(details)
+-
+-//feedback variable datum, for storing all kinds of data
+-/datum/feedback_variable
+- var/variable
+- var/value
+- var/details
+-
+-/datum/feedback_variable/New(var/param_variable,var/param_value = 0)
+- variable = param_variable
+- value = param_value
+-
+-/datum/feedback_variable/proc/inc(num = 1)
+- if (isnum(value))
+- value += num
+- else
+- value = text2num(value)
+- if (isnum(value))
+- value += num
+- else
+- value = num
+-
+-/datum/feedback_variable/proc/dec(num = 1)
+- if (isnum(value))
+- value -= num
+- else
+- value = text2num(value)
+- if (isnum(value))
+- value -= num
+- else
+- value = -num
+-
+-/datum/feedback_variable/proc/set_value(num)
+- if (isnum(num))
+- value = num
+-
+-/datum/feedback_variable/proc/get_value()
+- if (!isnum(value))
+- return 0
+- return value
+-
+-/datum/feedback_variable/proc/get_variable()
+- return variable
+-
+-/datum/feedback_variable/proc/set_details(text)
+- if (istext(text))
+- details = text
+-
+-/datum/feedback_variable/proc/add_details(text)
+- if (istext(text))
+- text = replacetext(text, " ", "_")
+- if (!details)
+- details = text
+- else
+- details += " [text]"
+-
+-/datum/feedback_variable/proc/get_details()
+- return details
+-
+-/datum/feedback_variable/proc/get_parsed()
+- return list(variable,value,details)
+-
+-//sql reporting procs
+-/proc/sql_poll_population()
+- if(!config.sql_enabled)
+- return
+- if(!GLOB.dbcon.Connect())
+- return
+- var/playercount = 0
+- for(var/mob/M in GLOB.player_list)
+- if(M.client)
+- playercount += 1
+- var/admincount = GLOB.admins.len
+- var/DBQuery/query_record_playercount = GLOB.dbcon.NewQuery("INSERT INTO [format_table_name("legacy_population")] (playercount, admincount, time, server_ip, server_port) VALUES ([playercount], [admincount], '[SQLtime()]', INET_ATON('[world.internet_address]'), '[world.port]')")
+- query_record_playercount.Execute()
+-
+-/proc/sql_report_death(mob/living/L)
+- if(!config.sql_enabled)
+- return
+- if(!GLOB.dbcon.Connect())
+- return
+- if(!L || !L.key || !L.mind)
+- return
+- var/turf/T = get_turf(L)
+- var/area/placeofdeath = get_area(T.loc)
+- var/sqlname = sanitizeSQL(L.real_name)
+- var/sqlkey = sanitizeSQL(L.ckey)
+- var/sqljob = sanitizeSQL(L.mind.assigned_role)
+- var/sqlspecial = sanitizeSQL(L.mind.special_role)
+- var/sqlpod = sanitizeSQL(placeofdeath.name)
+- var/laname
+- var/lakey
+- if(L.lastattacker && ismob(L.lastattacker))
+- var/mob/LA = L.lastattacker
+- laname = sanitizeSQL(LA.real_name)
+- lakey = sanitizeSQL(LA.key)
+- var/sqlgender = sanitizeSQL(L.gender)
+- var/sqlbrute = sanitizeSQL(L.getBruteLoss())
+- var/sqlfire = sanitizeSQL(L.getFireLoss())
+- var/sqlbrain = sanitizeSQL(L.getBrainLoss())
+- var/sqloxy = sanitizeSQL(L.getOxyLoss())
+- var/sqltox = sanitizeSQL(L.getStaminaLoss())
+- var/sqlclone = sanitizeSQL(L.getStaminaLoss())
+- var/sqlstamina = sanitizeSQL(L.getStaminaLoss())
+- var/coord = sanitizeSQL("[L.x], [L.y], [L.z]")
+- var/map = sanitizeSQL(SSmapping.config.map_name)
+- var/DBQuery/query_report_death = GLOB.dbcon.NewQuery("INSERT INTO [format_table_name("death")] (name, byondkey, job, special, pod, tod, laname, lakey, gender, bruteloss, fireloss, brainloss, oxyloss, toxloss, cloneloss, staminaloss, coord, mapname, server_ip, server_port) VALUES ('[sqlname]', '[sqlkey]', '[sqljob]', '[sqlspecial]', '[sqlpod]', '[SQLtime()]', '[laname]', '[lakey]', '[sqlgender]', [sqlbrute], [sqlfire], [sqlbrain], [sqloxy], [sqltox], [sqlclone], [sqlstamina], '[coord]', '[map]', INET_ATON('[world.internet_address]'), '[world.port]')")
+- query_report_death.Execute()
++SUBSYSTEM_DEF(blackbox)
++ name = "Blackbox"
++ wait = 6000
++ flags = SS_NO_TICK_CHECK
++
++ var/list/msg_common = list()
++ var/list/msg_science = list()
++ var/list/msg_command = list()
++ var/list/msg_medical = list()
++ var/list/msg_engineering = list()
++ var/list/msg_security = list()
++ var/list/msg_deathsquad = list()
++ var/list/msg_syndicate = list()
++ var/list/msg_service = list()
++ var/list/msg_cargo = list()
++ var/list/msg_other = list()
++
++ var/list/feedback = list() //list of datum/feedback_variable
++
++//poll population
++/datum/controller/subsystem/blackbox/fire()
++ if(!GLOB.dbcon.Connect())
++ return
++ var/playercount = 0
++ for(var/mob/M in GLOB.player_list)
++ if(M.client)
++ playercount += 1
++ var/admincount = GLOB.admins.len
++ var/DBQuery/query_record_playercount = GLOB.dbcon.NewQuery("INSERT INTO [format_table_name("legacy_population")] (playercount, admincount, time, server_ip, server_port) VALUES ([playercount], [admincount], '[SQLtime()]', INET_ATON('[world.internet_address]'), '[world.port]')")
++ query_record_playercount.Execute()
++
++/datum/controller/subsystem/blackbox/Recover()
++ msg_common = SSblackbox.msg_common
++ msg_science = SSblackbox.msg_science
++ msg_command = SSblackbox.msg_command
++ msg_medical = SSblackbox.msg_medical
++ msg_engineering = SSblackbox.msg_engineering
++ msg_security = SSblackbox.msg_security
++ msg_deathsquad = SSblackbox.msg_deathsquad
++ msg_syndicate = SSblackbox.msg_syndicate
++ msg_service = SSblackbox.msg_service
++ msg_cargo = SSblackbox.msg_cargo
++ msg_other = SSblackbox.msg_other
++
++ feedback = SSblackbox.feedback
++
++//no touchie
++/datum/controller/subsystem/blackbox/can_vv_get(var_name)
++ if(var_name == "feedback")
++ return FALSE
++ return ..()
++
++/datum/controller/subsystem/blackbox/vv_edit_var(var_name, var_value)
++ return FALSE
++
++/datum/controller/subsystem/blackbox/Shutdown()
++ var/pda_msg_amt = 0
++ var/rc_msg_amt = 0
++
++ for (var/obj/machinery/message_server/MS in GLOB.message_servers)
++ if (MS.pda_msgs.len > pda_msg_amt)
++ pda_msg_amt = MS.pda_msgs.len
++ if (MS.rc_msgs.len > rc_msg_amt)
++ rc_msg_amt = MS.rc_msgs.len
++
++ set_details("radio_usage","")
++
++ add_details("radio_usage","COM-[msg_common.len]")
++ add_details("radio_usage","SCI-[msg_science.len]")
++ add_details("radio_usage","HEA-[msg_command.len]")
++ add_details("radio_usage","MED-[msg_medical.len]")
++ add_details("radio_usage","ENG-[msg_engineering.len]")
++ add_details("radio_usage","SEC-[msg_security.len]")
++ add_details("radio_usage","DTH-[msg_deathsquad.len]")
++ add_details("radio_usage","SYN-[msg_syndicate.len]")
++ add_details("radio_usage","SRV-[msg_service.len]")
++ add_details("radio_usage","CAR-[msg_cargo.len]")
++ add_details("radio_usage","OTH-[msg_other.len]")
++ add_details("radio_usage","PDA-[pda_msg_amt]")
++ add_details("radio_usage","RC-[rc_msg_amt]")
++
++ set_details("round_end","[time2text(world.realtime)]") //This one MUST be the last one that gets set.
++
++ if (!GLOB.dbcon.Connect())
++ return
++
++ var/round_id
++
++ var/DBQuery/query_feedback_max_id = GLOB.dbcon.NewQuery("SELECT MAX(round_id) AS round_id FROM [format_table_name("feedback")]")
++ if(!query_feedback_max_id.Execute())
++ return
++ while (query_feedback_max_id.NextRow())
++ round_id = query_feedback_max_id.item[1]
++
++ if (!isnum(round_id))
++ round_id = text2num(round_id)
++ round_id++
++
++ var/sqlrowlist = ""
++
++ for (var/datum/feedback_variable/FV in feedback)
++ if (sqlrowlist != "")
++ sqlrowlist += ", " //a comma (,) at the start of the first row to insert will trigger a SQL error
++
++ sqlrowlist += "(null, Now(), [round_id], \"[sanitizeSQL(FV.get_variable())]\", [FV.get_value()], \"[sanitizeSQL(FV.get_details())]\")"
++
++ if (sqlrowlist == "")
++ return
++
++ var/DBQuery/query_feedback_save = GLOB.dbcon.NewQuery("INSERT DELAYED IGNORE INTO [format_table_name("feedback")] VALUES " + sqlrowlist)
++ query_feedback_save.Execute()
++
++/datum/controller/subsystem/blackbox/proc/LogBroadcast(blackbox_msg, freq)
++ switch(freq)
++ if(1459)
++ msg_common += blackbox_msg
++ if(1351)
++ msg_science += blackbox_msg
++ if(1353)
++ msg_command += blackbox_msg
++ if(1355)
++ msg_medical += blackbox_msg
++ if(1357)
++ msg_engineering += blackbox_msg
++ if(1359)
++ msg_security += blackbox_msg
++ if(1441)
++ msg_deathsquad += blackbox_msg
++ if(1213)
++ msg_syndicate += blackbox_msg
++ if(1349)
++ msg_service += blackbox_msg
++ if(1347)
++ msg_cargo += blackbox_msg
++ else
++ msg_other += blackbox_msg
++
++/datum/controller/subsystem/blackbox/proc/find_feedback_datum(variable)
++ for(var/datum/feedback_variable/FV in feedback)
++ if(FV.get_variable() == variable)
++ return FV
++
++ var/datum/feedback_variable/FV = new(variable)
++ feedback += FV
++ return FV
++
++/datum/controller/subsystem/blackbox/proc/set_val(variable, value)
++ var/datum/feedback_variable/FV = find_feedback_datum(variable)
++ FV.set_value(value)
++
++/datum/controller/subsystem/blackbox/proc/inc(variable, value)
++ var/datum/feedback_variable/FV = find_feedback_datum(variable)
++ FV.inc(value)
++
++/datum/controller/subsystem/blackbox/proc/dec(variable,value)
++ var/datum/feedback_variable/FV = find_feedback_datum(variable)
++ FV.dec(value)
++
++/datum/controller/subsystem/blackbox/proc/set_details(variable,details)
++ var/datum/feedback_variable/FV = find_feedback_datum(variable)
++ FV.set_details(details)
++
++/datum/controller/subsystem/blackbox/proc/add_details(variable,details)
++ var/datum/feedback_variable/FV = find_feedback_datum(variable)
++ FV.add_details(details)
++
++/datum/controller/subsystem/blackbox/proc/ReportDeath(mob/living/L)
++ if(!GLOB.dbcon.Connect())
++ return
++ if(!L || !L.key || !L.mind)
++ return
++ var/turf/T = get_turf(L)
++ var/area/placeofdeath = get_area(T.loc)
++ var/sqlname = sanitizeSQL(L.real_name)
++ var/sqlkey = sanitizeSQL(L.ckey)
++ var/sqljob = sanitizeSQL(L.mind.assigned_role)
++ var/sqlspecial = sanitizeSQL(L.mind.special_role)
++ var/sqlpod = sanitizeSQL(placeofdeath.name)
++ var/laname
++ var/lakey
++ if(L.lastattacker && ismob(L.lastattacker))
++ var/mob/LA = L.lastattacker
++ laname = sanitizeSQL(LA.real_name)
++ lakey = sanitizeSQL(LA.key)
++ var/sqlgender = sanitizeSQL(L.gender)
++ var/sqlbrute = sanitizeSQL(L.getBruteLoss())
++ var/sqlfire = sanitizeSQL(L.getFireLoss())
++ var/sqlbrain = sanitizeSQL(L.getBrainLoss())
++ var/sqloxy = sanitizeSQL(L.getOxyLoss())
++ var/sqltox = sanitizeSQL(L.getStaminaLoss())
++ var/sqlclone = sanitizeSQL(L.getStaminaLoss())
++ var/sqlstamina = sanitizeSQL(L.getStaminaLoss())
++ var/coord = sanitizeSQL("[L.x], [L.y], [L.z]")
++ var/map = sanitizeSQL(SSmapping.config.map_name)
++ var/DBQuery/query_report_death = GLOB.dbcon.NewQuery("INSERT INTO [format_table_name("death")] (name, byondkey, job, special, pod, tod, laname, lakey, gender, bruteloss, fireloss, brainloss, oxyloss, toxloss, cloneloss, staminaloss, coord, mapname, server_ip, server_port) VALUES ('[sqlname]', '[sqlkey]', '[sqljob]', '[sqlspecial]', '[sqlpod]', '[SQLtime()]', '[laname]', '[lakey]', '[sqlgender]', [sqlbrute], [sqlfire], [sqlbrain], [sqloxy], [sqltox], [sqlclone], [sqlstamina], '[coord]', '[map]', INET_ATON('[world.internet_address]'), '[world.port]')")
++ query_report_death.Execute()
++
++
++//feedback variable datum, for storing all kinds of data
++/datum/feedback_variable
++ var/variable
++ var/value
++ var/details
++
++/datum/feedback_variable/New(param_variable, param_value = 0)
++ variable = param_variable
++ value = param_value
++
++/datum/feedback_variable/proc/inc(num = 1)
++ if (isnum(value))
++ value += num
++ else
++ value = text2num(value)
++ if (isnum(value))
++ value += num
++ else
++ value = num
++
++/datum/feedback_variable/proc/dec(num = 1)
++ if (isnum(value))
++ value -= num
++ else
++ value = text2num(value)
++ if (isnum(value))
++ value -= num
++ else
++ value = -num
++
++/datum/feedback_variable/proc/set_value(num)
++ if (isnum(num))
++ value = num
++
++/datum/feedback_variable/proc/get_value()
++ if (!isnum(value))
++ return 0
++ return value
++
++/datum/feedback_variable/proc/get_variable()
++ return variable
++
++/datum/feedback_variable/proc/set_details(text)
++ if (istext(text))
++ details = text
++
++/datum/feedback_variable/proc/add_details(text)
++ if (istext(text))
++ text = replacetext(text, " ", "_")
++ if (!details)
++ details = text
++ else
++ details += " [text]"
++
++/datum/feedback_variable/proc/get_details()
++ return details
++
++/datum/feedback_variable/proc/get_parsed()
++ return list(variable,value,details)
diff --git a/code/controllers/subsystem/garbage.dm b/code/controllers/subsystem/garbage.dm
index 083127c9c3..7d3682cf5f 100644
--- a/code/controllers/subsystem/garbage.dm
+++ b/code/controllers/subsystem/garbage.dm
@@ -66,6 +66,9 @@ SUBSYSTEM_DEF(garbage)
HandleToBeQueued()
if(state == SS_RUNNING)
HandleQueue()
+
+ if (state == SS_PAUSED) //make us wait again before the next run.
+ state = SS_RUNNING
//If you see this proc high on the profile, what you are really seeing is the garbage collection/soft delete overhead in byond.
//Don't attempt to optimize, not worth the effort.
@@ -110,24 +113,9 @@ SUBSYSTEM_DEF(garbage)
var/type = A.type
testing("GC: -- \ref[A] | [type] was unable to be GC'd and was deleted --")
didntgc["[type]"]++
- var/time = world.timeofday
- var/tick = world.tick_usage
- var/ticktime = world.time
+
HardDelete(A)
- tick = (world.tick_usage-tick+((world.time-ticktime)/world.tick_lag*100))
- if (tick > highest_del_tickusage)
- highest_del_tickusage = tick
- time = world.timeofday - time
- if (!time && TICK_DELTA_TO_MS(tick) > 1)
- time = TICK_DELTA_TO_MS(tick)/100
- if (time > highest_del_time)
- highest_del_time = time
- if (time > 10)
- log_game("Error: [type]([refID]) took longer then 1 second to delete (took [time/10] seconds to delete)")
- message_admins("Error: [type]([refID]) took longer then 1 second to delete (took [time/10] seconds to delete).")
- postpone(time/5)
- break
++delslasttick
++totaldels
else
@@ -157,8 +145,28 @@ SUBSYSTEM_DEF(garbage)
//this is purely to seperate things profile wise.
/datum/controller/subsystem/garbage/proc/HardDelete(datum/A)
+ var/time = world.timeofday
+ var/tick = world.tick_usage
+ var/ticktime = world.time
+
+ var/type = A.type
+ var/refID = "\ref[A]"
+
del(A)
-
+
+ tick = (world.tick_usage-tick+((world.time-ticktime)/world.tick_lag*100))
+ if (tick > highest_del_tickusage)
+ highest_del_tickusage = tick
+ time = world.timeofday - time
+ if (!time && TICK_DELTA_TO_MS(tick) > 1)
+ time = TICK_DELTA_TO_MS(tick)/100
+ if (time > highest_del_time)
+ highest_del_time = time
+ if (time > 10)
+ log_game("Error: [type]([refID]) took longer then 1 second to delete (took [time/10] seconds to delete)")
+ message_admins("Error: [type]([refID]) took longer then 1 second to delete (took [time/10] seconds to delete).")
+ postpone(time/5)
+
/datum/controller/subsystem/garbage/proc/HardQueue(datum/A)
if (istype(A) && A.gc_destroyed == GC_CURRENTLY_BEING_QDELETED)
tobequeued += A
@@ -211,7 +219,7 @@ SUBSYSTEM_DEF(garbage)
if (QDEL_HINT_HARDDEL) //qdel should assume this object won't gc, and queue a hard delete using a hard reference to save time from the locate()
SSgarbage.HardQueue(D)
if (QDEL_HINT_HARDDEL_NOW) //qdel should assume this object won't gc, and hard del it post haste.
- del(D)
+ SSgarbage.HardDelete(D)
if (QDEL_HINT_FINDREFERENCE)//qdel will, if TESTING is enabled, display all references to this object, then queue the object for deletion.
SSgarbage.QueueForQueuing(D)
#ifdef TESTING
diff --git a/code/controllers/subsystem/job.dm b/code/controllers/subsystem/job.dm
index 137bd2a2c1..a3255b73e4 100644
--- a/code/controllers/subsystem/job.dm
+++ b/code/controllers/subsystem/job.dm
@@ -483,7 +483,7 @@ SUBSYSTEM_DEF(job)
else level4++ //not selected
tmp_str += "HIGH=[level1]|MEDIUM=[level2]|LOW=[level3]|NEVER=[level4]|BANNED=[level5]|YOUNG=[level6]|-"
- feedback_add_details("job_preferences",tmp_str)
+ SSblackbox.add_details("job_preferences",tmp_str)
/datum/controller/subsystem/job/proc/PopcapReached()
if(config.hard_popcap || config.extreme_popcap)
diff --git a/code/controllers/subsystem/mapping.dm b/code/controllers/subsystem/mapping.dm
index 1499bc5029..85c580f4d9 100644
--- a/code/controllers/subsystem/mapping.dm
+++ b/code/controllers/subsystem/mapping.dm
@@ -18,6 +18,8 @@ SUBSYSTEM_DEF(mapping)
var/list/shuttle_templates = list()
var/list/shelter_templates = list()
+ var/loading_ruins = FALSE
+
/datum/controller/subsystem/mapping/PreInit()
if(!config)
#ifdef FORCE_MAP
@@ -32,13 +34,13 @@ SUBSYSTEM_DEF(mapping)
if(config.defaulted)
to_chat(world, "Unable to load next map config, defaulting to Box Station")
loadWorld()
- SortAreas()
+ repopulate_sorted_areas()
process_teleport_locs() //Sets up the wizard teleport locations
preloadTemplates()
// Pick a random away mission.
createRandomZlevel()
// Generate mining.
-
+ loading_ruins = TRUE
var/mining_type = config.minetype
if (mining_type == "lavaland")
seedRuins(list(5), global.config.lavaland_budget, /area/lavaland/surface/outdoors, lava_ruins_templates)
@@ -54,7 +56,8 @@ SUBSYSTEM_DEF(mapping)
space_zlevels += i
seedRuins(space_zlevels, global.config.space_budget, /area/space, space_ruins_templates)
-
+ loading_ruins = FALSE
+ repopulate_sorted_areas()
// Set up Z-level transistions.
setup_map_transitions()
..()
@@ -116,7 +119,7 @@ SUBSYSTEM_DEF(mapping)
INIT_ANNOUNCE("Loading [config.map_name]...")
TryLoadZ(config.GetFullMapPath(), FailedZs, ZLEVEL_STATION)
INIT_ANNOUNCE("Loaded station in [(REALTIMEOFDAY - start_time)/10]s!")
- feedback_add_details("map_name", config.map_name)
+ SSblackbox.add_details("map_name", config.map_name)
if(config.minetype != "lavaland")
INIT_ANNOUNCE("WARNING: A map without lavaland set as it's minetype was loaded! This is being ignored! Update the maploader code!")
@@ -144,31 +147,35 @@ SUBSYSTEM_DEF(mapping)
mapvotes[global.config.defaultmap.map_name] += 1
continue
mapvotes[vote] += 1
+ else
+ for(var/M in global.config.maplist)
+ mapvotes[M] = 1
- //filter votes
- for (var/map in mapvotes)
- if (!map)
- mapvotes.Remove(map)
- if (!(map in global.config.maplist))
- mapvotes.Remove(map)
- continue
- var/datum/map_config/VM = global.config.maplist[map]
- if (!VM)
- mapvotes.Remove(map)
- continue
- if (VM.voteweight <= 0)
- mapvotes.Remove(map)
- continue
- if (VM.config_min_users > 0 && players < VM.config_min_users)
- mapvotes.Remove(map)
- continue
- if (VM.config_max_users > 0 && players > VM.config_max_users)
- mapvotes.Remove(map)
- continue
+ //filter votes
+ for (var/map in mapvotes)
+ if (!map)
+ mapvotes.Remove(map)
+ if (!(map in global.config.maplist))
+ mapvotes.Remove(map)
+ continue
+ var/datum/map_config/VM = global.config.maplist[map]
+ if (!VM)
+ mapvotes.Remove(map)
+ continue
+ if (VM.voteweight <= 0)
+ mapvotes.Remove(map)
+ continue
+ if (VM.config_min_users > 0 && players < VM.config_min_users)
+ mapvotes.Remove(map)
+ continue
+ if (VM.config_max_users > 0 && players > VM.config_max_users)
+ mapvotes.Remove(map)
+ continue
+ if(global.config.allow_map_voting)
mapvotes[map] = mapvotes[map]*VM.voteweight
- var/pickedmap = global.config.allow_map_voting ? pickweight(mapvotes) : pick(global.config.maplist)
+ var/pickedmap = pickweight(mapvotes)
if (!pickedmap)
return
var/datum/map_config/VM = global.config.maplist[pickedmap]
diff --git a/code/controllers/subsystem/npcpool.dm b/code/controllers/subsystem/npcpool.dm
index 7bd412b823..26e6f90b9d 100644
--- a/code/controllers/subsystem/npcpool.dm
+++ b/code/controllers/subsystem/npcpool.dm
@@ -19,7 +19,7 @@ SUBSYSTEM_DEF(npcpool)
/datum/controller/subsystem/npcpool/stat_entry()
..("NPCS:[processing.len]|D:[needsDelegate.len]|A:[needsAssistant.len]|U:[canBeUsed.len]")
-/datum/controller/subsystem/npcpool/proc/stop_processing(mob/living/carbon/human/interactive/I)
+/datum/controller/subsystem/npcpool/proc/stop_processing(mob/living/I)
processing -= I
currentrun -= I
needsDelegate -= I
diff --git a/code/controllers/subsystem/ping.dm b/code/controllers/subsystem/ping.dm
index 0829766174..a6b444c4e7 100644
--- a/code/controllers/subsystem/ping.dm
+++ b/code/controllers/subsystem/ping.dm
@@ -3,14 +3,20 @@
SUBSYSTEM_DEF(ping)
name = "Ping"
wait = 6
- flags = SS_NO_INIT|SS_POST_FIRE_TIMING|SS_FIRE_IN_LOBBY
+ flags = SS_POST_FIRE_TIMING|SS_FIRE_IN_LOBBY
priority = 10
var/list/currentrun
+/datum/controller/subsystem/ping/Initialize()
+ if (config.hub)
+ world.visibility = 1
+ ..()
+
/datum/controller/subsystem/ping/fire(resumed = FALSE)
if (!resumed)
src.currentrun = GLOB.clients.Copy()
+ var/round_started = Master.round_started
var/list/currentrun = src.currentrun
while (length(currentrun))
var/client/C = currentrun[currentrun.len]
@@ -19,7 +25,15 @@ SUBSYSTEM_DEF(ping)
if (MC_TICK_CHECK)
return
continue
+
+ if(round_started && C.is_afk(INACTIVITY_KICK))
+ if(!istype(C.mob, /mob/dead))
+ log_access("AFK: [key_name(C)]")
+ to_chat(C, "You have been inactive for more than 10 minutes and have been disconnected.")
+ qdel(C)
+
winset(C, null, "command=.update_ping+[world.time+world.tick_lag*world.tick_usage/100]")
+
if (MC_TICK_CHECK) //one day, when ss13 has 1000 people per server, you guys are gonna be glad I added this tick check
return
diff --git a/code/controllers/subsystem/server_maint.dm.rej b/code/controllers/subsystem/server_maint.dm.rej
new file mode 100644
index 0000000000..f759db5330
--- /dev/null
+++ b/code/controllers/subsystem/server_maint.dm.rej
@@ -0,0 +1,7 @@
+diff a/code/controllers/subsystem/server_maint.dm b/code/controllers/subsystem/server_maint.dm (rejected hunks)
+@@ -18,5 +18,3 @@ SUBSYSTEM_DEF(server_maint)
+ to_chat(C, "You have been inactive for more than 10 minutes and have been disconnected.")
+ qdel(C)
+
+- if(config.sql_enabled)
+- sql_poll_population()
diff --git a/code/controllers/subsystem/shuttle.dm b/code/controllers/subsystem/shuttle.dm
index b8d17cab87..e2546f65c4 100644
--- a/code/controllers/subsystem/shuttle.dm
+++ b/code/controllers/subsystem/shuttle.dm
@@ -210,12 +210,10 @@ SUBSYSTEM_DEF(shuttle)
var/emergency_reason = "\nNature of emergency:\n\n[call_reason]"
var/security_num = seclevel2num(get_security_level())
switch(security_num)
- if(SEC_LEVEL_GREEN)
- emergency.request(null, 2, signal_origin, html_decode(emergency_reason), 0)
- if(SEC_LEVEL_BLUE)
- emergency.request(null, 1, signal_origin, html_decode(emergency_reason), 0)
+ if(SEC_LEVEL_RED,SEC_LEVEL_DELTA)
+ emergency.request(null, signal_origin, html_decode(emergency_reason), 1) //There is a serious threat we gotta move no time to give them five minutes.
else
- emergency.request(null, 0.5, signal_origin, html_decode(emergency_reason), 1) // There is a serious threat we gotta move no time to give them five minutes.
+ emergency.request(null, signal_origin, html_decode(emergency_reason), 0)
log_game("[key_name(user)] has called the shuttle.")
message_admins("[key_name_admin(user)] has called the shuttle.")
@@ -274,7 +272,7 @@ SUBSYSTEM_DEF(shuttle)
if(callShuttle)
if(EMERGENCY_IDLE_OR_RECALLED)
- emergency.request(null, 2.5)
+ emergency.request(null, set_coefficient = 2.5)
log_game("There is no means of calling the shuttle anymore. Shuttle automatically called.")
message_admins("All the communications consoles were destroyed and all AIs are inactive. Shuttle called.")
diff --git a/code/datums/antagonists/antag_datum.dm b/code/datums/antagonists/antag_datum.dm
index cdad092087..deee1111c0 100644
--- a/code/datums/antagonists/antag_datum.dm
+++ b/code/datums/antagonists/antag_datum.dm
@@ -1,87 +1,49 @@
-//The Datum, Antagonist. Handles various antag things via a datum.
/datum/antagonist
- var/mob/living/owner //who's our owner and accordingly an antagonist
- var/some_flufftext = "yer an antag larry"
- var/prevented_antag_datum_type //the type of antag datum that this datum can't coexist with; should probably be a list
- var/silent_update = FALSE //if we suppress messages during on_gain, apply_innate_effects, remove_innate_effects, and on_remove
+ var/name = "Antagonist"
-/datum/antagonist/New()
- if(!prevented_antag_datum_type)
- prevented_antag_datum_type = type
+ var/datum/mind/owner //Mind that owns this datum
-/datum/antagonist/Destroy()
- owner = null
- return ..()
+ var/silent = FALSE //Silent will prevent the gain/lose texts to show
-/datum/antagonist/proc/can_be_owned(mob/living/new_body)
- return new_body && !new_body.has_antag_datum(prevented_antag_datum_type, TRUE)
+ var/can_coexist_with_others = TRUE //Whether or not the person will be able to have more than one datum
+ var/list/typecache_datum_blacklist = list() //List of datums this type can't coexist with
-/datum/antagonist/proc/give_to_body(mob/living/new_body) //tries to give an antag datum to a mob. cancels out if it can't be owned by the new body
- if(new_body && can_be_owned(new_body))
- new_body.antag_datums += src
- owner = new_body
- on_gain()
- . = src //return the datum if successful
- else
- qdel(src)
- . = FALSE
-/datum/antagonist/proc/on_gain() //on initial gain of antag datum, do this. should only be called once per datum
- apply_innate_effects()
- if(!silent_update && some_flufftext)
- to_chat(owner, some_flufftext)
+/datum/antagonist/New(datum/mind/new_owner)
+ . = ..()
+ typecache_datum_blacklist = typecacheof(typecache_datum_blacklist)
+ if(new_owner)
+ owner = new_owner
-/datum/antagonist/proc/apply_innate_effects() //applies innate effects to the owner, may be called multiple times due to mind transferral, but should only be called once per mob
- //antag huds would go here if antag huds were less completely unworkable as-is
+/datum/antagonist/proc/on_body_transfer(mob/living/old_body, mob/living/new_body)
+ remove_innate_effects(old_body)
+ apply_innate_effects(new_body)
-/datum/antagonist/proc/remove_innate_effects() //removes innate effects from the owner, may be called multiple times due to mind transferral, but should only be called once per mob
- //also antag huds but see above antag huds a shit
+//This handles the application of antag huds/special abilities
+/datum/antagonist/proc/apply_innate_effects(mob/living/mob_override)
+ return
-/datum/antagonist/proc/on_remove() //totally removes the antag datum from the owner; can only be called once per owner
+//This handles the removal of antag huds/special abilities
+/datum/antagonist/proc/remove_innate_effects(mob/living/mob_override)
+ return
+
+//Proc called when the datum is given to a mind.
+/datum/antagonist/proc/on_gain()
+ if(owner && owner.current)
+ if(!silent)
+ greet()
+ apply_innate_effects()
+
+/datum/antagonist/proc/on_removal()
remove_innate_effects()
- owner.antag_datums -= src
+ if(owner)
+ owner.antag_datums -= src
+ if(!silent && owner.current)
+ farewell()
qdel(src)
-/datum/antagonist/proc/transfer_to_new_body(mob/living/new_body)
- remove_innate_effects()
- if(!islist(new_body.antag_datums))
- new_body.antag_datums = list()
- new_body.antag_datums += src
- owner.antag_datums -= src
- owner = new_body
- apply_innate_effects()
+/datum/antagonist/proc/greet()
+ return
-//mob var and helper procs/Destroy override
-/mob/living
- var/list/antag_datums
-
-/mob/living/Destroy() //TODO: merge this with the living/Destroy() in code\modules\mob\living\living.dm (currently line 29)
- if(islist(antag_datums))
- for(var/i in antag_datums)
- qdel(i)
- antag_datums = null
- return ..()
-
-/mob/living/proc/can_have_antag_datum(datum_type) //if we can have this specific antagonist datum; neccessary, but requires creating a new antag datum each time.
- var/datum/antagonist/D = new datum_type()
- . = D.can_be_owned(src) //we can't exactly cache the results, either, because conditions might change. avoid use? TODO: better proc
- qdel(D)
-
-/mob/living/proc/gain_antag_datum(datum_type) //tries to give a mob a specific antagonist datum; returns the datum if successful.
- if(!islist(antag_datums))
- antag_datums = list()
- var/datum/antagonist/D = new datum_type()
- . = D.give_to_body(src)
-
-/mob/living/proc/has_antag_datum(type, check_subtypes) //checks this mob for if it has the antagonist datum. can either check specific type or subtypes
- if(!islist(antag_datums))
- return FALSE
- for(var/i in antag_datums)
- var/datum/antagonist/D = i
- if(check_subtypes)
- if(istype(D, type))
- return D //if it finds the datum, will return it so you can mess with it
- else
- if(D.type == type)
- return D
- return FALSE
+/datum/antagonist/proc/farewell()
+ return
\ No newline at end of file
diff --git a/code/datums/antagonists/datum_clockcult.dm b/code/datums/antagonists/datum_clockcult.dm
index 0c39b5a989..ba18e76f02 100644
--- a/code/datums/antagonists/datum_clockcult.dm
+++ b/code/datums/antagonists/datum_clockcult.dm
@@ -1,92 +1,57 @@
//CLOCKCULT PROOF OF CONCEPT
-
-/datum/antagonist/clockcultist
- prevented_antag_datum_type = /datum/antagonist/clockcultist
- some_flufftext = null
+/datum/antagonist/clockcult
var/datum/action/innate/hierophant/hierophant_network = new()
-/datum/antagonist/clockcultist/silent
- silent_update = TRUE
+/datum/antagonist/clockcult/silent
+ silent = TRUE
-/datum/antagonist/clockcultist/Destroy()
+/datum/antagonist/clockcult/Destroy()
qdel(hierophant_network)
- ..()
+ return ..()
-/datum/antagonist/clockcultist/can_be_owned(mob/living/new_body)
- . = ..()
- if(.)
- . = is_eligible_servant(new_body)
-
-/datum/antagonist/clockcultist/give_to_body(mob/living/new_body)
- if(iscyborg(new_body))
- var/mob/living/silicon/robot/R = new_body
- if(R.deployed)
- var/mob/living/silicon/ai/AI = R.mainframe
- R.undeploy()
- var/converted = add_servant_of_ratvar(AI, silent_update)
- to_chat(AI, "Anomaly Detected. Returned to core!") //The AI needs to be in its core to properly be converted
- return converted
- if(!silent_update)
- if(issilicon(new_body))
- to_chat(new_body, "You are unable to compute this truth. Your vision glows a brilliant yellow, and all at once it comes to you. Ratvar, the Clockwork Justiciar, \
- lies in exile, derelict and forgotten in an unseen realm.")
- else
- to_chat(new_body, "[iscarbon(new_body) ? "Your mind is racing! Your body feels incredibly light! ":""]Your world glows a brilliant yellow! All at once it comes to you. \
- Ratvar, the Clockwork Justiciar, lies in exile, derelict and forgotten in an unseen realm.")
- . = ..()
- if(!silent_update && new_body)
- if(.)
- new_body.visible_message("[new_body]'s eyes glow a blazing yellow!")
- to_chat(new_body, "Assist your new companions in their righteous efforts. Your goal is theirs, and theirs yours. You serve the Clockwork Justiciar above all else. \
- Perform his every whim without hesitation.")
- else
- new_body.visible_message("[new_body] seems to resist an unseen force!")
- to_chat(new_body, "And yet, you somehow push it all away.")
-
-/datum/antagonist/clockcultist/on_gain()
- if(SSticker && SSticker.mode && owner.mind)
- SSticker.mode.servants_of_ratvar += owner.mind
- SSticker.mode.update_servant_icons_added(owner.mind)
- if(jobban_isbanned(owner, ROLE_SERVANT_OF_RATVAR))
- INVOKE_ASYNC(SSticker.mode, /datum/game_mode.proc/replace_jobbaned_player, owner, ROLE_SERVANT_OF_RATVAR, ROLE_SERVANT_OF_RATVAR)
- if(owner.mind)
- owner.mind.special_role = "Servant of Ratvar"
- owner.log_message("Has been converted to the cult of Ratvar!", INDIVIDUAL_ATTACK_LOG)
- if(issilicon(owner))
+/datum/antagonist/clockcult/on_gain()
+ if(!owner)
+ return
+ var/mob/living/current = owner.current
+ if(!istype(current))
+ return
+ if(jobban_isbanned(current, ROLE_SERVANT_OF_RATVAR))
+ addtimer(CALLBACK(SSticker.mode, /datum/game_mode.proc/replace_jobbaned_player, owner, ROLE_SERVANT_OF_RATVAR, ROLE_SERVANT_OF_RATVAR), 0)
+ owner.current.log_message("Has been converted to the cult of Ratvar!", INDIVIDUAL_ATTACK_LOG)
+ if(issilicon(current))
var/mob/living/silicon/S = owner
- if(iscyborg(S) && !silent_update)
- to_chat(S, "You have been desynced from your master AI.\n\
- In addition, your onboard camera is no longer active and you have gained additional equipment, including a limited clockwork slab.")
+ if(iscyborg(S) && !silent)
+ to_chat(S, "You have been desynced from your master AI.")
+ to_chat(S, "In addition, your onboard camera is no longer active and you have gained additional equipment, including a limited clockwork slab.")
if(isAI(S))
to_chat(S, "You are able to use your cameras to listen in on conversations.")
to_chat(S, "You can communicate with other servants by using the Hierophant Network action button in the upper left.")
- else if(isbrain(owner) || isclockmob(owner))
- to_chat(owner, "You can communicate with other servants by using the Hierophant Network action button in the upper left.")
+ else if(isbrain(current) || isclockmob(current))
+ to_chat(current, "You can communicate with other servants by using the Hierophant Network action button in the upper left.")
..()
if(istype(SSticker.mode, /datum/game_mode/clockwork_cult))
var/datum/game_mode/clockwork_cult/C = SSticker.mode
C.present_tasks(owner) //Memorize the objectives
-/datum/antagonist/clockcultist/apply_innate_effects()
- GLOB.all_clockwork_mobs += owner
- owner.faction |= "ratvar"
- owner.grant_language(/datum/language/ratvar)
- owner.update_action_buttons_icon() //because a few clockcult things are action buttons and we may be wearing/holding them for whatever reason, we need to update buttons
- if(issilicon(owner))
- var/mob/living/silicon/S = owner
+/datum/antagonist/clockcult/apply_innate_effects(mob/living/mob_override)
+ . = ..()
+ var/mob/living/current = owner.current
+ if(istype(mob_override))
+ current = mob_override
+ GLOB.all_clockwork_mobs += current
+ SSticker.mode.update_servant_icons_added(owner)
+ current.faction |= "ratvar"
+ current.grant_language(/datum/language/ratvar)
+ current.update_action_buttons_icon() //because a few clockcult things are action buttons and we may be wearing/holding them for whatever reason, we need to update buttons
+ if(issilicon(current))
+ var/mob/living/silicon/S = current
if(iscyborg(S))
var/mob/living/silicon/robot/R = S
- if(!R.shell)
- R.UnlinkSelf()
+ R.UnlinkSelf()
R.module.rebuild_modules()
else if(isAI(S))
var/mob/living/silicon/ai/A = S
- A.can_be_carded = FALSE
A.requires_power = POWER_REQ_CLOCKCULT
- var/list/AI_frame = list(mutable_appearance('icons/mob/clockwork_mobs.dmi', "aiframe")) //make the AI's cool frame
- for(var/d in GLOB.cardinal)
- AI_frame += image('icons/mob/clockwork_mobs.dmi', A, "eye[rand(1, 10)]", dir = d) //the eyes are randomly fast or slow
- A.add_overlay(AI_frame)
if(!A.lacks_power())
A.ai_restore_power()
if(A.eyeobj)
@@ -106,58 +71,55 @@
hierophant_network.title = "Silicon"
hierophant_network.span_for_name = "nezbere"
hierophant_network.span_for_message = "brass"
- else if(isbrain(owner))
- hierophant_network.Grant(owner)
+ else if(isbrain(current))
+ hierophant_network.Grant(current)
hierophant_network.title = "Vessel"
hierophant_network.span_for_name = "nezbere"
hierophant_network.span_for_message = "alloy"
- else if(isclockmob(owner))
- hierophant_network.Grant(owner)
+ else if(isclockmob(current))
+ hierophant_network.Grant(current)
hierophant_network.title = "Construct"
hierophant_network.span_for_name = "nezbere"
hierophant_network.span_for_message = "brass"
- owner.throw_alert("clockinfo", /obj/screen/alert/clockwork/infodump)
+ current.throw_alert("clockinfo", /obj/screen/alert/clockwork/infodump)
if(!GLOB.clockwork_gateway_activated)
- owner.throw_alert("scripturereq", /obj/screen/alert/clockwork/scripture_reqs)
- ..()
+ current.throw_alert("scripturereq", /obj/screen/alert/clockwork/scripture_reqs)
+ update_slab_info()
-/datum/antagonist/clockcultist/remove_innate_effects()
- GLOB.all_clockwork_mobs -= owner
- owner.faction -= "ratvar"
- owner.remove_language(/datum/language/ratvar)
- owner.clear_alert("clockinfo")
- owner.clear_alert("scripturereq")
- for(var/datum/action/innate/function_call/F in owner.actions) //Removes any bound Ratvarian spears
+
+/datum/antagonist/clockcult/remove_innate_effects(mob/living/mob_override)
+ var/mob/living/current = owner.current
+ if(istype(mob_override))
+ current = mob_override
+ GLOB.all_clockwork_mobs -= current
+ current.faction -= "ratvar"
+ current.remove_language(/datum/language/ratvar)
+ current.clear_alert("clockinfo")
+ current.clear_alert("scripturereq")
+ for(var/datum/action/innate/function_call/F in owner.current.actions) //Removes any bound Ratvarian spears
qdel(F)
- if(issilicon(owner))
- var/mob/living/silicon/S = owner
+ if(issilicon(current))
+ var/mob/living/silicon/S = current
if(isAI(S))
var/mob/living/silicon/ai/A = S
- A.can_be_carded = initial(A.can_be_carded)
A.requires_power = initial(A.requires_power)
- A.cut_overlays()
S.make_laws()
S.update_icons()
S.show_laws()
- var/mob/living/temp_owner = owner
+ var/mob/living/temp_owner = current
..()
if(iscyborg(temp_owner))
var/mob/living/silicon/robot/R = temp_owner
R.module.rebuild_modules()
if(temp_owner)
temp_owner.update_action_buttons_icon() //because a few clockcult things are action buttons and we may be wearing/holding them, we need to update buttons
+ update_slab_info()
-/datum/antagonist/clockcultist/on_remove()
- if(!silent_update)
- owner.visible_message("[owner] seems to have remembered their true allegiance!", \
+/datum/antagonist/clockcult/on_removal()
+ . = ..()
+ if(!silent)
+ owner.current.visible_message("[owner] seems to have remembered their true allegiance!", \
"A cold, cold darkness flows through your mind, extinguishing the Justiciar's light and all of your memories as his servant.")
- if(SSticker && SSticker.mode && owner.mind)
- SSticker.mode.servants_of_ratvar -= owner.mind
- SSticker.mode.update_servant_icons_removed(owner.mind)
- if(owner.mind)
- owner.mind.wipe_memory()
- owner.mind.special_role = null
- owner.log_message("Has renounced the cult of Ratvar!", INDIVIDUAL_ATTACK_LOG)
- if(iscyborg(owner))
- to_chat(owner, "Despite your freedom from Ratvar's influence, you are still irreparably damaged and no longer possess certain functions such as AI linking.")
- ..()
+ owner.current.log_message("Has renounced the cult of Ratvar!", INDIVIDUAL_ATTACK_LOG)
+ if(iscyborg(owner.current))
+ to_chat(owner.current, "Despite your freedom from Ratvar's influence, you are still irreparably damaged and no longer possess certain functions such as AI linking.")
\ No newline at end of file
diff --git a/code/datums/antagonists/datum_cult.dm b/code/datums/antagonists/datum_cult.dm
index 7d6806bab6..69c9849782 100644
--- a/code/datums/antagonists/datum_cult.dm
+++ b/code/datums/antagonists/datum_cult.dm
@@ -1,50 +1,33 @@
-/datum/antagonist/cultist
- prevented_antag_datum_type = /datum/antagonist/cultist
- some_flufftext = null
- var/datum/action/innate/cultcomm/communion = new()
+/datum/antagonist/cult
+ var/datum/action/innate/cultcomm/communion = new
-/datum/antagonist/cultist/Destroy()
+/datum/antagonist/cult/Destroy()
qdel(communion)
return ..()
-/datum/antagonist/cultist/can_be_owned(mob/living/new_body)
+/datum/antagonist/cult/on_gain()
. = ..()
- if(.)
- . = is_convertable_to_cult(new_body)
+ if(!owner)
+ return
+ if(jobban_isbanned(owner.current, ROLE_CULTIST))
+ addtimer(CALLBACK(SSticker.mode, /datum/game_mode.proc/replace_jobbaned_player, owner, ROLE_CULTIST, ROLE_CULTIST), 0)
+ owner.current.log_message("Has been converted to the cult of Nar'Sie!", INDIVIDUAL_ATTACK_LOG)
-/datum/antagonist/cultist/on_gain()
- if(SSticker && SSticker.mode && owner.mind)
- SSticker.mode.cult += owner.mind
- SSticker.mode.update_cult_icons_added(owner.mind)
- if(istype(SSticker.mode, /datum/game_mode/cult))
- var/datum/game_mode/cult/C = SSticker.mode
- C.memorize_cult_objectives(owner.mind)
- if(jobban_isbanned(owner, ROLE_CULTIST))
- INVOKE_ASYNC(SSticker.mode, /datum/game_mode.proc/replace_jobbaned_player, owner, ROLE_CULTIST, ROLE_CULTIST)
- if(owner.mind)
- owner.mind.special_role = "Cultist"
- owner.log_message("Has been converted to the cult of Nar'Sie!", INDIVIDUAL_ATTACK_LOG)
- ..()
-
-/datum/antagonist/cultist/apply_innate_effects()
- owner.faction |= "cult"
- owner.verbs += /mob/living/proc/cult_help
+/datum/antagonist/cult/apply_innate_effects()
+ . = ..()
+ owner.current.faction |= "cult"
+ owner.current.verbs += /mob/living/proc/cult_help
communion.Grant(owner)
- ..()
-/datum/antagonist/cultist/remove_innate_effects()
- owner.faction -= "cult"
- owner.verbs -= /mob/living/proc/cult_help
- ..()
+/datum/antagonist/cult/remove_innate_effects()
+ . = ..()
+ owner.current.faction -= "cult"
+ owner.current.verbs -= /mob/living/proc/cult_help
-/datum/antagonist/cultist/on_remove()
- if(owner.mind)
- owner.mind.wipe_memory()
- if(SSticker && SSticker.mode)
- SSticker.mode.cult -= owner.mind
- SSticker.mode.update_cult_icons_removed(owner.mind)
+
+/datum/antagonist/cult/on_removal()
+ . = ..()
to_chat(owner, "An unfamiliar white light flashes through your mind, cleansing the taint of the Dark One and all your memories as its servant.")
- owner.log_message("Has renounced the cult of Nar'Sie!", INDIVIDUAL_ATTACK_LOG)
- if(!silent_update)
- owner.visible_message("[owner] looks like [owner.p_they()] just reverted to their old faith!")
- ..()
+ owner.current.log_message("Has renounced the cult of Nar'Sie!", INDIVIDUAL_ATTACK_LOG)
+ if(!silent)
+ owner.current.visible_message("[owner] looks like [owner.current.p_they()] just reverted to their old faith!")
\ No newline at end of file
diff --git a/code/datums/datumvars.dm b/code/datums/datumvars.dm
index fbde20a8d7..fbbf97a6ca 100644
--- a/code/datums/datumvars.dm
+++ b/code/datums/datumvars.dm
@@ -27,6 +27,7 @@
. += "---"
.["Call Proc"] = "?_src_=vars;proc_call=\ref[src]"
.["Mark Object"] = "?_src_=vars;mark_object=\ref[src]"
+ .["Delete"] = "?_src_=vars;delete=\ref[src]"
/datum/proc/on_reagent_change()
@@ -93,7 +94,6 @@
CLONE:[M.getCloneLoss()]
BRAIN:[M.getBrainLoss()]
STAMINA:[M.getStaminaLoss()]
- AROUSAL:[M.getArousalLoss()]
"}
else
@@ -446,7 +446,7 @@
var/list/L = value
var/list/items = list()
- if (L.len > 0 && !(name == "underlays" || name == "overlays" || L.len > 500))
+ if (L.len > 0 && !(name == "underlays" || name == "overlays" || L.len > (IS_NORMAL_LIST(L) ? 50 : 150)))
for (var/i in 1 to L.len)
var/key = L[i]
var/val
@@ -526,6 +526,16 @@
if(T)
callproc_datum(T)
+ else if(href_list["delete"])
+ if(!check_rights(R_DEBUG, 0))
+ return
+
+ var/datum/D = locate(href_list["delete"])
+ if(!D)
+ to_chat(usr, "Unable to locate item!")
+ admin_delete(D)
+ href_list["datumrefresh"] = href_list["delete"]
+
else if(href_list["regenerateicons"])
if(!check_rights(0))
return
@@ -1155,8 +1165,6 @@
L.adjustCloneLoss(amount)
if("stamina")
L.adjustStaminaLoss(amount)
- if("arousal")
- L.adjustArousalLoss(amount)
else
to_chat(usr, "You caused an error. DEBUG: Text:[Text] Mob:[L]")
return
@@ -1167,3 +1175,4 @@
message_admins(msg)
admin_ticket_log(L, msg)
href_list["datumrefresh"] = href_list["mobToDamage"]
+
diff --git a/code/datums/emotes.dm b/code/datums/emotes.dm
index 0d6488c633..9f2753dfee 100644
--- a/code/datums/emotes.dm
+++ b/code/datums/emotes.dm
@@ -35,10 +35,6 @@
var/msg = select_message_type(user)
if(params && message_param)
msg = select_param(user, params)
- if(findtext(msg, "their"))
- msg = replacetext(msg, "their", user.p_their())
- if(findtext(msg, "them"))
- msg = replacetext(msg, "them", user.p_them())
if(findtext(msg, "%s"))
msg = replacetext(msg, "%s", user.p_s())
diff --git a/code/datums/helper_datums/getrev.dm b/code/datums/helper_datums/getrev.dm
index 628949ebc0..b9358817e3 100644
--- a/code/datums/helper_datums/getrev.dm
+++ b/code/datums/helper_datums/getrev.dm
@@ -25,7 +25,7 @@
for(var/line in testmerge)
if(line)
log_world("Test merge active of PR #[line]")
- feedback_add_details("testmerged_prs","[line]")
+ SSblackbox.add_details("testmerged_prs","[line]")
log_world("Based off master commit [parentcommit]")
else
log_world(parentcommit)
@@ -105,13 +105,13 @@
probs[ctag] = 1
prob_sum += config.probabilities[ctag]
if(current_odds_differ)
- src <<"Game Mode Odds for current round:"
+ to_chat(src, "Game Mode Odds for current round:")
for(var/ctag in probs)
if(config.probabilities[ctag] > 0)
var/percentage = round(config.probabilities[ctag] / prob_sum * 100, 0.1)
to_chat(src, "[ctag] [percentage]%")
- src <<"All Game Mode Odds:"
+ to_chat(src, "All Game Mode Odds:")
var/sum = 0
for(var/ctag in config.probabilities)
sum += config.probabilities[ctag]
diff --git a/code/datums/martial.dm b/code/datums/martial.dm
index cc6fa4f2c8..b20bf556d5 100644
--- a/code/datums/martial.dm
+++ b/code/datums/martial.dm
@@ -657,7 +657,7 @@
/obj/item/weapon/cqc_manual/attack_self(mob/living/carbon/human/user)
if(!istype(user) || !user)
return
- user <<"You remember the basics of CQC."
+ to_chat(user, "You remember the basics of CQC.")
var/datum/martial_art/cqc/D = new(null)
D.teach(user)
user.drop_item()
diff --git a/code/datums/material_container.dm b/code/datums/material_container.dm
index af227212a7..76de0329cd 100644
--- a/code/datums/material_container.dm
+++ b/code/datums/material_container.dm
@@ -136,7 +136,7 @@
return FALSE
//For spawning mineral sheets; internal use only
-/datum/material_container/proc/retrieve(sheet_amt, datum/material/M)
+/datum/material_container/proc/retrieve(sheet_amt, datum/material/M, target = null)
if(!M.sheet_type)
return 0
if(sheet_amt > 0)
@@ -149,26 +149,28 @@
use_amount_type(sheet_amt * MINERAL_MATERIAL_AMOUNT, M.id)
sheet_amt -= MAX_STACK_SIZE
if(round((sheet_amt * MINERAL_MATERIAL_AMOUNT) / MINERAL_MATERIAL_AMOUNT))
- new M.sheet_type(get_turf(owner), sheet_amt)
+ var/obj/item/stack/sheet/s = new M.sheet_type(get_turf(owner), sheet_amt)
+ if(target)
+ s.forceMove(target)
count += sheet_amt
use_amount_type(sheet_amt * MINERAL_MATERIAL_AMOUNT, M.id)
return count
return 0
-/datum/material_container/proc/retrieve_sheets(sheet_amt, id)
+/datum/material_container/proc/retrieve_sheets(sheet_amt, id, target = null)
if(materials[id])
- return retrieve(sheet_amt, materials[id])
+ return retrieve(sheet_amt, materials[id], target)
return 0
-/datum/material_container/proc/retrieve_amount(amt, id)
- return retrieve_sheets(amount2sheet(amt), id)
+/datum/material_container/proc/retrieve_amount(amt, id, target)
+ return retrieve_sheets(amount2sheet(amt), id, target)
-/datum/material_container/proc/retrieve_all()
+/datum/material_container/proc/retrieve_all(target = null)
var/result = 0
var/datum/material/M
for(var/MAT in materials)
M = materials[MAT]
- result += retrieve_sheets(amount2sheet(M.amount), MAT)
+ result += retrieve_sheets(amount2sheet(M.amount), MAT, target)
return result
/datum/material_container/proc/has_space(amt = 0)
diff --git a/code/datums/mind.dm b/code/datums/mind.dm
index 535247d750..5a1ba5b8c5 100644
--- a/code/datums/mind.dm
+++ b/code/datums/mind.dm
@@ -54,6 +54,7 @@
var/linglink
var/miming = 0 // Mime's vow of silence
+ var/list/antag_datums = list()
var/antag_hud_icon_state = null //this mind's ANTAG_HUD should have this icon_state
var/datum/atom_hud/antag/antag_hud = null //this mind's antag HUD
var/datum/gang/gang_datum //Which gang this mind belongs to, if any
@@ -86,13 +87,13 @@
if(new_character.mind) //disassociate any mind currently in our new body's mind variable
new_character.mind.current = null
- if(istype(current) && islist(current.antag_datums)) //wow apparently current isn't always living good fucking job SOMEONE
- for(var/i in current.antag_datums)
- var/datum/antagonist/D = i
- D.transfer_to_new_body(new_character)
var/datum/atom_hud/antag/hud_to_transfer = antag_hud//we need this because leave_hud() will clear this list
+ var/mob/living/old_current = current
current = new_character //associate ourself with our new body
new_character.mind = src //and associate our new body with ourself
+ for(var/a in antag_datums) //Makes sure all antag datums effects are applied in the new body
+ var/datum/antagonist/A = a
+ A.on_body_transfer(old_current, current)
if(iscarbon(new_character))
var/mob/living/carbon/C = new_character
C.last_mind = src
@@ -108,6 +109,51 @@
/datum/mind/proc/wipe_memory()
memory = null
+// Datum antag mind procs
+/datum/mind/proc/add_antag_datum(datum_type, on_gain = TRUE)
+ if(!datum_type)
+ return
+ if(!can_hold_antag_datum(datum_type))
+ return
+ var/datum/antagonist/A = new datum_type(src)
+ antag_datums += A
+ if(on_gain)
+ A.on_gain()
+
+/datum/mind/proc/remove_antag_datum(datum_type)
+ if(!datum_type)
+ return
+ var/datum/antagonist/A = has_antag_datum(datum_type)
+ if(A)
+ A.on_removal()
+
+/datum/mind/proc/remove_all_antag_datums() //For the Lazy amongst us.
+ for(var/a in antag_datums)
+ var/datum/antagonist/A = a
+ A.on_removal()
+
+/datum/mind/proc/has_antag_datum(datum_type, check_subtypes = TRUE)
+ if(!datum_type)
+ return
+ . = FALSE
+ for(var/a in antag_datums)
+ var/datum/antagonist/A = a
+ if(check_subtypes && istype(A, datum_type))
+ return A
+ else if(A.type == datum_type)
+ return A
+
+/datum/mind/proc/can_hold_antag_datum(datum_type)
+ if(!datum_type)
+ return
+ . = TRUE
+ if(has_antag_datum(datum_type))
+ return FALSE
+ for(var/i in antag_datums)
+ var/datum/antagonist/A = i
+ if(is_type_in_typecache(A, A.typecache_datum_blacklist))
+ return FALSE
+
/*
Removes antag type's references from a mind.
@@ -1143,7 +1189,7 @@
log_admin("[key_name_admin(usr)] has made [current] unable to ascend as a devil.")
return
if(!ishuman(current) && !iscyborg(current))
- usr << "This only works on humans and cyborgs!"
+ to_chat(usr, "This only works on humans and cyborgs!")
return
SSticker.mode.devils += src
special_role = "devil"
diff --git a/code/datums/ruins/space.dm b/code/datums/ruins/space.dm
index ab55919a03..36883c59fe 100644
--- a/code/datums/ruins/space.dm
+++ b/code/datums/ruins/space.dm
@@ -43,6 +43,13 @@
name = "Asteroid 5"
description = "Oh my god, another giant rock!"
+/datum/map_template/ruin/space/deep_storage
+ id = "deep-storage"
+ suffix = "deepstorage.dmm"
+ name = "Survivalist Bunker"
+ description = "Assume the best, prepare for the worst. Generally, you should do so by digging a three man heavily fortified bunker into a giant unused asteroid. \
+ Then make it self sufficient, mask any evidence of construction, hook it covertly into the telecommunications network and hope for the best."
+
/datum/map_template/ruin/space/bigderelict1
id = "bigderelict1"
suffix = "bigderelict1.dmm"
diff --git a/code/datums/status_effects/buffs.dm b/code/datums/status_effects/buffs.dm
index d07f66609b..3f261c7991 100644
--- a/code/datums/status_effects/buffs.dm
+++ b/code/datums/status_effects/buffs.dm
@@ -72,6 +72,8 @@
add_logs(owner, null, "gained Vanguard stun immunity")
owner.add_stun_absorption("vanguard", 200, 1, "'s yellow aura momentarily intensifies!", "Your ward absorbs the stun!", " radiating with a soft yellow light!")
owner.visible_message("[owner] begins to faintly glow!", "You will absorb all stuns for the next twenty seconds.")
+ owner.SetStunned(0, FALSE)
+ owner.SetWeakened(0)
progbar = new(owner, duration, owner)
progbar.bar.color = list("#FAE48C", "#FAE48C", "#FAE48C", rgb(0,0,0))
progbar.update(duration - world.time)
diff --git a/code/datums/status_effects/status_effect.dm b/code/datums/status_effects/status_effect.dm
index 8b6d255f1a..51b4f8fc5f 100644
--- a/code/datums/status_effects/status_effect.dm
+++ b/code/datums/status_effects/status_effect.dm
@@ -8,6 +8,7 @@
var/tick_interval = 10 //How many deciseconds between ticks, approximately. Leave at 10 for every second.
var/mob/living/owner //The mob affected by the status effect.
var/status_type = STATUS_EFFECT_UNIQUE //How many of the effect can be on one mob, and what happens when you try to add another
+ var/on_remove_on_mob_delete = FALSE //if we call on_remove() when the mob is deleted
var/alert_type = /obj/screen/alert/status_effect //the alert thrown by the status effect, contains name and description
/datum/status_effect/New(mob/living/new_owner)
@@ -21,8 +22,9 @@
STOP_PROCESSING(SSfastprocess, src)
if(owner)
owner.clear_alert(id)
- on_remove()
LAZYREMOVE(owner.status_effects, src)
+ on_remove()
+ owner = null
return ..()
/datum/status_effect/proc/start_ticking()
@@ -52,8 +54,8 @@
/datum/status_effect/proc/on_apply() //Called whenever the buff is applied.
/datum/status_effect/proc/tick() //Called every tick.
-/datum/status_effect/proc/on_remove() //Called whenever the buff expires or is removed.
-/datum/status_effect/proc/be_replaced() //Called instead of on_remove when a status effect is replaced by itself
+/datum/status_effect/proc/on_remove() //Called whenever the buff expires or is removed; do note that at the point this is called, it is out of the owner's status_effects but owner is not yet null
+/datum/status_effect/proc/be_replaced() //Called instead of on_remove when a status effect is replaced by itself or when a status effect with on_remove_on_mob_delete = FALSE has its mob deleted
owner.clear_alert(id)
LAZYREMOVE(owner.status_effects, src)
owner = null
diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm
index f3e2de241f..137229db37 100644
--- a/code/game/area/areas.dm
+++ b/code/game/area/areas.dm
@@ -42,6 +42,7 @@
var/has_gravity = 0
var/noteleport = 0 //Are you forbidden from teleporting to the area? (centcomm, mobs, wizard, hand teleporter)
+ var/hidden = FALSE //Hides area from player Teleport function.
var/safe = 0 //Is the area teleport-safe: no space / radiation / aggresive mobs / other dangers
var/no_air = null
diff --git a/code/game/area/areas/holodeck.dm b/code/game/area/areas/holodeck.dm
index 21999a74a1..7bf213be52 100644
--- a/code/game/area/areas/holodeck.dm
+++ b/code/game/area/areas/holodeck.dm
@@ -3,6 +3,7 @@
icon_state = "Holodeck"
dynamic_lighting = DYNAMIC_LIGHTING_DISABLED
flags = 0
+ hidden = TRUE
var/obj/machinery/computer/holodeck/linked
var/restricted = 0 // if true, program goes on emag list
@@ -95,16 +96,15 @@
/area/holodeck/rec_center/kobayashi
name = "Holodeck - Kobayashi Maru"
+/area/holodeck/rec_center/winterwonderland
+ name = "Holodeck - Winter Wonderland"
+
// Bad programs
/area/holodeck/rec_center/burn
name = "Holodeck - Atmospheric Burn Test"
restricted = 1
-/area/holodeck/rec_center/winterwonderland
- name = "Holodeck - Winter Wonderland"
- restricted = 1
-
/area/holodeck/rec_center/wildlife
name = "Holodeck - Wildlife Simulation"
restricted = 1
diff --git a/code/game/area/areas/ruins.dm b/code/game/area/areas/ruins.dm
index d697c8436f..828d165dd8 100644
--- a/code/game/area/areas/ruins.dm
+++ b/code/game/area/areas/ruins.dm
@@ -4,6 +4,7 @@
name = "\improper Unexplored Location"
icon_state = "away"
has_gravity = 1
+ hidden = TRUE
/area/ruin/unpowered
diff --git a/code/game/atoms.dm b/code/game/atoms.dm
index fda74c2ac8..ab0038f7be 100644
--- a/code/game/atoms.dm
+++ b/code/game/atoms.dm
@@ -39,20 +39,21 @@
var/do_initialize = SSatoms.initialized
if(do_initialize > INITIALIZATION_INSSATOMS)
- if(QDELETED(src))
- CRASH("Found new qdeletion in type [type]!")
- var/mapload = do_initialize == INITIALIZATION_INNEW_MAPLOAD
- args[1] = mapload
- if(Initialize(arglist(args)) && mapload)
- LAZYADD(SSatoms.late_loaders, src)
+ args[1] = do_initialize == INITIALIZATION_INNEW_MAPLOAD
+ if(SSatoms.InitAtom(src, args))
+ //we were deleted
+ return
+
+ var/list/created = SSatoms.created_atoms
+ if(created)
+ created += src
//Called after New if the map is being loaded. mapload = TRUE
//Called from base of New if the map is being loaded. mapload = FALSE
-//This base must be called or derivatives must set initialized to TRUE to prevent repeat calls
-//Derivatives must not sleep
-//Returning TRUE while mapload is TRUE will cause the object to be initialized again with mapload = FALSE when everything else is done
-//(Useful for things that requires turfs to have air). This base may only be called once, however
+//This base must be called or derivatives must set initialized to TRUE
+//must not sleep
//Other parameters are passed from New (excluding loc), this does not happen if mapload is TRUE
+//Must return an Initialize hint. Defined in __DEFINES/subsystems.dm
//Note: the following functions don't call the base for optimization and must copypasta:
// /turf/Initialize
@@ -75,7 +76,16 @@
if (opacity && isturf(loc))
var/turf/T = loc
T.has_opaque_atom = TRUE // No need to recalculate it in this case, it's guaranteed to be on afterwards anyways.
+ return INITIALIZE_HINT_NORMAL
+//called if Initialize returns INITIALIZE_HINT_LATELOAD
+//This version shouldn't be called
+/atom/proc/LateInitialize()
+ var/static/list/warned_types = list()
+ if(!warned_types[type])
+ WARNING("Old style LateInitialize behaviour detected in [type]!")
+ warned_types[type] = TRUE
+ Initialize(FALSE)
/atom/Destroy()
if(alternate_appearances)
diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm
index 2d3d19f7c0..dc418cbf89 100644
--- a/code/game/atoms_movable.dm
+++ b/code/game/atoms_movable.dm
@@ -45,7 +45,7 @@
return ..()
/atom/movable/Initialize(mapload)
- ..()
+ . = ..()
for(var/L in initial_languages)
grant_language(L)
@@ -120,7 +120,7 @@
if(flags & CLEAN_ON_MOVE)
clean_on_move()
-
+
var/datum/proximity_monitor/proximity_monitor = src.proximity_monitor
if(proximity_monitor)
proximity_monitor.HandleMove()
@@ -562,7 +562,7 @@
return
else
var/turf/currentturf = get_turf(src)
- get(src, /mob) << "You can't help but feel that you just lost something back there..."
+ to_chat(get(src, /mob), "You can't help but feel that you just lost something back there...")
var/turf/targetturf = relocate()
log_game("[src] has been moved out of bounds in [COORD(currentturf)]. Moving it to [COORD(targetturf)].")
if(HAS_SECONDARY_FLAG(src, INFORM_ADMINS_ON_RELOCATE))
@@ -627,4 +627,4 @@
/atom/movable/proc/ConveyorMove(movedir)
set waitfor = FALSE
if(!anchored && has_gravity())
- step(src, movedir)
+ step(src, movedir)
diff --git a/code/game/gamemodes/blob/blob_finish.dm b/code/game/gamemodes/blob/blob_finish.dm
index a5fc5e339a..47e2ce6a14 100644
--- a/code/game/gamemodes/blob/blob_finish.dm
+++ b/code/game/gamemodes/blob/blob_finish.dm
@@ -20,7 +20,7 @@
if(round_converted) //So badmin blobs later don't step on the dead natural blobs metaphorical toes
..()
if(blobwincount <= GLOB.blobs_legit.len)
- feedback_set_details("round_end_result","win - blob took over")
+ SSblackbox.set_details("round_end_result","win - blob took over")
to_chat(world, "The blob has taken over the station!")
to_chat(world, "The entire station was eaten by the Blob!")
log_game("Blob mode completed with a blob victory.")
@@ -28,7 +28,7 @@
SSticker.news_report = BLOB_WIN
else if(station_was_nuked)
- feedback_set_details("round_end_result","halfwin - nuke")
+ SSblackbox.set_details("round_end_result","halfwin - nuke")
to_chat(world, "Partial Win: The station has been destroyed!")
to_chat(world, "Directive 7-12 has been successfully carried out, preventing the Blob from spreading.")
log_game("Blob mode completed with a tie (station destroyed).")
@@ -36,7 +36,7 @@
SSticker.news_report = BLOB_NUKE
else if(!GLOB.blob_cores.len)
- feedback_set_details("round_end_result","loss - blob eliminated")
+ SSblackbox.set_details("round_end_result","loss - blob eliminated")
to_chat(world, "The staff has won!")
to_chat(world, "The alien organism has been eradicated from the station!")
log_game("Blob mode completed with a crew victory.")
diff --git a/code/game/gamemodes/changeling/changeling.dm b/code/game/gamemodes/changeling/changeling.dm
index fc39f2222e..9d281b5f2f 100644
--- a/code/game/gamemodes/changeling/changeling.dm
+++ b/code/game/gamemodes/changeling/changeling.dm
@@ -254,19 +254,19 @@ GLOBAL_LIST_INIT(slot2type, list("head" = /obj/item/clothing/head/changeling, "w
for(var/datum/objective/objective in changeling.objectives)
if(objective.check_completion())
text += "
Objective #[count]: [objective.explanation_text] Success!"
- feedback_add_details("changeling_objective","[objective.type]|SUCCESS")
+ SSblackbox.add_details("changeling_objective","[objective.type]|SUCCESS")
else
text += "
Objective #[count]: [objective.explanation_text] Fail."
- feedback_add_details("changeling_objective","[objective.type]|FAIL")
+ SSblackbox.add_details("changeling_objective","[objective.type]|FAIL")
changelingwin = 0
count++
if(changelingwin)
text += "
The changeling was successful!"
- feedback_add_details("changeling_success","SUCCESS")
+ SSblackbox.add_details("changeling_success","SUCCESS")
else
text += "
The changeling has failed."
- feedback_add_details("changeling_success","FAIL")
+ SSblackbox.add_details("changeling_success","FAIL")
text += "
"
to_chat(world, text)
diff --git a/code/game/gamemodes/changeling/changeling_power.dm b/code/game/gamemodes/changeling/changeling_power.dm
index 1673e59f49..67eb216d58 100644
--- a/code/game/gamemodes/changeling/changeling_power.dm
+++ b/code/game/gamemodes/changeling/changeling_power.dm
@@ -21,7 +21,7 @@
/obj/effect/proc_holder/changeling/proc/on_purchase(mob/user, is_respec)
if(!is_respec)
- feedback_add_details("changeling_power_purchase",name)
+ SSblackbox.add_details("changeling_power_purchase",name)
/obj/effect/proc_holder/changeling/proc/on_refund(mob/user)
return
@@ -37,7 +37,7 @@
return
var/datum/changeling/c = user.mind.changeling
if(sting_action(user, target))
- feedback_add_details("changeling_powers",name)
+ SSblackbox.add_details("changeling_powers",name)
sting_feedback(user, target)
take_chemical_cost(c)
diff --git a/code/game/gamemodes/changeling/evolution_menu.dm b/code/game/gamemodes/changeling/evolution_menu.dm
index db1405537f..fdfec9e270 100644
--- a/code/game/gamemodes/changeling/evolution_menu.dm
+++ b/code/game/gamemodes/changeling/evolution_menu.dm
@@ -68,7 +68,7 @@
mind.changeling.purchasedpowers+=S
S.on_purchase(src, is_respec)
if(is_respec)
- feedback_add_details("changeling_power_purchase","Readapt")
+ SSblackbox.add_details("changeling_power_purchase","Readapt")
var/mob/living/carbon/C = src //only carbons have dna now, so we have to typecaste
if(ishuman(C))
diff --git a/code/game/gamemodes/changeling/powers/absorb.dm b/code/game/gamemodes/changeling/powers/absorb.dm
index 0f1fb93071..6a52ab9312 100644
--- a/code/game/gamemodes/changeling/powers/absorb.dm
+++ b/code/game/gamemodes/changeling/powers/absorb.dm
@@ -42,13 +42,13 @@
to_chat(target, "You feel a sharp stabbing pain!")
target.take_overall_damage(40)
- feedback_add_details("changeling_powers","Absorb DNA|[i]")
+ SSblackbox.add_details("changeling_powers","Absorb DNA|[i]")
if(!do_mob(user, target, 150))
to_chat(user, "Our absorption of [target] has been interrupted!")
changeling.isabsorbing = 0
return
- feedback_add_details("changeling_powers","Absorb DNA|4")
+ SSblackbox.add_details("changeling_powers","Absorb DNA|4")
user.visible_message("[user] sucks the fluids from [target]!", "We have absorbed [target].")
to_chat(target, "You are absorbed by the changeling!")
diff --git a/code/game/gamemodes/changeling/powers/linglink.dm b/code/game/gamemodes/changeling/powers/linglink.dm
index 5a64d551b5..fc4b91b650 100644
--- a/code/game/gamemodes/changeling/powers/linglink.dm
+++ b/code/game/gamemodes/changeling/powers/linglink.dm
@@ -56,7 +56,7 @@
to_chat(target, "You can now communicate in the changeling hivemind, say \":g message\" to communicate!")
target.reagents.add_reagent("salbutamol", 40) // So they don't choke to death while you interrogate them
sleep(1800)
- feedback_add_details("changeling_powers","Hivemind Link|[i]")
+ SSblackbox.add_details("changeling_powers","Hivemind Link|[i]")
if(!do_mob(user, target, 20))
to_chat(user, "Our link with [target] has ended!")
changeling.islinking = 0
diff --git a/code/game/gamemodes/clock_cult/clock_cult.dm b/code/game/gamemodes/clock_cult/clock_cult.dm
index 670e08e7a2..7fccb37d3c 100644
--- a/code/game/gamemodes/clock_cult/clock_cult.dm
+++ b/code/game/gamemodes/clock_cult/clock_cult.dm
@@ -46,7 +46,7 @@ Credit where due:
///////////
/proc/is_servant_of_ratvar(mob/living/M)
- return istype(M) && M.has_antag_datum(/datum/antagonist/clockcultist, TRUE)
+ return istype(M) && M.mind && M.mind.has_antag_datum(ANTAG_DATUM_CLOCKCULT)
/proc/is_eligible_servant(mob/living/M)
if(!istype(M))
@@ -65,17 +65,21 @@ Credit where due:
return FALSE
/proc/add_servant_of_ratvar(mob/living/L, silent = FALSE)
- var/update_type = /datum/antagonist/clockcultist
+ if(!L || !L.mind)
+ return
+ var/update_type = ANTAG_DATUM_CLOCKCULT
if(silent)
- update_type = /datum/antagonist/clockcultist/silent
- . = L.gain_antag_datum(update_type)
+ update_type = ANTAG_DATUM_CLOCKCULT_SILENT
+ . = L.mind.add_antag_datum(update_type)
/proc/remove_servant_of_ratvar(mob/living/L, silent = FALSE)
- var/datum/antagonist/clockcultist/clock_datum = L.has_antag_datum(/datum/antagonist/clockcultist, TRUE)
+ if(!L || !L.mind)
+ return
+ var/datum/antagonist/clockcult/clock_datum = L.mind.has_antag_datum(/datum/antagonist/clockcult)
if(!clock_datum)
return FALSE
- clock_datum.silent_update = silent
- clock_datum.on_remove()
+ clock_datum.silent = silent
+ clock_datum.on_removal()
return TRUE
///////////////
@@ -194,7 +198,7 @@ Credit where due:
var/datum/game_mode/clockwork_cult/C = SSticker.mode
if(C.check_clockwork_victory())
text += "Ratvar's servants have succeeded in fulfilling His goals!"
- feedback_set_details("round_end_result", "win - servants completed their objective (summon ratvar)")
+ SSblackbox.set_details("round_end_result", "win - servants completed their objective (summon ratvar)")
else
var/half_victory = FALSE
var/obj/structure/destructible/clockwork/massive/celestial_gateway/G = locate() in GLOB.all_clockwork_objects
@@ -203,10 +207,10 @@ Credit where due:
if(half_victory)
text += "The crew escaped before Ratvar could rise, but the gateway \
was successfully constructed!"
- feedback_set_details("round_end_result", "halfwin - servants constructed the gateway but their objective was not completed (summon ratvar)")
+ SSblackbox.set_details("round_end_result", "halfwin - servants constructed the gateway but their objective was not completed (summon ratvar)")
else
text += "Ratvar's servants have failed!"
- feedback_set_details("round_end_result", "loss - servants failed their objective (summon ratvar)")
+ SSblackbox.set_details("round_end_result", "loss - servants failed their objective (summon ratvar)")
text += "
The servants' objective was:
[CLOCKCULT_OBJECTIVE]"
text += "
Ratvar's servants had [GLOB.clockwork_caches] Tinkerer's Caches."
text += "
Construction Value(CV) was: [GLOB.clockwork_construction_value]"
diff --git a/code/game/gamemodes/clock_cult/clock_helpers/ratvarian_language.dm b/code/game/gamemodes/clock_cult/clock_helpers/ratvarian_language.dm
index fcb30a096d..a9727017d3 100644
--- a/code/game/gamemodes/clock_cult/clock_helpers/ratvarian_language.dm
+++ b/code/game/gamemodes/clock_cult/clock_helpers/ratvarian_language.dm
@@ -106,6 +106,6 @@ List of nuances:
if(!whisper)
L.say(message, "clock", spans, language=/datum/language/common)
else
- L.whisper(message)
+ L.whisper(message, "clock", spans, language=/datum/language/common)
else
AM.say(message, language=/datum/language/common)
diff --git a/code/game/gamemodes/clock_cult/clock_items/clockwork_slab.dm b/code/game/gamemodes/clock_cult/clock_items/clockwork_slab.dm
index 36ff67262b..35caabab5a 100644
--- a/code/game/gamemodes/clock_cult/clock_items/clockwork_slab.dm
+++ b/code/game/gamemodes/clock_cult/clock_items/clockwork_slab.dm
@@ -61,7 +61,7 @@
/obj/item/clockwork/slab/cyborg/medical //five scriptures, plus a spear
quickbound = list(/datum/clockwork_scripture/ranged_ability/linked_vanguard, /datum/clockwork_scripture/ranged_ability/sentinels_compromise, \
- /datum/clockwork_scripture/create_object/vitality_matrix, /datum/clockwork_scripture/fellowship_armory, /datum/clockwork_scripture/create_object/mending_motor)
+ /datum/clockwork_scripture/create_object/vitality_matrix, /datum/clockwork_scripture/channeled/mending_mantra, /datum/clockwork_scripture/fellowship_armory)
/obj/item/clockwork/slab/cyborg/security //four scriptures, plus a spear
quickbound = list(/datum/clockwork_scripture/channeled/belligerent, /datum/clockwork_scripture/ranged_ability/judicial_marker, /datum/clockwork_scripture/channeled/taunting_tirade, \
diff --git a/code/game/gamemodes/clock_cult/clock_scripture.dm b/code/game/gamemodes/clock_cult/clock_scripture.dm
index 8e688f30aa..e8f1e8dbbc 100644
--- a/code/game/gamemodes/clock_cult/clock_scripture.dm
+++ b/code/game/gamemodes/clock_cult/clock_scripture.dm
@@ -86,7 +86,7 @@ Judgement: 12 servants, 5 caches, 300 CV, and any existing AIs are converted or
else
successful = TRUE
if(slab && !slab.no_cost && !GLOB.ratvar_awakens) //if the slab exists and isn't debug and ratvar isn't up, log the scripture as being used
- feedback_add_details("clockcult_scripture_recited", name)
+ SSblackbox.add_details("clockcult_scripture_recited", name)
if(slab)
slab.busy = null
qdel(src)
diff --git a/code/game/gamemodes/clock_cult/clock_scriptures/scripture_applications.dm b/code/game/gamemodes/clock_cult/clock_scriptures/scripture_applications.dm
index efc479f522..25576f5710 100644
--- a/code/game/gamemodes/clock_cult/clock_scriptures/scripture_applications.dm
+++ b/code/game/gamemodes/clock_cult/clock_scriptures/scripture_applications.dm
@@ -214,28 +214,6 @@
quickbind_desc = "Creates an Interdiction Lens, which drains power into nearby Sigils of Transmission."
-//Mending Motor: Creates a prism that will quickly heal mechanical servants/clockwork structures at a power cost
-/datum/clockwork_scripture/create_object/mending_motor
- descname = "Powered Structure, Repairs Other Structures"
- name = "Mending Motor"
- desc = "Creates a mechanized prism that will rapidly repair damaged clockwork constructs, converted cyborgs, and clockwork structures."
- invocations = list("May this prism...", "...mend our dents and scratches!")
- channel_time = 80
- consumed_components = list(VANGUARD_COGWHEEL = 3, GEIS_CAPACITOR = 1, REPLICANT_ALLOY = 1)
- object_path = /obj/structure/destructible/clockwork/powered/mending_motor
- creator_message = "You form a mending motor, which will rapidly repair damaged clockwork constructs, converted cyborgs, and clockwork structures."
- observer_message = "An onyx prism forms in midair and sprouts tendrils to support itself!"
- invokers_required = 2
- multiple_invokers_used = TRUE
- usage_tip = "Powerful healing but power use is somewhat inefficient, though much better than a proselytizer."
- tier = SCRIPTURE_APPLICATION
- one_per_tile = TRUE
- primary_component = VANGUARD_COGWHEEL
- sort_priority = 7
- quickbind = TRUE
- quickbind_desc = "Creates a Mending Motor, which rapidly repairs constructs and structures at a power cost."
-
-
//Mania Motor: Creates a malevolent transmitter that will broadcast the whispers of Sevtug into the minds of nearby nonservants, causing a variety of mental effects at a power cost.
/datum/clockwork_scripture/create_object/mania_motor
descname = "Powered Structure, Area Denial"
diff --git a/code/game/gamemodes/clock_cult/clock_scriptures/scripture_revenant.dm b/code/game/gamemodes/clock_cult/clock_scriptures/scripture_revenant.dm
index faab84befe..0dbd2d46e8 100644
--- a/code/game/gamemodes/clock_cult/clock_scriptures/scripture_revenant.dm
+++ b/code/game/gamemodes/clock_cult/clock_scriptures/scripture_revenant.dm
@@ -110,7 +110,7 @@
channel_time = 150
consumed_components = list(BELLIGERENT_EYE = 3, VANGUARD_COGWHEEL = 3, GEIS_CAPACITOR = 3, REPLICANT_ALLOY = 6)
usage_tip = "Ocular wardens will become empowered, clockwork proselytizers will require no alloy, tinkerer's daemons will produce twice as quickly, \
- and interdiction lenses, mending motors, mania motors, tinkerer's daemons, and clockwork obelisks will all require no power."
+ and interdiction lenses, mania motors, tinkerer's daemons, and clockwork obelisks will all require no power."
tier = SCRIPTURE_REVENANT
primary_component = REPLICANT_ALLOY
sort_priority = 4
diff --git a/code/game/gamemodes/clock_cult/clock_scriptures/scripture_scripts.dm b/code/game/gamemodes/clock_cult/clock_scriptures/scripture_scripts.dm
index 4fd4e629a1..f7fcc8c299 100644
--- a/code/game/gamemodes/clock_cult/clock_scriptures/scripture_scripts.dm
+++ b/code/game/gamemodes/clock_cult/clock_scriptures/scripture_scripts.dm
@@ -69,6 +69,117 @@
quickbind_desc = "Creates a Vitality Matrix, which drains non-Servants on it to heal Servants that cross it."
+//Mending Mantra: Channeled for up to ten times over twenty seconds to repair structures and heal allies
+/datum/clockwork_scripture/channeled/mending_mantra
+ descname = "Channeled, Area Healing and Repair"
+ name = "Mending Mantra"
+ desc = "Repairs nearby structures and constructs. Servants wearing clockwork armor will also be healed. Channeled every two seconds for a maximum of twenty seconds."
+ chant_invocations = list("Mend our dents!", "Heal our scratches!", "Repair our gears!")
+ chant_amount = 10
+ chant_interval = 20
+ consumed_components = list(VANGUARD_COGWHEEL = 1, REPLICANT_ALLOY = 1)
+ usage_tip = "This is a very effective way to rapidly reinforce a base after an attack."
+ tier = SCRIPTURE_SCRIPT
+ primary_component = VANGUARD_COGWHEEL
+ sort_priority = 4
+ quickbind = TRUE
+ quickbind_desc = "Repairs nearby structures and constructs. Servants wearing clockwork armor will also be healed.
Maximum 10 chants."
+ var/heal_attempts = 4
+ var/heal_amount = 2.5
+ var/static/list/damage_heal_order = list(BRUTE, BURN, OXY)
+ var/static/list/heal_finish_messages = list("There, all mended!", "Try not to get too damaged.", "No more dents and scratches for you!", "Champions never die.", "All patched up.", \
+ "Ah, child, it's okay now.", "Pain is temporary.", "What you do for the Justiciar is eternal.", "Bear this for me.", "Be strong, child.", "Please, be careful!", \
+ "If you die, you will be remembered.")
+ var/static/list/heal_target_typecache = typecacheof(list(
+ /obj/structure/destructible/clockwork,
+ /obj/machinery/door/airlock/clockwork,
+ /obj/machinery/door/window/clockwork,
+ /obj/structure/window/reinforced/clockwork,
+ /obj/structure/table/reinforced/brass))
+ var/static/list/ratvarian_armor_typecache = typecacheof(list(
+ /obj/item/clothing/suit/armor/clockwork,
+ /obj/item/clothing/head/helmet/clockwork,
+ /obj/item/clothing/gloves/clockwork,
+ /obj/item/clothing/shoes/clockwork))
+
+/datum/clockwork_scripture/channeled/mending_mantra/chant_effects(chant_number)
+ var/turf/T
+ for(var/atom/movable/M in range(7, invoker))
+ if(isliving(M))
+ if(isclockmob(M) || istype(M, /mob/living/simple_animal/drone/cogscarab))
+ var/mob/living/simple_animal/S = M
+ if(S.health == S.maxHealth || S.stat == DEAD)
+ continue
+ T = get_turf(M)
+ for(var/i in 1 to heal_attempts)
+ if(S.health < S.maxHealth)
+ S.adjustHealth(-heal_amount)
+ new /obj/effect/overlay/temp/heal(T, "#1E8CE1")
+ if(i == heal_attempts && S.health >= S.maxHealth) //we finished healing on the last tick, give them the message
+ to_chat(S, "\"[text2ratvar(pick(heal_finish_messages))]\"")
+ break
+ else
+ to_chat(S, "\"[text2ratvar(pick(heal_finish_messages))]\"")
+ break
+ else if(issilicon(M))
+ var/mob/living/silicon/S = M
+ if(S.health == S.maxHealth || S.stat == DEAD || !is_servant_of_ratvar(S))
+ continue
+ T = get_turf(M)
+ for(var/i in 1 to heal_attempts)
+ if(S.health < S.maxHealth)
+ S.heal_ordered_damage(heal_amount, damage_heal_order)
+ new /obj/effect/overlay/temp/heal(T, "#1E8CE1")
+ if(i == heal_attempts && S.health >= S.maxHealth)
+ to_chat(S, "\"[text2ratvar(pick(heal_finish_messages))]\"")
+ break
+ else
+ to_chat(S, "\"[text2ratvar(pick(heal_finish_messages))]\"")
+ break
+ else if(ishuman(M))
+ var/mob/living/carbon/human/H = M
+ if(H.health == H.maxHealth || H.stat == DEAD || !is_servant_of_ratvar(H))
+ continue
+ T = get_turf(M)
+ var/heal_ticks = 0 //one heal tick for each piece of ratvarian armor worn
+ var/obj/item/I = H.get_item_by_slot(slot_wear_suit)
+ if(is_type_in_typecache(I, ratvarian_armor_typecache))
+ heal_ticks++
+ I = H.get_item_by_slot(slot_head)
+ if(is_type_in_typecache(I, ratvarian_armor_typecache))
+ heal_ticks++
+ I = H.get_item_by_slot(slot_gloves)
+ if(is_type_in_typecache(I, ratvarian_armor_typecache))
+ heal_ticks++
+ I = H.get_item_by_slot(slot_shoes)
+ if(is_type_in_typecache(I, ratvarian_armor_typecache))
+ heal_ticks++
+ if(heal_ticks)
+ for(var/i in 1 to heal_ticks)
+ if(H.health < H.maxHealth)
+ H.heal_ordered_damage(heal_amount, damage_heal_order)
+ new /obj/effect/overlay/temp/heal(T, "#1E8CE1")
+ if(i == heal_ticks && H.health >= H.maxHealth)
+ to_chat(H, "\"[text2ratvar(pick(heal_finish_messages))]\"")
+ break
+ else
+ to_chat(H, "\"[text2ratvar(pick(heal_finish_messages))]\"")
+ break
+ else if(is_type_in_typecache(M, heal_target_typecache))
+ var/obj/structure/destructible/clockwork/C = M
+ if(C.obj_integrity == C.max_integrity || (istype(C) && !C.can_be_repaired))
+ continue
+ T = get_turf(M)
+ for(var/i in 1 to heal_attempts)
+ if(C.obj_integrity < C.max_integrity)
+ C.obj_integrity = min(C.obj_integrity + 5, C.max_integrity)
+ C.update_icon()
+ new /obj/effect/overlay/temp/heal(T, "#1E8CE1")
+ else
+ break
+ return TRUE
+
+
//Sigil of Submission: Creates a sigil of submission, which converts one heretic above it after a delay.
/datum/clockwork_scripture/create_object/sigil_of_submission
descname = "Trap, Conversion"
diff --git a/code/game/gamemodes/clock_cult/clock_structures/mending_motor.dm b/code/game/gamemodes/clock_cult/clock_structures/mending_motor.dm
deleted file mode 100644
index 6bd0f46e9d..0000000000
--- a/code/game/gamemodes/clock_cult/clock_structures/mending_motor.dm
+++ /dev/null
@@ -1,107 +0,0 @@
-//Mending Motor: A prism that consumes replicant alloy or power to repair nearby mechanical servants at a quick rate.
-/obj/structure/destructible/clockwork/powered/mending_motor
- name = "mending motor"
- desc = "A dark onyx prism, held in midair by spiraling tendrils of stone."
- clockwork_desc = "A powerful prism that rapidly repairs nearby mechanical servants and clockwork structures."
- icon_state = "mending_motor_inactive"
- active_icon = "mending_motor"
- inactive_icon = "mending_motor_inactive"
- unanchored_icon = "mending_motor_unwrenched"
- construction_value = 20
- max_integrity = 125
- obj_integrity = 125
- break_message = "The prism falls to the ground with a heavy thud!"
- debris = list(/obj/item/clockwork/alloy_shards/small = 3, \
- /obj/item/clockwork/alloy_shards/medium = 1, \
- /obj/item/clockwork/alloy_shards/large = 1, \
- /obj/item/clockwork/component/vanguard_cogwheel/onyx_prism = 1)
- var/heal_attempts = 4
- var/heal_cost = MIN_CLOCKCULT_POWER*2
- var/static/list/damage_heal_order = list(BRUTE, BURN, OXY)
- var/static/list/heal_finish_messages = list("There, all mended!", "Try not to get too damaged.", "No more dents and scratches for you!", "Champions never die.", "All patched up.", \
- "Ah, child, it's okay now.")
- var/static/list/heal_failure_messages = list("Pain is temporary.", "What you do for the Justiciar is eternal.", "Bear this for me.", "Be strong, child.", "Please, be careful!", \
- "If you die, you will be remembered.")
- var/static/list/mending_motor_typecache = typecacheof(list(
- /obj/structure/destructible/clockwork,
- /obj/machinery/door/airlock/clockwork,
- /obj/machinery/door/window/clockwork,
- /obj/structure/window/reinforced/clockwork,
- /obj/structure/table/reinforced/brass))
-
-/obj/structure/destructible/clockwork/powered/mending_motor/examine(mob/user)
- ..()
- if(is_servant_of_ratvar(user) || isobserver(user))
- to_chat(user, "It requires at least [heal_cost]W to attempt to repair clockwork mobs, structures, or converted silicons.")
-
-/obj/structure/destructible/clockwork/powered/mending_motor/forced_disable(bad_effects)
- if(active)
- if(bad_effects)
- try_use_power(heal_cost)
- visible_message("[src] emits an airy chuckling sound and falls dark!")
- toggle()
- return TRUE
-
-/obj/structure/destructible/clockwork/powered/mending_motor/attack_hand(mob/living/user)
- if(user.canUseTopic(src, !issilicon(user), NO_DEXTERY) && is_servant_of_ratvar(user))
- if(total_accessable_power() < MIN_CLOCKCULT_POWER)
- to_chat(user, "[src] needs more power to function!")
- return 0
- toggle(0, user)
-
-/obj/structure/destructible/clockwork/powered/mending_motor/process()
- var/efficiency = get_efficiency_mod()
- for(var/atom/movable/M in range(7, src))
- var/turf/T
- if(isclockmob(M) || istype(M, /mob/living/simple_animal/drone/cogscarab))
- T = get_turf(M)
- var/mob/living/simple_animal/S = M
- if(S.health == S.maxHealth || S.stat == DEAD)
- continue
- for(var/i in 1 to heal_attempts)
- if(S.health < S.maxHealth)
- if(try_use_power(heal_cost))
- S.adjustHealth(-(8 * efficiency))
- new /obj/effect/overlay/temp/heal(T, "#1E8CE1")
- else
- to_chat(S, "\"[text2ratvar(pick(heal_failure_messages))]\"")
- break
- else
- to_chat(S, "\"[text2ratvar(pick(heal_finish_messages))]\"")
- break
- else if(is_type_in_typecache(M, mending_motor_typecache))
- T = get_turf(M)
- var/obj/structure/destructible/clockwork/C = M
- if(C.obj_integrity == C.max_integrity || (istype(C) && !C.can_be_repaired))
- continue
- for(var/i in 1 to heal_attempts)
- if(C.obj_integrity < C.max_integrity)
- if(try_use_power(heal_cost))
- C.obj_integrity = min(C.obj_integrity + (8 * efficiency), C.max_integrity)
- if(C == src)
- efficiency = get_efficiency_mod()
- C.update_icon()
- new /obj/effect/overlay/temp/heal(T, "#1E8CE1")
- else
- break
- else
- break
- else if(issilicon(M))
- T = get_turf(M)
- var/mob/living/silicon/S = M
- if(S.health == S.maxHealth || S.stat == DEAD || !is_servant_of_ratvar(S))
- continue
- for(var/i in 1 to heal_attempts)
- if(S.health < S.maxHealth)
- if(try_use_power(heal_cost))
- S.heal_ordered_damage(8 * efficiency, damage_heal_order)
- new /obj/effect/overlay/temp/heal(T, "#1E8CE1")
- else
- to_chat(S, "\"[text2ratvar(pick(heal_failure_messages))]\"")
- break
- else
- to_chat(S, "\"[text2ratvar(pick(heal_finish_messages))]\"")
- break
- . = ..()
- if(. < heal_cost)
- forced_disable(FALSE)
diff --git a/code/game/gamemodes/clock_cult/clock_structures/ratvar_the_clockwork_justicar.dm b/code/game/gamemodes/clock_cult/clock_structures/ratvar_the_clockwork_justicar.dm
index 9b2d868730..614a22a6f5 100644
--- a/code/game/gamemodes/clock_cult/clock_structures/ratvar_the_clockwork_justicar.dm
+++ b/code/game/gamemodes/clock_cult/clock_structures/ratvar_the_clockwork_justicar.dm
@@ -40,8 +40,8 @@
/obj/structure/destructible/clockwork/massive/ratvar/attack_ghost(mob/dead/observer/O)
var/alertresult = alert(O, "Embrace the Justiciar's light? You can no longer be cloned!",,"Yes", "No")
- if(alertresult == "No" || !O)
- return 0
+ if(alertresult == "No" || QDELETED(O) || !istype(O) || !O.key)
+ return FALSE
var/mob/living/simple_animal/drone/cogscarab/ratvar/R = new/mob/living/simple_animal/drone/cogscarab/ratvar(get_turf(src))
R.visible_message("[R] forms, and its eyes blink open, glowing bright red!")
R.key = O.key
diff --git a/code/game/gamemodes/cult/cult.dm b/code/game/gamemodes/cult/cult.dm
index 65dcb863eb..7780ae5db9 100644
--- a/code/game/gamemodes/cult/cult.dm
+++ b/code/game/gamemodes/cult/cult.dm
@@ -5,7 +5,7 @@
var/list/cult_objectives = list()
/proc/iscultist(mob/living/M)
- return istype(M) && M.has_antag_datum(/datum/antagonist/cultist, TRUE)
+ return istype(M) && M.mind && M.mind.has_antag_datum(ANTAG_DATUM_CULT)
/proc/is_sacrifice_target(datum/mind/mind)
if(SSticker.mode.name == "cult")
@@ -158,18 +158,18 @@
/datum/game_mode/proc/add_cultist(datum/mind/cult_mind, stun) //BASE
if (!istype(cult_mind))
return 0
- if(cult_mind.current.gain_antag_datum(/datum/antagonist/cultist))
+ if(cult_mind.add_antag_datum(ANTAG_DATUM_CULT))
if(stun)
cult_mind.current.Paralyse(5)
return 1
/datum/game_mode/proc/remove_cultist(datum/mind/cult_mind, show_message = 1, stun)
if(cult_mind.current)
- var/datum/antagonist/cultist/cult_datum = cult_mind.current.has_antag_datum(/datum/antagonist/cultist, TRUE)
+ var/datum/antagonist/cult/cult_datum = cult_mind.has_antag_datum(ANTAG_DATUM_CULT)
if(!cult_datum)
return FALSE
- cult_datum.silent_update = show_message
- cult_datum.on_remove()
+ cult_datum.silent = show_message
+ cult_datum.on_removal()
if(stun)
cult_mind.current.Paralyse(5)
return TRUE
@@ -218,12 +218,12 @@
/datum/game_mode/cult/declare_completion()
if(!check_cult_victory())
- feedback_set_details("round_end_result","win - cult win")
- feedback_set("round_end_result",acolytes_survived)
+ SSblackbox.set_details("round_end_result","win - cult win")
+ SSblackbox.set_val("round_end_result",acolytes_survived)
to_chat(world, "The cult has succeeded! Nar-sie has snuffed out another torch in the void!")
else
- feedback_set_details("round_end_result","loss - staff stopped the cult")
- feedback_set("round_end_result",acolytes_survived)
+ SSblackbox.set_details("round_end_result","loss - staff stopped the cult")
+ SSblackbox.set_val("round_end_result",acolytes_survived)
to_chat(world, "The staff managed to stop the cult! Dark words and heresy are no match for Nanotrasen's finest!")
var/text = ""
@@ -236,31 +236,31 @@
if("survive")
if(!check_survive())
explanation = "Make sure at least [acolytes_needed] acolytes escape on the shuttle. ([acolytes_survived] escaped) Success!"
- feedback_add_details("cult_objective","cult_survive|SUCCESS|[acolytes_needed]")
+ SSblackbox.add_details("cult_objective","cult_survive|SUCCESS|[acolytes_needed]")
SSticker.news_report = CULT_ESCAPE
else
explanation = "Make sure at least [acolytes_needed] acolytes escape on the shuttle. ([acolytes_survived] escaped) Fail."
- feedback_add_details("cult_objective","cult_survive|FAIL|[acolytes_needed]")
+ SSblackbox.add_details("cult_objective","cult_survive|FAIL|[acolytes_needed]")
SSticker.news_report = CULT_FAILURE
if("sacrifice")
if(sacrifice_target)
if(sacrifice_target in GLOB.sacrificed)
explanation = "Sacrifice [sacrifice_target.name], the [sacrifice_target.assigned_role]. Success!"
- feedback_add_details("cult_objective","cult_sacrifice|SUCCESS")
+ SSblackbox.add_details("cult_objective","cult_sacrifice|SUCCESS")
else if(sacrifice_target && sacrifice_target.current)
explanation = "Sacrifice [sacrifice_target.name], the [sacrifice_target.assigned_role]. Fail."
- feedback_add_details("cult_objective","cult_sacrifice|FAIL")
+ SSblackbox.add_details("cult_objective","cult_sacrifice|FAIL")
else
explanation = "Sacrifice [sacrifice_target.name], the [sacrifice_target.assigned_role]. Fail (Gibbed)."
- feedback_add_details("cult_objective","cult_sacrifice|FAIL|GIBBED")
+ SSblackbox.add_details("cult_objective","cult_sacrifice|FAIL|GIBBED")
if("eldergod")
if(!eldergod)
explanation = "Summon Nar-Sie. Success!"
- feedback_add_details("cult_objective","cult_narsie|SUCCESS")
+ SSblackbox.add_details("cult_objective","cult_narsie|SUCCESS")
SSticker.news_report = CULT_SUMMON
else
explanation = "Summon Nar-Sie. Fail."
- feedback_add_details("cult_objective","cult_narsie|FAIL")
+ SSblackbox.add_details("cult_objective","cult_narsie|FAIL")
SSticker.news_report = CULT_FAILURE
text += "
Objective #[obj_count]: [explanation]"
diff --git a/code/game/gamemodes/cult/ritual.dm b/code/game/gamemodes/cult/ritual.dm
index 2ed6840c91..843d16592a 100644
--- a/code/game/gamemodes/cult/ritual.dm
+++ b/code/game/gamemodes/cult/ritual.dm
@@ -247,7 +247,7 @@ This file contains the arcane tome files.
var/obj/effect/rune/R = new rune_to_scribe(Turf, chosen_keyword)
R.add_mob_blood(user)
to_chat(user, "The [lowertext(R.cultist_name)] rune [R.cultist_desc]")
- feedback_add_details("cult_runes_scribed", R.cultist_name)
+ SSblackbox.add_details("cult_runes_scribed", R.cultist_name)
/obj/item/weapon/tome/proc/check_rune_turf(turf/T, mob/user)
var/area/A = get_area(T)
diff --git a/code/game/gamemodes/devil/devilinfo.dm b/code/game/gamemodes/devil/devilinfo.dm
index ef9091891f..01437cdf2e 100644
--- a/code/game/gamemodes/devil/devilinfo.dm
+++ b/code/game/gamemodes/devil/devilinfo.dm
@@ -287,7 +287,7 @@ GLOBAL_LIST_INIT(lawlorify, list (
notify_ghosts("An arch devil has ascended in \the [A.name]. Reach out to the devil to be given a new shell for your soul.", source = owner.current, action=NOTIFY_ATTACK)
sleep(50)
if(!SSticker.mode.devil_ascended)
- SSshuttle.emergency.request(null, 0.3)
+ SSshuttle.emergency.request(null, set_coefficient = 0.3)
SSticker.mode.devil_ascended++
form = ARCH_DEVIL
@@ -449,7 +449,7 @@ GLOBAL_LIST_INIT(lawlorify, list (
A.convert_to_archdevil()
else
throw EXCEPTION("Unable to find a blobstart landmark for hellish resurrection")
-
+
/datum/devilinfo/proc/update_hud()
if(istype(owner.current, /mob/living/carbon))
diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm
index 2564d1b262..a496715af2 100644
--- a/code/game/gamemodes/game_mode.dm
+++ b/code/game/gamemodes/game_mode.dm
@@ -80,12 +80,12 @@
report = config.intercept
addtimer(CALLBACK(GLOBAL_PROC, .proc/display_roundstart_logout_report), ROUNDSTART_LOGOUT_REPORT_TIME)
- feedback_set_details("round_start","[time2text(world.realtime)]")
+ SSblackbox.set_details("round_start","[time2text(world.realtime)]")
if(SSticker && SSticker.mode)
- feedback_set_details("game_mode","[SSticker.mode]")
+ SSblackbox.set_details("game_mode","[SSticker.mode]")
if(GLOB.revdata.commit)
- feedback_set_details("revision","[GLOB.revdata.commit]")
- feedback_set_details("server_ip","[world.internet_address]:[world.port]")
+ SSblackbox.set_details("revision","[GLOB.revdata.commit]")
+ SSblackbox.set_details("server_ip","[world.internet_address]:[world.port]")
if(report)
addtimer(CALLBACK(src, .proc/send_intercept, 0), rand(waittime_l, waittime_h))
generate_station_goals()
@@ -246,17 +246,17 @@
ghosts++
if(clients > 0)
- feedback_set("round_end_clients",clients)
+ SSblackbox.set_val("round_end_clients",clients)
if(ghosts > 0)
- feedback_set("round_end_ghosts",ghosts)
+ SSblackbox.set_val("round_end_ghosts",ghosts)
if(surviving_humans > 0)
- feedback_set("survived_human",surviving_humans)
+ SSblackbox.set_val("survived_human",surviving_humans)
if(surviving_total > 0)
- feedback_set("survived_total",surviving_total)
+ SSblackbox.set_val("survived_total",surviving_total)
if(escaped_humans > 0)
- feedback_set("escaped_human",escaped_humans)
+ SSblackbox.set_val("escaped_human",escaped_humans)
if(escaped_total > 0)
- feedback_set("escaped_total",escaped_total)
+ SSblackbox.set_val("escaped_total",escaped_total)
send2irc("Server", "Round just ended.")
return 0
diff --git a/code/game/gamemodes/game_mode.dm.rej b/code/game/gamemodes/game_mode.dm.rej
new file mode 100644
index 0000000000..2ee380eecf
--- /dev/null
+++ b/code/game/gamemodes/game_mode.dm.rej
@@ -0,0 +1,18 @@
+diff a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm (rejected hunks)
+@@ -81,12 +81,12 @@
+ spawn (ROUNDSTART_LOGOUT_REPORT_TIME)
+ display_roundstart_logout_report()
+
+- feedback_set_details("round_start","[time2text(world.realtime)]")
++ SSblackbox.set_details("round_start","[time2text(world.realtime)]")
+ if(SSticker && SSticker.mode)
+- feedback_set_details("game_mode","[SSticker.mode]")
++ SSblackbox.set_details("game_mode","[SSticker.mode]")
+ if(GLOB.revdata.commit)
+- feedback_set_details("revision","[GLOB.revdata.commit]")
+- feedback_set_details("server_ip","[world.internet_address]:[world.port]")
++ SSblackbox.set_details("revision","[GLOB.revdata.commit]")
++ SSblackbox.set_details("server_ip","[world.internet_address]:[world.port]")
+ if(report)
+ spawn (rand(waittime_l, waittime_h))
+ send_intercept(0)
diff --git a/code/game/gamemodes/gang/gang.dm b/code/game/gamemodes/gang/gang.dm
index 22ca4b2298..9c31edf55f 100644
--- a/code/game/gamemodes/gang/gang.dm
+++ b/code/game/gamemodes/gang/gang.dm
@@ -260,12 +260,12 @@ GLOBAL_LIST_INIT(gang_colors_pool, list("red","orange","yellow","green","blue","
return
if(!winner)
to_chat(world, "The station was [station_was_nuked ? "destroyed!" : "evacuated before a gang could claim it! The station wins!"]
")
- feedback_set_details("round_end_result","loss - gangs failed takeover")
+ SSblackbox.set_details("round_end_result","loss - gangs failed takeover")
SSticker.news_report = GANG_LOSS
else
to_chat(world, "The [winner.name] Gang successfully performed a hostile takeover of the station!
")
- feedback_set_details("round_end_result","win - gang domination complete")
+ SSblackbox.set_details("round_end_result","win - gang domination complete")
SSticker.news_report = GANG_TAKEOVER
diff --git a/code/game/gamemodes/gang/gang_pen.dm b/code/game/gamemodes/gang/gang_pen.dm
index 0e01532190..621d40cc45 100644
--- a/code/game/gamemodes/gang/gang_pen.dm
+++ b/code/game/gamemodes/gang/gang_pen.dm
@@ -11,7 +11,7 @@
..()
last_used = world.time
-/obj/item/weapon/pen/gang/attack(mob/living/M, mob/user)
+/obj/item/weapon/pen/gang/attack(mob/living/M, mob/user, stealth = TRUE)
if(!istype(M))
return
if(ishuman(M) && ishuman(user) && M.stat != DEAD)
diff --git a/code/game/gamemodes/malfunction/Malf_Modules.dm b/code/game/gamemodes/malfunction/Malf_Modules.dm
index a7c466e746..4f09f2e362 100644
--- a/code/game/gamemodes/malfunction/Malf_Modules.dm
+++ b/code/game/gamemodes/malfunction/Malf_Modules.dm
@@ -556,7 +556,7 @@
var/mob/living/silicon/ai/A = usr
if(A.stat == DEAD)
- A <<"You are already dead!" //Omae Wa Mou Shindeiru
+ to_chat(A, "You are already dead!") //Omae Wa Mou Shindeiru
return
for(var/datum/AI_Module/AM in possible_modules)
diff --git a/code/game/gamemodes/meteor/meteor.dm b/code/game/gamemodes/meteor/meteor.dm
index e1a2ddf78f..400b38309b 100644
--- a/code/game/gamemodes/meteor/meteor.dm
+++ b/code/game/gamemodes/meteor/meteor.dm
@@ -50,8 +50,8 @@
else
to_chat(world, "Nobody survived the meteor storm!")
- feedback_set_details("round_end_result","end - evacuation")
- feedback_set("round_end_result",survivors)
+ SSblackbox.set_details("round_end_result","end - evacuation")
+ SSblackbox.set_val("round_end_result",survivors)
..()
return 1
diff --git a/code/game/gamemodes/miniantags/abduction/abduction.dm b/code/game/gamemodes/miniantags/abduction/abduction.dm
index e692654bf3..0e4a11f8ab 100644
--- a/code/game/gamemodes/miniantags/abduction/abduction.dm
+++ b/code/game/gamemodes/miniantags/abduction/abduction.dm
@@ -166,7 +166,7 @@
var/obj/machinery/abductor/console/con = get_team_console(team_number)
var/datum/objective/objective = team_objectives[team_number]
if (con.experiment.points >= objective.target_amount)
- SSshuttle.emergency.request(null, 0.5)
+ SSshuttle.emergency.request(null, set_coefficient = 0.5)
finished = 1
return ..()
return ..()
diff --git a/code/game/gamemodes/miniantags/abduction/abduction_gear.dm b/code/game/gamemodes/miniantags/abduction/abduction_gear.dm
index e6365d5e65..d7ab46cb9c 100644
--- a/code/game/gamemodes/miniantags/abduction/abduction_gear.dm
+++ b/code/game/gamemodes/miniantags/abduction/abduction_gear.dm
@@ -14,6 +14,13 @@
origin_tech = "magnets=7;biotech=4;powerstorage=4;abductor=4"
armor = list(melee = 15, bullet = 15, laser = 15, energy = 15, bomb = 15, bio = 15, rad = 15, fire = 70, acid = 70)
actions_types = list(/datum/action/item_action/hands_free/activate)
+ allowed = list(
+ /obj/item/device/abductor,
+ /obj/item/weapon/abductor_baton,
+ /obj/item/weapon/melee/baton,
+ /obj/item/weapon/gun/energy,
+ /obj/item/weapon/restraints/handcuffs
+ )
var/mode = VEST_STEALTH
var/stealth_active = 0
var/combat_cooldown = 10
@@ -21,6 +28,11 @@
var/stealth_armor = list(melee = 15, bullet = 15, laser = 15, energy = 15, bomb = 15, bio = 15, rad = 15, fire = 70, acid = 70)
var/combat_armor = list(melee = 50, bullet = 50, laser = 50, energy = 50, bomb = 50, bio = 50, rad = 50, fire = 90, acid = 90)
+/obj/item/clothing/suit/armor/abductor/vest/proc/toggle_nodrop()
+ flags ^= NODROP
+ if(ismob(loc))
+ to_chat(loc, "Your vest is now [flags & NODROP ? "locked" : "unlocked"].")
+
/obj/item/clothing/suit/armor/abductor/vest/proc/flip_mode()
switch(mode)
if(VEST_STEALTH)
@@ -107,6 +119,18 @@
if(combat_cooldown==initial(combat_cooldown))
STOP_PROCESSING(SSobj, src)
+/obj/item/clothing/suit/armor/abductor/Destroy()
+ STOP_PROCESSING(SSobj, src)
+ for(var/obj/machinery/abductor/console/C in GLOB.machines)
+ if(C.vest == src)
+ C.vest = null
+ break
+ . = ..()
+
+
+/obj/item/device/abductor
+ icon = 'icons/obj/abductor.dmi'
+
/obj/item/device/abductor/proc/AbductorCheck(user)
if(isabductor(user))
return TRUE
@@ -114,14 +138,19 @@
return FALSE
/obj/item/device/abductor/proc/ScientistCheck(user)
+ if(!AbductorCheck(user))
+ return FALSE
+
var/mob/living/carbon/human/H = user
var/datum/species/abductor/S = H.dna.species
- return S.scientist
+ if(S.scientist)
+ return TRUE
+ to_chat(user, "You're not trained to use this!")
+ return FALSE
/obj/item/device/abductor/gizmo
name = "science tool"
desc = "A dual-mode tool for retrieving specimens and scanning appearances. Scanning can be done through cameras."
- icon = 'icons/obj/abductor.dmi'
icon_state = "gizmo_scan"
item_state = "silencer"
origin_tech = "engineering=7;magnets=4;bluespace=4;abductor=3"
@@ -130,11 +159,12 @@
var/obj/machinery/abductor/console/console
/obj/item/device/abductor/gizmo/attack_self(mob/user)
- if(!AbductorCheck(user))
- return
if(!ScientistCheck(user))
- to_chat(user, "You're not trained to use this!")
return
+ if(!console)
+ to_chat(user, "The device is not linked to console!")
+ return
+
if(mode == GIZMO_SCAN)
mode = GIZMO_MARK
icon_state = "gizmo_mark"
@@ -144,11 +174,12 @@
to_chat(user, "You switch the device to [mode==GIZMO_SCAN? "SCAN": "MARK"] MODE")
/obj/item/device/abductor/gizmo/attack(mob/living/M, mob/user)
- if(!AbductorCheck(user))
- return
if(!ScientistCheck(user))
- to_chat(user, "You're not trained to use this")
return
+ if(!console)
+ to_chat(user, "The device is not linked to console!")
+ return
+
switch(mode)
if(GIZMO_SCAN)
scan(M, user)
@@ -159,11 +190,12 @@
/obj/item/device/abductor/gizmo/afterattack(atom/target, mob/living/user, flag, params)
if(flag)
return
- if(!AbductorCheck(user))
- return
if(!ScientistCheck(user))
- to_chat(user, "You're not trained to use this")
return
+ if(!console)
+ to_chat(user, "The device is not linked to console!")
+ return
+
switch(mode)
if(GIZMO_SCAN)
scan(target, user)
@@ -172,9 +204,8 @@
/obj/item/device/abductor/gizmo/proc/scan(atom/target, mob/living/user)
if(ishuman(target))
- if(console!=null)
- console.AddSnapshot(target)
- to_chat(user, "You scan [target] and add them to the database.")
+ console.AddSnapshot(target)
+ to_chat(user, "You scan [target] and add them to the database.")
/obj/item/device/abductor/gizmo/proc/mark(atom/target, mob/living/user)
if(marked == target)
@@ -198,11 +229,15 @@
marked = target
to_chat(user, "You finish preparing [target] for transport.")
+/obj/item/device/abductor/gizmo/Destroy()
+ if(console)
+ console.gizmo = null
+ . = ..()
+
/obj/item/device/abductor/silencer
name = "abductor silencer"
desc = "A compact device used to shut down communications equipment."
- icon = 'icons/obj/abductor.dmi'
icon_state = "silencer"
item_state = "gizmo"
origin_tech = "materials=4;programming=7;abductor=3"
@@ -419,10 +454,10 @@ Congratulations! You are now trained for invasive xenobiology research!"}
if(!C.handcuffed)
C.handcuffed = new /obj/item/weapon/restraints/handcuffs/energy/used(C)
C.update_handcuffed()
- to_chat(user, "You handcuff [C].")
+ to_chat(user, "You restrain [C].")
add_logs(user, C, "handcuffed")
else
- to_chat(user, "You fail to handcuff [C].")
+ to_chat(user, "You fail to restrain [C].")
else
to_chat(user, "[C] doesn't have two hands...")
@@ -471,11 +506,11 @@ Congratulations! You are now trained for invasive xenobiology research!"}
..()
switch(mode)
if(BATON_STUN)
- user <<"The baton is in stun mode."
+ to_chat(user, "The baton is in stun mode.")
if(BATON_SLEEP)
- user <<"The baton is in sleep inducement mode."
+ to_chat(user, "The baton is in sleep inducement mode.")
if(BATON_CUFF)
- user <<"The baton is in restraining mode."
+ to_chat(user, "The baton is in restraining mode.")
if(BATON_PROBE)
to_chat(user, "The baton is in probing mode.")
diff --git a/code/game/gamemodes/miniantags/abduction/abduction_outfits.dm b/code/game/gamemodes/miniantags/abduction/abduction_outfits.dm
index 100c485263..c92fdddf26 100644
--- a/code/game/gamemodes/miniantags/abduction/abduction_outfits.dm
+++ b/code/game/gamemodes/miniantags/abduction/abduction_outfits.dm
@@ -22,13 +22,13 @@
if(console)
var/obj/item/clothing/suit/armor/abductor/vest/V = locate() in H
if(V)
- console.vest = V
+ console.AddVest(V)
V.flags |= NODROP
- var/obj/item/device/abductor/gizmo/G = locate() in H.getBackSlot()
- if(G)
- console.gizmo = G
- G.console = console
+ var/obj/item/weapon/storage/backpack/B = locate() in H
+ if(B)
+ for(var/obj/item/device/abductor/gizmo/G in B.contents)
+ console.AddGizmo(G)
/datum/outfit/abductor/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
..()
@@ -40,10 +40,10 @@
name = "Abductor Agent"
head = /obj/item/clothing/head/helmet/abductor
suit = /obj/item/clothing/suit/armor/abductor/vest
+ suit_store = /obj/item/weapon/abductor_baton
belt = /obj/item/weapon/storage/belt/military/abductor/full
backpack_contents = list(
- /obj/item/weapon/abductor_baton = 1,
/obj/item/weapon/gun/energy/alien = 1,
/obj/item/device/abductor/silencer = 1
)
diff --git a/code/game/gamemodes/miniantags/abduction/machinery/console.dm b/code/game/gamemodes/miniantags/abduction/machinery/console.dm
index 2a23c37444..8ad8cc8474 100644
--- a/code/game/gamemodes/miniantags/abduction/machinery/console.dm
+++ b/code/game/gamemodes/miniantags/abduction/machinery/console.dm
@@ -7,7 +7,7 @@
//Console
/obj/machinery/abductor/console
- name = "Abductor console"
+ name = "abductor console"
desc = "Ship command center."
icon = 'icons/obj/abductor.dmi'
icon_state = "console"
@@ -32,7 +32,7 @@
var/dat = ""
dat += " Abductsoft 3000
"
- if(experiment != null)
+ if(experiment)
var/points = experiment.points
var/credits = experiment.credits
dat += "Collected Samples : [points]
"
@@ -46,18 +46,18 @@
else
dat += "NO EXPERIMENT MACHINE DETECTED
"
- if(pad!=null)
+ if(pad)
dat += "Emergency Teleporter System."
dat += "Consider using primary observation console first."
dat += "Activate Teleporter
"
- if(gizmo!=null && gizmo.marked!=null)
+ if(gizmo && gizmo.marked)
dat += "Retrieve Mark
"
else
dat += "Retrieve Mark
"
else
dat += "NO TELEPAD DETECTED"
- if(vest!=null)
+ if(vest)
dat += " Agent Vest Mode
"
var/mode = vest.mode
if(mode == VEST_STEALTH)
@@ -88,7 +88,8 @@
else if(href_list["flip_vest"])
FlipVest()
else if(href_list["toggle_vest"])
- toggle_vest()
+ if(vest)
+ vest.toggle_nodrop()
else if(href_list["select_disguise"])
SelectDisguise()
else if(href_list["dispense"])
@@ -105,23 +106,22 @@
Dispense(/obj/item/clothing/suit/armor/abductor/vest)
updateUsrDialog()
-
/obj/machinery/abductor/console/proc/TeleporterRetrieve()
- if(gizmo!=null && pad!=null && gizmo.marked)
+ if(pad && gizmo && gizmo.marked)
pad.Retrieve(gizmo.marked)
/obj/machinery/abductor/console/proc/TeleporterSend()
- if(pad!=null)
+ if(pad)
pad.Send()
/obj/machinery/abductor/console/proc/FlipVest()
- if(vest!=null)
+ 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
var/datum/icon_snapshot/chosen = disguises[entry_name]
- if(chosen && (remote || in_range(usr,src)))
+ if(chosen && vest && (remote || in_range(usr,src)))
vest.SetDisguise(chosen)
/obj/machinery/abductor/console/proc/SetDroppoint(turf/open/location,user)
@@ -135,10 +135,10 @@
/obj/machinery/abductor/console/Initialize(mapload)
- if(mapload)
- return TRUE //wait for machines list
..()
+ return INITIALIZE_HINT_LATELOAD
+/obj/machinery/abductor/console/LateInitialize()
if(!team)
return
@@ -169,36 +169,48 @@
return
disguises[entry.name] = entry
+/obj/machinery/abductor/console/proc/AddGizmo(obj/item/device/abductor/gizmo/G)
+ if(G == gizmo && G.console == src)
+ return FALSE
+
+ if(G.console)
+ G.console.gizmo = null
+
+ gizmo = G
+ G.console = src
+ return TRUE
+
+/obj/machinery/abductor/console/proc/AddVest(obj/item/clothing/suit/armor/abductor/vest/V)
+ if(vest == V)
+ return FALSE
+
+ for(var/obj/machinery/abductor/console/C in GLOB.machines)
+ if(C.vest == V)
+ C.vest = null
+ break
+
+ vest = V
+ return TRUE
+
/obj/machinery/abductor/console/attackby(obj/O, mob/user, params)
- if(istype(O, /obj/item/device/abductor/gizmo))
- var/obj/item/device/abductor/gizmo/G = O
+ if(istype(O, /obj/item/device/abductor/gizmo) && AddGizmo(O))
to_chat(user, "You link the tool to the console.")
- gizmo = G
- G.console = src
- else if(istype(O, /obj/item/clothing/suit/armor/abductor/vest))
- var/obj/item/clothing/suit/armor/abductor/vest/V = O
+ else if(istype(O, /obj/item/clothing/suit/armor/abductor/vest) && AddVest(O))
to_chat(user, "You link the vest to the console.")
- if(istype(vest))
- if(vest.flags & NODROP)
- toggle_vest()
- vest = V
else
return ..()
+
+
/obj/machinery/abductor/console/proc/Dispense(item,cost=1)
if(experiment && experiment.credits >= cost)
experiment.credits -=cost
say("Incoming supply!")
+ var/drop_location = loc
if(pad)
flick("alien-pad", pad)
- new item(pad.loc)
- else
- new item(loc)
+ drop_location = pad.loc
+ new item(drop_location)
+
else
say("Insufficent data!")
-
-/obj/machinery/abductor/console/proc/toggle_vest()
- vest.flags ^= NODROP
- var/mob/M = vest.loc
- if(istype(M))
- to_chat(M, "[src] is now [vest.flags & NODROP ? "locked" : "unlocked"].")
diff --git a/code/game/gamemodes/miniantags/abduction/machinery/dispenser.dm b/code/game/gamemodes/miniantags/abduction/machinery/dispenser.dm
index d006ba0f68..8cf9acac0b 100644
--- a/code/game/gamemodes/miniantags/abduction/machinery/dispenser.dm
+++ b/code/game/gamemodes/miniantags/abduction/machinery/dispenser.dm
@@ -1,5 +1,5 @@
/obj/machinery/abductor/gland_dispenser
- name = "Replacement Organ Storage"
+ name = "replacement organ storage"
desc = "A tank filled with replacement organs."
icon = 'icons/obj/abductor.dmi'
icon_state = "dispenser"
@@ -49,7 +49,7 @@
var/g_color = gland_colors[i]
var/amount = amounts[i]
dat += "[amount]"
- if(item_count == 3) // Three boxes per line
+ if(item_count == 4) // Four boxes per line
dat +=""
item_count = 0
var/datum/browser/popup = new(user, "glands", "Gland Dispenser", 200, 200)
diff --git a/code/game/gamemodes/miniantags/abduction/machinery/pad.dm b/code/game/gamemodes/miniantags/abduction/machinery/pad.dm
index 5f8ad3de9d..083e610587 100644
--- a/code/game/gamemodes/miniantags/abduction/machinery/pad.dm
+++ b/code/game/gamemodes/miniantags/abduction/machinery/pad.dm
@@ -47,8 +47,8 @@
icon_state = "teleport"
duration = 80
-/obj/effect/overlay/temp/teleport_abductor/New()
+/obj/effect/overlay/temp/teleport_abductor/Initialize()
+ . = ..()
var/datum/effect_system/spark_spread/S = new
S.set_up(10,0,loc)
- S.start()
- ..()
\ No newline at end of file
+ S.start()
\ No newline at end of file
diff --git a/code/game/gamemodes/miniantags/borer/borer.dm b/code/game/gamemodes/miniantags/borer/borer.dm
index b10fb16768..92cff03ec9 100644
--- a/code/game/gamemodes/miniantags/borer/borer.dm
+++ b/code/game/gamemodes/miniantags/borer/borer.dm
@@ -628,7 +628,7 @@ GLOBAL_VAR_INIT(total_borer_hosts_needed, 10)
chemicals -= 250
to_chat(src, "You send a jolt of energy to your host, reviving them!")
victim.grab_ghost(force = TRUE) //brings the host back, no eggscape
- victim <<"You bolt upright, gasping for breath!"
+ to_chat(victim, "You bolt upright, gasping for breath!")
/mob/living/simple_animal/borer/verb/bond_brain()
set category = "Borer"
@@ -672,7 +672,7 @@ GLOBAL_VAR_INIT(total_borer_hosts_needed, 10)
if(!bonding)
return
if(docile)
- src <<"You are feeling far too docile to do that."
+ to_chat(src, "You are feeling far too docile to do that.")
return
if(is_servant_of_ratvar(victim) || iscultist(victim) || victim.isloyal())
to_chat(src, "[victim]'s mind seems to be blocked by some unknown force!")
diff --git a/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm b/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm
index 6ce04bed14..c6248b03cc 100644
--- a/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm
+++ b/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm
@@ -527,9 +527,9 @@
icon_state = "disintegrate"
duration = 10
-/obj/effect/overlay/temp/swarmer/disintegration/New()
- playsound(src.loc, "sparks", 100, 1)
- ..()
+/obj/effect/overlay/temp/swarmer/disintegration/Initialize()
+ . = ..()
+ playsound(loc, "sparks", 100, 1)
/obj/effect/overlay/temp/swarmer/dismantle
icon_state = "dismantle"
diff --git a/code/game/gamemodes/miniantags/monkey/monkey.dm b/code/game/gamemodes/miniantags/monkey/monkey.dm
index ecb15bc221..f9ea8dcc2c 100644
--- a/code/game/gamemodes/miniantags/monkey/monkey.dm
+++ b/code/game/gamemodes/miniantags/monkey/monkey.dm
@@ -107,10 +107,10 @@
/datum/game_mode/monkey/declare_completion()
if(check_monkey_victory())
- feedback_set_details("round_end_result","win - monkey win")
- feedback_set("round_end_result",escaped_monkeys)
+ SSblackbox.set_details("round_end_result","win - monkey win")
+ SSblackbox.set_val("round_end_result",escaped_monkeys)
to_chat(world, "The monkeys have overthrown their captors! Eeek eeeek!!")
else
- feedback_set_details("round_end_result","loss - staff stopped the monkeys")
- feedback_set("round_end_result",escaped_monkeys)
+ SSblackbox.set_details("round_end_result","loss - staff stopped the monkeys")
+ SSblackbox.set_val("round_end_result",escaped_monkeys)
to_chat(world, "The staff managed to contain the monkey infestation!")
diff --git a/code/game/gamemodes/miniantags/slaughter/slaughter.dm b/code/game/gamemodes/miniantags/slaughter/slaughter.dm
index c3d06bfe2c..53e92c639d 100644
--- a/code/game/gamemodes/miniantags/slaughter/slaughter.dm
+++ b/code/game/gamemodes/miniantags/slaughter/slaughter.dm
@@ -92,7 +92,7 @@
playsound(user, 'sound/magic/Demon_consume.ogg', 50, 1)
for(var/obj/effect/proc_holder/spell/knownspell in user.mind.spell_list)
if(knownspell.type == /obj/effect/proc_holder/spell/bloodcrawl)
- user <<"...and you don't feel any different."
+ to_chat(user, "...and you don't feel any different.")
qdel(src)
return
user.visible_message("[user]'s eyes flare a deep crimson!", \
diff --git a/code/game/gamemodes/nuclear/nuclear.dm b/code/game/gamemodes/nuclear/nuclear.dm
index d4d788e049..b12dcc3bcc 100644
--- a/code/game/gamemodes/nuclear/nuclear.dm
+++ b/code/game/gamemodes/nuclear/nuclear.dm
@@ -199,70 +199,70 @@
if(nuke_off_station == NUKE_SYNDICATE_BASE)
- feedback_set_details("round_end_result","loss - syndicate nuked - disk secured")
+ SSblackbox.set_details("round_end_result","loss - syndicate nuked - disk secured")
to_chat(world, "Humiliating Syndicate Defeat")
to_chat(world, "The crew of [station_name()] gave [syndicate_name()] operatives back their bomb! The syndicate base was destroyed! Next time, don't lose the nuke!")
SSticker.news_report = NUKE_SYNDICATE_BASE
else if(!disk_rescued && station_was_nuked && !syndies_didnt_escape)
- feedback_set_details("round_end_result","win - syndicate nuke")
+ SSblackbox.set_details("round_end_result","win - syndicate nuke")
to_chat(world, "Syndicate Major Victory!")
to_chat(world, "[syndicate_name()] operatives have destroyed [station_name()]!")
SSticker.news_report = STATION_NUKED
else if (!disk_rescued && station_was_nuked && syndies_didnt_escape)
- feedback_set_details("round_end_result","halfwin - syndicate nuke - did not evacuate in time")
+ SSblackbox.set_details("round_end_result","halfwin - syndicate nuke - did not evacuate in time")
to_chat(world, "Total Annihilation")
to_chat(world, "[syndicate_name()] operatives destroyed [station_name()] but did not leave the area in time and got caught in the explosion. Next time, don't lose the disk!")
SSticker.news_report = STATION_NUKED
else if (!disk_rescued && !station_was_nuked && nuke_off_station && !syndies_didnt_escape)
- feedback_set_details("round_end_result","halfwin - blew wrong station")
+ SSblackbox.set_details("round_end_result","halfwin - blew wrong station")
to_chat(world, "Crew Minor Victory")
to_chat(world, "[syndicate_name()] operatives secured the authentication disk but blew up something that wasn't [station_name()]. Next time, don't do that!")
SSticker.news_report = NUKE_MISS
else if (!disk_rescued && !station_was_nuked && nuke_off_station && syndies_didnt_escape)
- feedback_set_details("round_end_result","halfwin - blew wrong station - did not evacuate in time")
+ SSblackbox.set_details("round_end_result","halfwin - blew wrong station - did not evacuate in time")
to_chat(world, "[syndicate_name()] operatives have earned Darwin Award!")
to_chat(world, "[syndicate_name()] operatives blew up something that wasn't [station_name()] and got caught in the explosion. Next time, don't do that!")
SSticker.news_report = NUKE_MISS
else if ((disk_rescued || SSshuttle.emergency.mode != SHUTTLE_ENDGAME) && are_operatives_dead())
- feedback_set_details("round_end_result","loss - evacuation - disk secured - syndi team dead")
+ SSblackbox.set_details("round_end_result","loss - evacuation - disk secured - syndi team dead")
to_chat(world, "Crew Major Victory!")
to_chat(world, "The Research Staff has saved the disk and killed the [syndicate_name()] Operatives")
SSticker.news_report = OPERATIVES_KILLED
else if (disk_rescued)
- feedback_set_details("round_end_result","loss - evacuation - disk secured")
+ SSblackbox.set_details("round_end_result","loss - evacuation - disk secured")
to_chat(world, "Crew Major Victory")
to_chat(world, "The Research Staff has saved the disk and stopped the [syndicate_name()] Operatives!")
SSticker.news_report = OPERATIVES_KILLED
else if (!disk_rescued && are_operatives_dead())
- feedback_set_details("round_end_result","halfwin - evacuation - disk not secured")
+ SSblackbox.set_details("round_end_result","halfwin - evacuation - disk not secured")
to_chat(world, "Neutral Victory!")
to_chat(world, "The Research Staff failed to secure the authentication disk but did manage to kill most of the [syndicate_name()] Operatives!")
SSticker.news_report = OPERATIVE_SKIRMISH
else if (!disk_rescued && crew_evacuated)
- feedback_set_details("round_end_result","halfwin - detonation averted")
+ SSblackbox.set_details("round_end_result","halfwin - detonation averted")
to_chat(world, "Syndicate Minor Victory!")
to_chat(world, "[syndicate_name()] operatives survived the assault but did not achieve the destruction of [station_name()]. Next time, don't lose the disk!")
SSticker.news_report = OPERATIVE_SKIRMISH
else if (!disk_rescued && !crew_evacuated)
- feedback_set_details("round_end_result","halfwin - interrupted")
+ SSblackbox.set_details("round_end_result","halfwin - interrupted")
to_chat(world, "Neutral Victory")
to_chat(world, "Round was mysteriously interrupted!")
diff --git a/code/game/gamemodes/nuclear/nuclear_challenge.dm b/code/game/gamemodes/nuclear/nuclear_challenge.dm
index 3e47aa517d..cad958ee64 100644
--- a/code/game/gamemodes/nuclear/nuclear_challenge.dm
+++ b/code/game/gamemodes/nuclear/nuclear_challenge.dm
@@ -57,7 +57,7 @@
U.hidden_uplink.telecrystals = CHALLENGE_TELECRYSTALS
U.hidden_uplink.set_gamemode(/datum/game_mode/nuclear)
config.shuttle_refuel_delay = max(config.shuttle_refuel_delay, CHALLENGE_SHUTTLE_DELAY)
- feedback_set("nuclear_challenge_mode",1)
+ SSblackbox.set_val("nuclear_challenge_mode",1)
qdel(src)
/obj/item/device/nuclear_challenge/proc/check_allowed(mob/living/user)
diff --git a/code/game/gamemodes/revolution/revolution.dm b/code/game/gamemodes/revolution/revolution.dm
index 634c68e89a..7a31d1f3cd 100644
--- a/code/game/gamemodes/revolution/revolution.dm
+++ b/code/game/gamemodes/revolution/revolution.dm
@@ -345,13 +345,13 @@
//////////////////////////////////////////////////////////////////////
/datum/game_mode/revolution/declare_completion()
if(finished == 1)
- feedback_set_details("round_end_result","win - heads killed")
+ SSblackbox.set_details("round_end_result","win - heads killed")
to_chat(world, "The heads of staff were killed or exiled! The revolutionaries win!")
SSticker.news_report = REVS_WIN
else if(finished == 2)
- feedback_set_details("round_end_result","loss - rev heads killed")
+ SSblackbox.set_details("round_end_result","loss - rev heads killed")
to_chat(world, "The heads of staff managed to stop the revolution!")
SSticker.news_report = REVS_LOSE
diff --git a/code/game/gamemodes/traitor/double_agents.dm b/code/game/gamemodes/traitor/double_agents.dm
index 992e10fa22..cb6609ebe6 100644
--- a/code/game/gamemodes/traitor/double_agents.dm
+++ b/code/game/gamemodes/traitor/double_agents.dm
@@ -1,22 +1,24 @@
-/datum/game_mode/traitor/double_agents
- name = "double agents"
- config_tag = "double_agents"
+/datum/game_mode/traitor/internal_affairs
+ name = "Internal Affairs"
+ config_tag = "internal_affairs"
+ employer = "Internal Affairs"
required_players = 25
required_enemies = 5
recommended_enemies = 8
reroll_friendly = 0
+ traitor_name = "Nanotrasen Internal Affairs Agent"
traitors_possible = 10 //hard limit on traitors if scaling is turned off
num_modifier = 4 // Four additional traitors
- announce_text = "There are double agents trying to kill each other!\n\
- Traitors: Eliminate your targets and protect yourself!\n\
- Crew: Stop the double agents before they can cause too much mayhem."
+ announce_text = "There are Nanotrasen Internal Affairs Agents trying to kill each other!\n\
+ IAA: Eliminate your targets and protect yourself!\n\
+ Crew: Stop the IAA agents before they can cause too much mayhem."
var/list/target_list = list()
var/list/late_joining_list = list()
-/datum/game_mode/traitor/double_agents/post_setup()
+/datum/game_mode/traitor/internal_affairs/post_setup()
var/i = 0
for(var/datum/mind/traitor in traitors)
i++
@@ -25,7 +27,7 @@
target_list[traitor] = traitors[i + 1]
..()
-/datum/game_mode/traitor/double_agents/forge_traitor_objectives(datum/mind/traitor)
+/datum/game_mode/traitor/internal_affairs/forge_traitor_objectives(datum/mind/traitor)
if(target_list.len && target_list[traitor]) // Is a double agent
@@ -58,7 +60,7 @@
..() // Give them standard objectives.
return
-/datum/game_mode/traitor/double_agents/add_latejoin_traitor(datum/mind/character)
+/datum/game_mode/traitor/internal_affairs/add_latejoin_traitor(datum/mind/character)
check_potential_agents()
@@ -87,7 +89,7 @@
late_joining_list += character
return
-/datum/game_mode/traitor/double_agents/proc/check_potential_agents()
+/datum/game_mode/traitor/internal_affairs/proc/check_potential_agents()
for(var/M in late_joining_list)
if(istype(M, /datum/mind))
@@ -100,3 +102,18 @@
// If any check fails, remove them from our list
late_joining_list -= M
+
+
+/datum/game_mode/traitor/internal_affairs/greet_traitor(datum/mind/traitor)
+ var/crime = pick("distribution of contraband" , "unauthorized erotic action on duty", "embezzlement", "piloting under the influence", "dereliction of duty", "syndicate collaboration", "mutiny", "multiple homicides", "corporate espionage", "recieving bribes", "malpractice", "worship of prohbited life forms", "possession of profane texts", "murder", "arson", "insulting their manager", "grand theft", "conspiracy", "attempting to unionize", "vandalism", "gross incompetence")
+ to_chat(traitor.current, "You are the [traitor_name].")
+ to_chat(traitor.current, "Your target is suspected of [crime], and you have been tasked with eliminating them by any means necessary to avoid a costly and embarrassing public trial.")
+ to_chat(traitor.current, "While you have a license to kill, unneeded property damage or loss of employee life will lead to your contract being terminated.")
+ to_chat(traitor.current, "For the sake of plausible deniability, you have been equipped with an array of captured Syndicate weaponry available via uplink.")
+ to_chat(traitor.current, "Finally, watch your back. Your target has friends in high places, and intel suggests someone may have taken out a contract of their own to protect them.")
+ traitor.announce_objectives()
+
+
+
+/datum/game_mode/traitor/internal_affairs/give_codewords(mob/living/traitor_mob)
+ return
\ No newline at end of file
diff --git a/code/game/gamemodes/traitor/traitor.dm b/code/game/gamemodes/traitor/traitor.dm
index c26945801b..90a953c446 100644
--- a/code/game/gamemodes/traitor/traitor.dm
+++ b/code/game/gamemodes/traitor/traitor.dm
@@ -1,5 +1,6 @@
/datum/game_mode
var/traitor_name = "traitor"
+ var/employer = "The Syndicate"
var/list/datum/mind/traitors = list()
var/datum/mind/exchange_red
@@ -213,7 +214,7 @@
..()
return//Traitors will be checked as part of check_extra_completion. Leaving this here as a reminder.
-/proc/give_codewords(mob/living/traitor_mob)
+/datum/game_mode/proc/give_codewords(mob/living/traitor_mob)
to_chat(traitor_mob, "The Syndicate provided you with the following information on how to identify their agents:")
to_chat(traitor_mob, "Code Phrase: [GLOB.syndicate_code_phrase]")
to_chat(traitor_mob, "Code Response: [GLOB.syndicate_code_response]")
@@ -260,10 +261,10 @@
for(var/datum/objective/objective in traitor.objectives)
if(objective.check_completion())
objectives += "
Objective #[count]: [objective.explanation_text] Success!"
- feedback_add_details("traitor_objective","[objective.type]|SUCCESS")
+ SSblackbox.add_details("traitor_objective","[objective.type]|SUCCESS")
else
objectives += "
Objective #[count]: [objective.explanation_text] Fail."
- feedback_add_details("traitor_objective","[objective.type]|FAIL")
+ SSblackbox.add_details("traitor_objective","[objective.type]|FAIL")
traitorwin = 0
count++
@@ -283,10 +284,10 @@
if(traitorwin)
text += "
The [special_role_text] was successful!"
- feedback_add_details("traitor_success","SUCCESS")
+ SSblackbox.add_details("traitor_success","SUCCESS")
else
text += "
The [special_role_text] has failed!"
- feedback_add_details("traitor_success","FAIL")
+ SSblackbox.add_details("traitor_success","FAIL")
text += "
"
@@ -335,7 +336,7 @@
uplink_loc = R
if (!uplink_loc)
- to_chat(traitor_mob, "Unfortunately, the Syndicate wasn't able to get you an Uplink.")
+ to_chat(traitor_mob, "Unfortunately, [employer] wasn't able to get you an Uplink.")
. = 0
else
var/obj/item/device/uplink/U = new(uplink_loc)
@@ -345,19 +346,19 @@
if(uplink_loc == R)
R.traitor_frequency = sanitize_frequency(rand(MIN_FREQ, MAX_FREQ))
- to_chat(traitor_mob, "The Syndicate have cunningly disguised a Syndicate Uplink as your [R.name]. Simply dial the frequency [format_frequency(R.traitor_frequency)] to unlock its hidden features.")
+ to_chat(traitor_mob, "[employer] has cunningly disguised a Syndicate Uplink as your [R.name]. Simply dial the frequency [format_frequency(R.traitor_frequency)] to unlock its hidden features.")
traitor_mob.mind.store_memory("Radio Frequency: [format_frequency(R.traitor_frequency)] ([R.name]).")
else if(uplink_loc == PDA)
PDA.lock_code = "[rand(100,999)] [pick("Alpha","Bravo","Charlie","Delta","Echo","Foxtrot","Golf","Hotel","India","Juliet","Kilo","Lima","Mike","November","Oscar","Papa","Quebec","Romeo","Sierra","Tango","Uniform","Victor","Whiskey","X-ray","Yankee","Zulu")]"
- to_chat(traitor_mob, "The Syndicate have cunningly disguised a Syndicate Uplink as your [PDA.name]. Simply enter the code \"[PDA.lock_code]\" into the ringtone select to unlock its hidden features.")
+ to_chat(traitor_mob, "[employer] has cunningly disguised a Syndicate Uplink as your [PDA.name]. Simply enter the code \"[PDA.lock_code]\" into the ringtone select to unlock its hidden features.")
traitor_mob.mind.store_memory("Uplink Passcode: [PDA.lock_code] ([PDA.name]).")
else if(uplink_loc == P)
P.traitor_unlock_degrees = rand(1, 360)
- to_chat(traitor_mob, "The Syndicate have cunningly disguised a Syndicate Uplink as your [P.name]. Simply twist the top of the pen [P.traitor_unlock_degrees] from its starting position to unlock its hidden features.")
+ to_chat(traitor_mob, "[employer] has cunningly disguised a Syndicate Uplink as your [P.name]. Simply twist the top of the pen [P.traitor_unlock_degrees] from its starting position to unlock its hidden features.")
traitor_mob.mind.store_memory("Uplink Degrees: [P.traitor_unlock_degrees] ([P.name]).")
if(!safety) // If they are not a rev. Can be added on to.
diff --git a/code/game/gamemodes/wizard/artefact.dm b/code/game/gamemodes/wizard/artefact.dm
index c925a5cbd5..137514d1e3 100644
--- a/code/game/gamemodes/wizard/artefact.dm
+++ b/code/game/gamemodes/wizard/artefact.dm
@@ -471,7 +471,7 @@
else if(istype(I,/obj/item/weapon/bikehorn))
to_chat(target, "HONK")
target << 'sound/items/AirHorn.ogg'
- target.adjustEarDamage(0,3)
+ target.adjustEarDamage(0,3)
GiveHint(target)
cooldown = world.time +cooldown_time
return
@@ -630,6 +630,6 @@
duration = 40
pixel_x = 500
-/obj/effect/overlay/temp/tornado/New(loc)
- ..()
+/obj/effect/overlay/temp/tornado/Initialize()
+ . = ..()
animate(src, pixel_x = -500, time = 40)
diff --git a/code/game/gamemodes/wizard/raginmages.dm b/code/game/gamemodes/wizard/raginmages.dm
index 01eb8a52c4..1eb51a95b4 100644
--- a/code/game/gamemodes/wizard/raginmages.dm
+++ b/code/game/gamemodes/wizard/raginmages.dm
@@ -132,7 +132,7 @@
/datum/game_mode/wizard/raginmages/declare_completion()
if(finished)
- feedback_set_details("round_end_result","loss - wizard killed")
+ SSblackbox.set_details("round_end_result","loss - wizard killed")
to_chat(world, "The crew has managed to hold off the wizard attack! The Space Wizards Federation has been taught a lesson they will not soon forget!")
..(1)
diff --git a/code/game/gamemodes/wizard/spellbook.dm b/code/game/gamemodes/wizard/spellbook.dm
index e9e1a95e73..b25187195d 100644
--- a/code/game/gamemodes/wizard/spellbook.dm
+++ b/code/game/gamemodes/wizard/spellbook.dm
@@ -57,10 +57,10 @@
aspell.name = "Instant [aspell.name]"
if(aspell.spell_level >= aspell.level_max)
to_chat(user, "This spell cannot be strengthened any further.")
- feedback_add_details("wizard_spell_improved", "[name]|[aspell.level]")
+ SSblackbox.add_details("wizard_spell_improved", "[name]|[aspell.level]")
return 1
//No same spell found - just learn it
- feedback_add_details("wizard_spell_learned", name)
+ SSblackbox.add_details("wizard_spell_learned", name)
user.mind.AddSpell(S)
to_chat(user, "You have learned [S.name].")
return 1
@@ -253,7 +253,7 @@
/datum/spellbook_entry/the_traps
name = "The Traps!"
spell_type = /obj/effect/proc_holder/spell/aoe_turf/conjure/the_traps
- category = "Offensive"
+ category = "Defensive"
cost = 1
@@ -266,7 +266,7 @@
/datum/spellbook_entry/item/Buy(mob/living/carbon/human/user,obj/item/weapon/spellbook/book)
new item_path(get_turf(user))
- feedback_add_details("wizard_spell_learned", name)
+ SSblackbox.add_details("wizard_spell_learned", name)
return 1
/datum/spellbook_entry/item/GetInfo()
@@ -465,7 +465,7 @@
return TRUE
/datum/spellbook_entry/summon/ghosts/Buy(mob/living/carbon/human/user, obj/item/weapon/spellbook/book)
- feedback_add_details("wizard_spell_learned", name)
+ SSblackbox.add_details("wizard_spell_learned", name)
new /datum/round_event/wizard/ghost()
active = TRUE
to_chat(user, "You have cast summon ghosts!")
@@ -482,7 +482,7 @@
return (SSticker.mode.name != "ragin' mages" && !config.no_summon_guns)
/datum/spellbook_entry/summon/guns/Buy(mob/living/carbon/human/user,obj/item/weapon/spellbook/book)
- feedback_add_details("wizard_spell_learned", name)
+ SSblackbox.add_details("wizard_spell_learned", name)
rightandwrong(0, user, 25)
active = 1
playsound(get_turf(user), 'sound/magic/CastSummon.ogg', 50, 1)
@@ -499,7 +499,7 @@
return (SSticker.mode.name != "ragin' mages" && !config.no_summon_magic)
/datum/spellbook_entry/summon/magic/Buy(mob/living/carbon/human/user,obj/item/weapon/spellbook/book)
- feedback_add_details("wizard_spell_learned", name)
+ SSblackbox.add_details("wizard_spell_learned", name)
rightandwrong(1, user, 25)
active = 1
playsound(get_turf(user), 'sound/magic/CastSummon.ogg', 50, 1)
@@ -517,7 +517,7 @@
return (SSticker.mode.name != "ragin' mages" && !config.no_summon_events)
/datum/spellbook_entry/summon/events/Buy(mob/living/carbon/human/user,obj/item/weapon/spellbook/book)
- feedback_add_details("wizard_spell_learned", name)
+ SSblackbox.add_details("wizard_spell_learned", name)
summonevents()
times++
playsound(get_turf(user), 'sound/magic/CastSummon.ogg', 50, 1)
diff --git a/code/game/gamemodes/wizard/wizard.dm b/code/game/gamemodes/wizard/wizard.dm
index 34d148f03c..35bccb692a 100644
--- a/code/game/gamemodes/wizard/wizard.dm
+++ b/code/game/gamemodes/wizard/wizard.dm
@@ -176,7 +176,7 @@
/datum/game_mode/wizard/declare_completion()
if(finished)
- feedback_set_details("round_end_result","loss - wizard killed")
+ SSblackbox.set_details("round_end_result","loss - wizard killed")
to_chat(world, "The wizard[(wizards.len>1)?"s":""] has been killed by the crew! The Space Wizards Federation has been taught a lesson they will not soon forget!")
SSticker.news_report = WIZARD_KILLED
@@ -208,19 +208,19 @@
for(var/datum/objective/objective in wizard.objectives)
if(objective.check_completion())
text += "
Objective #[count]: [objective.explanation_text] Success!"
- feedback_add_details("wizard_objective","[objective.type]|SUCCESS")
+ SSblackbox.add_details("wizard_objective","[objective.type]|SUCCESS")
else
text += "
Objective #[count]: [objective.explanation_text] Fail."
- feedback_add_details("wizard_objective","[objective.type]|FAIL")
+ SSblackbox.add_details("wizard_objective","[objective.type]|FAIL")
wizardwin = 0
count++
if(wizard.current && wizard.current.stat!=2 && wizardwin)
text += "
The wizard was successful!"
- feedback_add_details("wizard_success","SUCCESS")
+ SSblackbox.add_details("wizard_success","SUCCESS")
else
text += "
The wizard has failed!"
- feedback_add_details("wizard_success","FAIL")
+ SSblackbox.add_details("wizard_success","FAIL")
if(wizard.spell_list.len>0)
text += "
[wizard.name] used the following spells: "
var/i = 1
diff --git a/code/game/machinery/bank_machine.dm b/code/game/machinery/bank_machine.dm
index 35f7babe1e..ace9b543d1 100644
--- a/code/game/machinery/bank_machine.dm
+++ b/code/game/machinery/bank_machine.dm
@@ -4,7 +4,21 @@
icon = 'goon/icons/obj/goon_terminals.dmi'
idle_power_usage = 100
var/siphoning = FALSE
- var/last_warning = 0
+ var/next_warning = 0
+ var/obj/item/device/radio/radio
+ var/radio_channel = "Common"
+ var/minimum_time_between_warnings = 400
+
+/obj/machinery/computer/bank_machine/Initialize(mapload)
+ ..()
+ radio = new(src)
+ radio.subspace_transmission = TRUE
+ radio.canhear_range = 0
+ radio.recalculateChannels()
+
+/obj/machinery/computer/bank_machine/Destroy()
+ QDEL_NULL(radio)
+ . = ..()
/obj/machinery/computer/bank_machine/attackby(obj/item/I, mob/user)
var/value = 0
@@ -32,18 +46,17 @@
say("Station funds depleted. Halting siphon.")
siphoning = FALSE
else
- var/obj/item/stack/spacecash/c200/on_turf = locate() in src.loc
- if(on_turf && on_turf.amount < on_turf.max_amount)
- on_turf.amount++
- else
- new /obj/item/stack/spacecash/c200(get_turf(src))
+ new /obj/item/stack/spacecash/c200(get_turf(src)) // will autostack
playsound(src.loc, 'sound/items/poster_being_created.ogg', 100, 1)
SSshuttle.points -= 200
- if(last_warning < world.time && prob(15))
+ if(next_warning < world.time && prob(15))
var/area/A = get_area(loc)
- minor_announce("Unauthorized credit withdrawal underway in [A.map_name]." , "Network Breach", TRUE)
- last_warning = world.time + 400
+ var/message = "Unauthorized credit withdrawal underway in [A.map_name]!!"
+ radio.talk_into(src, message, radio_channel, get_spans())
+ next_warning = world.time + minimum_time_between_warnings
+/obj/machinery/computer/bank_machine/get_spans()
+ . = ..() | SPAN_ROBOT
/obj/machinery/computer/bank_machine/attack_hand(mob/user)
if(..())
@@ -67,8 +80,8 @@
if(..())
return
if(href_list["siphon"])
- say("Siphon of station credits has begun!")
+ say("Siphon of station credits has begun!")
siphoning = TRUE
if(href_list["halt"])
- say("Station credit withdrawal halted.")
- siphoning = FALSE
\ No newline at end of file
+ say("Station credit withdrawal halted.")
+ siphoning = FALSE
diff --git a/code/game/machinery/cloning.dm b/code/game/machinery/cloning.dm
index 5773db04be..eeef80ca5b 100644
--- a/code/game/machinery/cloning.dm
+++ b/code/game/machinery/cloning.dm
@@ -204,11 +204,13 @@
clonemind.transfer_to(H)
- H.grab_ghost()
- to_chat(H, "Consciousness slowly creeps over you as your body regenerates.
So this is what cloning feels like?")
+ if(grab_ghost_when == CLONER_FRESH_CLONE)
+ H.grab_ghost()
+ to_chat(H, "Consciousness slowly creeps over you as your body regenerates.
So this is what cloning feels like?")
if(grab_ghost_when == CLONER_MATURE_CLONE)
- addtimer(CALLBACK(src, .proc/occupant_dreams), 100)
+ H.ghostize(TRUE) //Only does anything if they were still in their old body and not already a ghost
+ to_chat(H.get_ghost(TRUE), "Your body is beginning to regenerate in a cloning pod. You will become conscious when it is complete.")
if(H)
H.faction |= factions
@@ -219,11 +221,6 @@
attempting = FALSE
return TRUE
-/obj/machinery/clonepod/proc/occupant_dreams()
- if(occupant)
- to_chat(occupant, "While your body grows, you have the strangest dream, like you can see yourself from the outside.")
- occupant.ghostize(TRUE)
-
//Grow clones to maturity then kick them out. FREELOADERS
/obj/machinery/clonepod/process()
diff --git a/code/game/machinery/computer/apc_control.dm b/code/game/machinery/computer/apc_control.dm
index 753cd42a4f..0c1b870771 100644
--- a/code/game/machinery/computer/apc_control.dm
+++ b/code/game/machinery/computer/apc_control.dm
@@ -108,7 +108,7 @@
if(!authenticated) //Check for emags
var/obj/item/weapon/card/emag/E = usr.get_active_held_item()
if(E && istype(E) && usr.Adjacent(src))
- usr << "You bypass [src]'s access requirements using your emag."
+ to_chat(usr, "You bypass [src]'s access requirements using your emag.")
authenticated = TRUE
log_activity("logged in") //Auth ID doesn't change, hinting that it was illicit
if(href_list["log_out"])
diff --git a/code/game/machinery/computer/arcade.dm b/code/game/machinery/computer/arcade.dm
index 514cf590af..643282ab4a 100644
--- a/code/game/machinery/computer/arcade.dm
+++ b/code/game/machinery/computer/arcade.dm
@@ -234,7 +234,7 @@
playsound(loc, 'sound/arcade/Win.ogg', 50, 1, extrarange = -3, falloff = 10)
if(emagged)
- feedback_inc("arcade_win_emagged")
+ SSblackbox.inc("arcade_win_emagged")
new /obj/effect/spawner/newbomb/timer/syndicate(loc)
new /obj/item/clothing/head/collectable/petehat(loc)
message_admins("[key_name_admin(usr)] has outbombed Cuban Pete and been awarded a bomb.")
@@ -242,7 +242,7 @@
Reset()
emagged = 0
else
- feedback_inc("arcade_win_normal")
+ SSblackbox.inc("arcade_win_normal")
prizevend()
else if (emagged && (turtle >= 4))
@@ -264,10 +264,10 @@
temp = "You have been drained! GAME OVER"
playsound(loc, 'sound/arcade/Lose.ogg', 50, 1, extrarange = -3, falloff = 10)
if(emagged)
- feedback_inc("arcade_loss_mana_emagged")
+ SSblackbox.inc("arcade_loss_mana_emagged")
usr.gib()
else
- feedback_inc("arcade_loss_mana_normal")
+ SSblackbox.inc("arcade_loss_mana_normal")
else if ((enemy_hp <= 10) && (enemy_mp > 4))
temp = "[enemy_name] heals for 4 health!"
@@ -286,10 +286,10 @@
temp = "You have been crushed! GAME OVER"
playsound(loc, 'sound/arcade/Lose.ogg', 50, 1, extrarange = -3, falloff = 10)
if(emagged)
- feedback_inc("arcade_loss_hp_emagged")
+ SSblackbox.inc("arcade_loss_hp_emagged")
usr.gib()
else
- feedback_inc("arcade_loss_hp_normal")
+ SSblackbox.inc("arcade_loss_hp_normal")
blocked = FALSE
return
diff --git a/code/game/machinery/computer/buildandrepair.dm b/code/game/machinery/computer/buildandrepair.dm
index 5271dc5293..9ec74dccd3 100644
--- a/code/game/machinery/computer/buildandrepair.dm
+++ b/code/game/machinery/computer/buildandrepair.dm
@@ -304,17 +304,17 @@
build_path = /obj/machinery/computer/gulag_teleporter_computer
/obj/item/weapon/circuitboard/computer/rdconsole
- name = "RD Console (Computer Board)"
+ name = "R&D Console (Computer Board)"
build_path = /obj/machinery/computer/rdconsole/core
/obj/item/weapon/circuitboard/computer/rdconsole/attackby(obj/item/I, mob/user, params)
if(istype(I,/obj/item/weapon/screwdriver))
if(build_path == /obj/machinery/computer/rdconsole/core)
- name = "RD Console - Robotics (Computer Board)"
+ name = "R&D Console - Robotics (Computer Board)"
build_path = /obj/machinery/computer/rdconsole/robotics
to_chat(user, "Access protocols successfully updated.")
else
- name = "RD Console (Computer Board)"
+ name = "R&D Console (Computer Board)"
build_path = /obj/machinery/computer/rdconsole/core
to_chat(user, "Defaulting access protocols.")
else
diff --git a/code/game/machinery/computer/card.dm b/code/game/machinery/computer/card.dm
index 907d7b5a6d..ca329f61e5 100644
--- a/code/game/machinery/computer/card.dm
+++ b/code/game/machinery/computer/card.dm
@@ -532,7 +532,7 @@ GLOBAL_VAR_INIT(time_last_changed_position, 0)
else
SSjob.prioritized_jobs += j
prioritycount++
- usr << "[j.title] has been successfully [priority ? "prioritized" : "unprioritized"]. Potential employees will notice your request."
+ to_chat(usr, "[j.title] has been successfully [priority ? "prioritized" : "unprioritized"]. Potential employees will notice your request.")
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
if ("print")
diff --git a/code/game/machinery/computer/communications.dm b/code/game/machinery/computer/communications.dm
index 5af4f9c281..c9a448fc7b 100644
--- a/code/game/machinery/computer/communications.dm
+++ b/code/game/machinery/computer/communications.dm
@@ -115,9 +115,9 @@
message_admins("[key_name_admin(usr)] has changed the security level to [get_security_level()].")
switch(GLOB.security_level)
if(SEC_LEVEL_GREEN)
- feedback_inc("alert_comms_green",1)
+ SSblackbox.inc("alert_comms_green",1)
if(SEC_LEVEL_BLUE)
- feedback_inc("alert_comms_blue",1)
+ SSblackbox.inc("alert_comms_blue",1)
tmp_alertlevel = 0
else
to_chat(usr, "You are not authorized to do this!")
@@ -176,7 +176,7 @@
SSshuttle.points -= S.credit_cost
minor_announce("[usr.name] has purchased [S.name] for [S.credit_cost] credits." , "Shuttle Purchase")
message_admins("[key_name_admin(usr)] purchased [S.name].")
- feedback_add_details("shuttle_purchase", S.name)
+ SSblackbox.add_details("shuttle_purchase", S.name)
else
to_chat(usr, "Something went wrong! The shuttle exchange system seems to be down.")
else
@@ -368,9 +368,9 @@
message_admins("[key_name_admin(usr)] has changed the security level to [get_security_level()].")
switch(GLOB.security_level)
if(SEC_LEVEL_GREEN)
- feedback_inc("alert_comms_green",1)
+ SSblackbox.inc("alert_comms_green",1)
if(SEC_LEVEL_BLUE)
- feedback_inc("alert_comms_blue",1)
+ SSblackbox.inc("alert_comms_blue",1)
tmp_alertlevel = 0
src.aistate = STATE_DEFAULT
if("ai-changeseclevel")
diff --git a/code/game/machinery/computer/message.dm b/code/game/machinery/computer/message.dm
index c97f487718..7f8eb32648 100644
--- a/code/game/machinery/computer/message.dm
+++ b/code/game/machinery/computer/message.dm
@@ -455,14 +455,16 @@
name = "monitor decryption key"
var/obj/machinery/message_server/server = null
-/obj/item/weapon/paper/monitorkey/New()
+/obj/item/weapon/paper/monitorkey/Initialize()
..()
- spawn(10)
- if(GLOB.message_servers)
- for(var/obj/machinery/message_server/server in GLOB.message_servers)
- if(!isnull(server))
- if(!isnull(server.decryptkey))
- info = "