diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_wizard.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_wizard.dmm index 05155ee2a8..88b906b467 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_wizard.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_wizard.dmm @@ -90,11 +90,11 @@ /obj/structure/stone_tile/surrounding_tile{ dir = 8 }, -/turf/open/indestructible/necropolis, +/turf/open/indestructible/necropolis/air, /area/lavaland/surface/outdoors) "l" = ( /obj/structure/stone_tile/block/cracked, -/turf/open/indestructible/necropolis, +/turf/open/indestructible/necropolis/air, /area/lavaland/surface/outdoors) "m" = ( /obj/structure/stone_tile/surrounding_tile/cracked, @@ -105,7 +105,7 @@ /obj/structure/stone_tile/surrounding_tile{ dir = 8 }, -/turf/open/indestructible/necropolis, +/turf/open/indestructible/necropolis/air, /area/lavaland/surface/outdoors) "n" = ( /obj/structure/stone_tile/block/cracked{ @@ -136,14 +136,14 @@ }, /obj/structure/table/bronze, /obj/item/disk/design_disk/adv/knight_gear, -/turf/open/indestructible/necropolis, +/turf/open/indestructible/necropolis/air, /area/lavaland/surface/outdoors) "q" = ( /obj/structure/table/bronze, /obj/item/stack/sheet/mineral/runite{ amount = 5 }, -/turf/open/indestructible/necropolis, +/turf/open/indestructible/necropolis/air, /area/lavaland/surface/outdoors) "r" = ( /obj/structure/stone_tile/block{ @@ -153,7 +153,7 @@ /obj/item/stack/sheet/mineral/runite{ amount = 5 }, -/turf/open/indestructible/necropolis, +/turf/open/indestructible/necropolis/air, /area/lavaland/surface/outdoors) "s" = ( /obj/structure/stone_tile/block{ @@ -186,13 +186,13 @@ /obj/structure/stone_tile/surrounding_tile{ dir = 1 }, -/turf/open/indestructible/necropolis, +/turf/open/indestructible/necropolis/air, /area/lavaland/surface/outdoors) "v" = ( /obj/structure/stone_tile/block{ dir = 1 }, -/turf/open/indestructible/necropolis, +/turf/open/indestructible/necropolis/air, /area/lavaland/surface/outdoors) "w" = ( /obj/structure/stone_tile/surrounding_tile/cracked{ @@ -205,7 +205,7 @@ /obj/structure/stone_tile/surrounding_tile{ dir = 4 }, -/turf/open/indestructible/necropolis, +/turf/open/indestructible/necropolis/air, /area/lavaland/surface/outdoors) "x" = ( /obj/structure/stone_tile/block{ diff --git a/_maps/RandomRuins/SpaceRuins/spacehermit.dmm b/_maps/RandomRuins/SpaceRuins/spacehermit.dmm index 791aac277d..c95e0c7539 100644 --- a/_maps/RandomRuins/SpaceRuins/spacehermit.dmm +++ b/_maps/RandomRuins/SpaceRuins/spacehermit.dmm @@ -5,9 +5,6 @@ "ab" = ( /turf/closed/mineral/random/low_chance, /area/ruin/unpowered) -"ac" = ( -/turf/open/floor/plating/asteroid, -/area/ruin/unpowered) "ad" = ( /obj/machinery/hydroponics/soil, /turf/open/floor/plating/asteroid, @@ -327,9 +324,6 @@ /obj/item/flashlight/lamp/bananalamp, /turf/open/floor/plating/asteroid, /area/ruin/powered) -"bt" = ( -/turf/closed/mineral/random/low_chance/earth_like, -/area/ruin/unpowered) "bC" = ( /obj/item/pickaxe/titanium, /turf/open/floor/plating/asteroid, @@ -396,7 +390,7 @@ aa aa aa aa -ac +aA aO aA aA @@ -2648,7 +2642,7 @@ aa aa aa aa -ac +aA aa aa aa @@ -2699,9 +2693,9 @@ aa aa aa aa -ac +aA ab -ac +aA aa aa "} @@ -2855,9 +2849,9 @@ aa aa aa aa -ac +aA ab -ac +aA aa aa "} @@ -2907,7 +2901,7 @@ aa aa aa aa -ac +aA aa aa aa @@ -2959,7 +2953,7 @@ aa aa aa aa -bt +ab aa aa aa diff --git a/_maps/map_files/BoxStation/BoxStation.dmm b/_maps/map_files/BoxStation/BoxStation.dmm index d91dd5b7c8..9877f5b259 100644 --- a/_maps/map_files/BoxStation/BoxStation.dmm +++ b/_maps/map_files/BoxStation/BoxStation.dmm @@ -13347,7 +13347,6 @@ pixel_y = 32 }, /obj/structure/sink{ - dir = 1; pixel_y = 25 }, /obj/machinery/button/door{ @@ -14233,7 +14232,6 @@ pixel_y = 32 }, /obj/structure/sink{ - dir = 1; pixel_y = 25 }, /obj/machinery/button/door{ @@ -21718,7 +21716,6 @@ pixel_y = 32 }, /obj/structure/sink{ - dir = 1; pixel_y = 25 }, /obj/machinery/button/door{ @@ -53437,6 +53434,7 @@ "dfh" = ( /obj/machinery/power/apc{ areastring = "/area/science/circuit"; + dir = 4; name = "Circuitry Lab APC"; pixel_x = 30 }, @@ -54387,6 +54385,7 @@ /obj/structure/chair/office/dark{ dir = 1 }, +/obj/effect/landmark/start/atmospheric_technician, /turf/open/floor/plasteel, /area/engine/atmos) "fMp" = ( @@ -54776,7 +54775,6 @@ dir = 8 }, /obj/structure/sink{ - dir = 1; pixel_y = 25 }, /obj/structure/mirror{ @@ -57075,6 +57073,7 @@ dir = 4; pixel_y = 5 }, +/obj/item/clothing/head/hardhat/cakehat, /turf/open/floor/wood, /area/crew_quarters/bar) "oby" = ( @@ -57198,7 +57197,6 @@ dir = 8 }, /obj/structure/sink{ - dir = 1; pixel_y = 25 }, /obj/structure/mirror{ @@ -57847,7 +57845,6 @@ pixel_y = 32 }, /obj/structure/sink{ - dir = 1; pixel_y = 25 }, /turf/open/floor/mineral/titanium/blue, @@ -57910,7 +57907,6 @@ pixel_y = 32 }, /obj/structure/sink{ - dir = 1; pixel_y = 25 }, /obj/machinery/light/small{ @@ -60673,7 +60669,6 @@ pixel_y = 32 }, /obj/structure/sink{ - dir = 1; pixel_y = 25 }, /obj/machinery/button/door{ diff --git a/_maps/map_files/Deltastation/DeltaStation2.dmm b/_maps/map_files/Deltastation/DeltaStation2.dmm index db191d5b2d..61ecaddddc 100644 --- a/_maps/map_files/Deltastation/DeltaStation2.dmm +++ b/_maps/map_files/Deltastation/DeltaStation2.dmm @@ -288,6 +288,15 @@ dir = 4 }, /obj/item/toy/poolnoodle/red, +/obj/machinery/power/apc{ + areastring = "/area/crew_quarters/fitness/pool"; + dir = 1; + name = "Pool APC"; + pixel_y = 24 + }, +/obj/structure/cable/white{ + icon_state = "0-4" + }, /turf/open/floor/plasteel/dark, /area/crew_quarters/fitness/pool) "aaH" = ( @@ -492,8 +501,8 @@ dir = 4 }, /turf/open/floor/plasteel/yellowsiding/corner{ - icon_state = "yellowcornersiding"; - dir = 8 + dir = 8; + icon_state = "yellowcornersiding" }, /area/crew_quarters/fitness/pool) "aba" = ( @@ -510,8 +519,8 @@ dir = 8 }, /turf/open/floor/plasteel/yellowsiding{ - icon_state = "yellowsiding"; - dir = 4 + dir = 4; + icon_state = "yellowsiding" }, /area/crew_quarters/fitness/pool) "abb" = ( @@ -604,8 +613,8 @@ dir = 4 }, /turf/open/floor/plasteel/yellowsiding{ - icon_state = "yellowsiding"; - dir = 8 + dir = 8; + icon_state = "yellowsiding" }, /area/crew_quarters/fitness/pool) "abn" = ( @@ -619,8 +628,8 @@ dir = 8 }, /turf/open/floor/plasteel/yellowsiding{ - icon_state = "yellowsiding"; - dir = 4 + dir = 4; + icon_state = "yellowsiding" }, /area/crew_quarters/fitness/pool) "abo" = ( @@ -704,8 +713,8 @@ name = "pool camera" }, /turf/open/floor/plasteel/yellowsiding{ - icon_state = "yellowsiding"; - dir = 4 + dir = 4; + icon_state = "yellowsiding" }, /area/crew_quarters/fitness/pool) "abv" = ( @@ -724,8 +733,8 @@ dir = 4 }, /turf/open/floor/plasteel/yellowsiding{ - icon_state = "yellowsiding"; - dir = 8 + dir = 8; + icon_state = "yellowsiding" }, /area/crew_quarters/fitness/pool) "aby" = ( @@ -765,8 +774,8 @@ dir = 8 }, /turf/open/floor/plasteel/yellowsiding{ - icon_state = "yellowsiding"; - dir = 4 + dir = 4; + icon_state = "yellowsiding" }, /area/crew_quarters/fitness/pool) "abC" = ( @@ -904,8 +913,8 @@ pixel_x = -23 }, /turf/open/floor/plasteel/yellowsiding{ - icon_state = "yellowsiding"; - dir = 4 + dir = 4; + icon_state = "yellowsiding" }, /area/crew_quarters/fitness/pool) "abP" = ( @@ -972,8 +981,8 @@ pixel_x = -26 }, /turf/open/floor/plasteel/yellowsiding/corner{ - icon_state = "yellowcornersiding"; - dir = 4 + dir = 4; + icon_state = "yellowcornersiding" }, /area/crew_quarters/fitness/pool) "abW" = ( @@ -982,8 +991,8 @@ dir = 8 }, /turf/open/floor/plasteel/yellowsiding{ - icon_state = "yellowsiding"; - dir = 1 + dir = 1; + icon_state = "yellowsiding" }, /area/crew_quarters/fitness/pool) "abX" = ( @@ -995,8 +1004,8 @@ dir = 4 }, /turf/open/floor/plasteel/yellowsiding/corner{ - icon_state = "yellowcornersiding"; - dir = 1 + dir = 1; + icon_state = "yellowcornersiding" }, /area/crew_quarters/fitness/pool) "abY" = ( @@ -31108,6 +31117,11 @@ /obj/effect/turf_decal/tile/green{ dir = 8 }, +/obj/machinery/power/apc{ + areastring = "/area/hydroponics"; + name = "Hydroponics APC"; + pixel_y = -24 + }, /turf/open/floor/plasteel, /area/hydroponics) "beS" = ( @@ -64485,8 +64499,8 @@ /area/library) "cel" = ( /obj/structure/chair/sofa/right{ - icon_state = "sofaend_right"; - dir = 8 + dir = 8; + icon_state = "sofaend_right" }, /obj/structure/sign/painting/library{ pixel_x = 32 @@ -92830,6 +92844,9 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/structure/cable/white{ + icon_state = "1-2" + }, /turf/open/floor/plasteel, /area/crew_quarters/fitness/recreation) "dad" = ( @@ -101794,6 +101811,13 @@ /obj/effect/turf_decal/tile/purple{ dir = 4 }, +/obj/structure/cable/white, +/obj/machinery/power/apc{ + areastring = "/area/science/misc_lab"; + dir = 4; + name = "Science Lounge APC"; + pixel_x = 26 + }, /turf/open/floor/plasteel/white, /area/science/misc_lab) "dqi" = ( @@ -113343,6 +113367,7 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/machinery/light/small, /turf/open/floor/plasteel/dark/telecomms, /area/science/server) "dKg" = ( @@ -125579,6 +125604,20 @@ }, /turf/open/floor/plasteel/dark, /area/science/mixing) +"ePP" = ( +/obj/machinery/door/firedoor, +/obj/effect/turf_decal/stripes/line, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/machinery/door/airlock/public/glass{ + name = "Pool" + }, +/obj/structure/cable/white{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel, +/area/crew_quarters/fitness/pool) "eTv" = ( /obj/effect/turf_decal/stripes/line{ dir = 8 @@ -127072,6 +127111,25 @@ }, /turf/open/floor/plasteel, /area/science/research/abandoned) +"pQQ" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/structure/cable/white{ + icon_state = "1-8" + }, +/turf/open/floor/plasteel/dark, +/area/crew_quarters/fitness/pool) "pWb" = ( /obj/structure/table/wood/fancy, /obj/structure/window/reinforced{ @@ -127298,6 +127356,24 @@ }, /turf/open/floor/plasteel, /area/science/circuit) +"tqP" = ( +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/structure/cable/white{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel{ + heat_capacity = 1e+006 + }, +/area/crew_quarters/fitness/recreation) "twt" = ( /obj/machinery/vr_sleeper, /obj/effect/turf_decal/tile/neutral{ @@ -127768,8 +127844,8 @@ /area/science/mixing) "xER" = ( /obj/structure/chair/sofa/left{ - icon_state = "sofaend_left"; - dir = 8 + dir = 8; + icon_state = "sofaend_left" }, /turf/open/floor/wood, /area/library) @@ -127849,6 +127925,22 @@ /obj/structure/fans/tiny/invisible, /turf/open/space/basic, /area/space) +"yfK" = ( +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/structure/cable/white{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel, +/area/crew_quarters/fitness/recreation) "yiv" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/tile/neutral{ @@ -181500,10 +181592,10 @@ cCl cWD cAz dac -cxy -aav -aaz -aaH +yfK +tqP +ePP +pQQ aaV aaN aaN diff --git a/_maps/map_files/KiloStation/KiloStation.dmm b/_maps/map_files/KiloStation/KiloStation.dmm index bf8c332cf0..fbe5b954ff 100644 --- a/_maps/map_files/KiloStation/KiloStation.dmm +++ b/_maps/map_files/KiloStation/KiloStation.dmm @@ -30475,6 +30475,7 @@ /obj/machinery/light{ dir = 1 }, +/obj/machinery/airalarm/directional/north, /turf/open/floor/plasteel/dark, /area/science/research) "aXx" = ( @@ -57345,9 +57346,7 @@ name = "landing marker"; picked_color = "Burgundy" }, -/turf/open/floor/plating/airless{ - initial_gas_mix = "o2=14;n2=23;TEMP=300" - }, +/turf/open/floor/plating/airless, /area/hallway/secondary/entry) "bOe" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer1{ @@ -58565,9 +58564,7 @@ dir = 4 }, /obj/effect/decal/cleanable/dirt, -/turf/open/floor/plating/airless{ - initial_gas_mix = "o2=14;n2=23;TEMP=300" - }, +/turf/open/floor/plating/airless, /area/hallway/secondary/entry) "bQb" = ( /obj/structure/flora/rock, @@ -58930,7 +58927,7 @@ dir = 8 }, /obj/machinery/power/apc{ - areastring = "/area/janitor"; + areastring = "/area/vacant_room/commissary"; dir = 4; name = "Vacant Commissary APC"; pixel_x = 27; @@ -61285,9 +61282,7 @@ name = "landing marker"; picked_color = "Burgundy" }, -/turf/open/floor/plating/airless{ - initial_gas_mix = "o2=14;n2=23;TEMP=300" - }, +/turf/open/floor/plating/airless, /area/hallway/secondary/entry) "bUk" = ( /obj/effect/turf_decal/tile/red, @@ -61567,9 +61562,7 @@ /turf/closed/wall, /area/engine/atmos) "bUN" = ( -/turf/open/floor/plating/airless{ - initial_gas_mix = "o2=14;n2=23;TEMP=300" - }, +/turf/open/floor/plating/airless, /area/hallway/secondary/entry) "bUP" = ( /obj/machinery/door/airlock/external{ @@ -67994,9 +67987,7 @@ name = "landing marker"; picked_color = "Burgundy" }, -/turf/open/floor/plating/airless{ - initial_gas_mix = "o2=14;n2=23;TEMP=300" - }, +/turf/open/floor/plating/airless, /area/hallway/secondary/entry) "ceV" = ( /obj/effect/turf_decal/tile/yellow{ @@ -68021,18 +68012,14 @@ dir = 1 }, /obj/effect/decal/cleanable/dirt, -/turf/open/floor/plating/airless{ - initial_gas_mix = "o2=14;n2=23;TEMP=300" - }, +/turf/open/floor/plating/airless, /area/hallway/secondary/entry) "ceX" = ( /obj/machinery/light{ dir = 8 }, /obj/effect/decal/cleanable/dirt, -/turf/open/floor/plating/airless{ - initial_gas_mix = "o2=14;n2=23;TEMP=300" - }, +/turf/open/floor/plating/airless, /area/hallway/secondary/entry) "ceY" = ( /obj/machinery/airalarm{ @@ -68880,9 +68867,7 @@ /area/engine/engineering) "cgI" = ( /obj/effect/decal/cleanable/dirt, -/turf/open/floor/plating/airless{ - initial_gas_mix = "o2=14;n2=23;TEMP=300" - }, +/turf/open/floor/plating/airless, /area/hallway/secondary/entry) "cgJ" = ( /obj/machinery/door/poddoor/preopen, @@ -80506,9 +80491,7 @@ /area/maintenance/fore) "cDp" = ( /obj/structure/lattice/catwalk, -/turf/open/floor/plating/airless{ - initial_gas_mix = "o2=14;n2=23;TEMP=300" - }, +/turf/open/floor/plating/airless, /area/hallway/secondary/entry) "cDq" = ( /obj/machinery/door/airlock/maintenance{ @@ -80896,9 +80879,6 @@ pixel_x = 4; pixel_y = 4 }, -/obj/item/storage/pill_bottle/dice{ - pixel_x = -4 - }, /obj/item/pen/red{ pixel_x = 4; pixel_y = 4 @@ -84920,9 +84900,7 @@ "jAT" = ( /obj/structure/lattice/catwalk, /obj/machinery/light, -/turf/open/floor/plating/airless{ - initial_gas_mix = "o2=14;n2=23;TEMP=300" - }, +/turf/open/floor/plating/airless, /area/hallway/secondary/entry) "jHJ" = ( /obj/machinery/atmospherics/pipe/simple/general/visible{ @@ -85370,9 +85348,7 @@ "rNm" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/lattice/catwalk, -/turf/open/floor/plating/airless{ - initial_gas_mix = "o2=14;n2=23;TEMP=300" - }, +/turf/open/floor/plating/airless, /area/hallway/secondary/entry) "swG" = ( /obj/item/reagent_containers/food/drinks/drinkingglass{ diff --git a/_maps/map_files/generic/City_of_Cogs.dmm b/_maps/map_files/generic/City_of_Cogs.dmm index 1195ad62c5..9ef765aa28 100644 --- a/_maps/map_files/generic/City_of_Cogs.dmm +++ b/_maps/map_files/generic/City_of_Cogs.dmm @@ -10,20 +10,10 @@ /obj/structure/grille/ratvar, /turf/open/indestructible/reebe_void, /area/reebe) -"ad" = ( -/obj/structure/lattice/clockwork, -/obj/item/clockwork/component/belligerent_eye/blind_eye, -/turf/open/indestructible/reebe_void, -/area/reebe) "ae" = ( /obj/structure/lattice/clockwork, /turf/open/indestructible/reebe_void, /area/reebe) -"af" = ( -/obj/structure/lattice/clockwork, -/obj/item/clockwork/component/geis_capacitor/antennae, -/turf/open/indestructible/reebe_void, -/area/reebe) "ag" = ( /obj/structure/lattice/catwalk/clockwork, /turf/open/indestructible/reebe_void, @@ -39,14 +29,6 @@ "aj" = ( /turf/open/floor/clockwork/reebe, /area/reebe/city_of_cogs) -"ak" = ( -/obj/structure/destructible/clockwork/massive/celestial_gateway, -/turf/open/floor/clockwork/reebe, -/area/reebe/city_of_cogs) -"al" = ( -/obj/machinery/sleeper/clockwork, -/turf/open/floor/clockwork/reebe, -/area/reebe/city_of_cogs) "an" = ( /obj/structure/noticeboard, /obj/item/paper/fluff/ruins/djstation{ @@ -64,10 +46,6 @@ }, /turf/open/floor/clockwork/reebe, /area/reebe/city_of_cogs) -"aq" = ( -/obj/machinery/computer/camera_advanced/ratvar, -/turf/open/floor/clockwork/reebe, -/area/reebe/city_of_cogs) "ar" = ( /obj/structure/closet/wardrobe/mixed, /turf/open/floor/clockwork/reebe, @@ -96,12 +74,6 @@ }, /turf/open/floor/clockwork/reebe, /area/reebe/city_of_cogs) -"ax" = ( -/obj/structure/chair/brass{ - dir = 1 - }, -/turf/open/floor/clockwork/reebe, -/area/reebe/city_of_cogs) "ay" = ( /obj/machinery/door/airlock/clockwork/brass{ name = "Dressing Room" @@ -109,7 +81,7 @@ /turf/open/floor/clockwork/reebe, /area/reebe/city_of_cogs) "az" = ( -/obj/structure/destructible/clockwork/heralds_beacon, +/obj/structure/destructible/clockwork/eminence_spire, /turf/open/floor/clockwork/reebe, /area/reebe/city_of_cogs) "aA" = ( @@ -118,17 +90,6 @@ }, /turf/open/floor/clockwork/reebe, /area/reebe/city_of_cogs) -"aB" = ( -/obj/structure/table/reinforced/brass, -/obj/item/clockwork/construct_chassis/cogscarab, -/turf/open/floor/clockwork/reebe, -/area/reebe/city_of_cogs) -"aC" = ( -/obj/machinery/sleeper/clockwork{ - dir = 1 - }, -/turf/open/floor/clockwork/reebe, -/area/reebe/city_of_cogs) "aD" = ( /obj/machinery/door/airlock/clockwork/brass{ name = "Listening Station" @@ -149,15 +110,6 @@ opacity = 0 }, /area/reebe/city_of_cogs) -"aH" = ( -/obj/effect/landmark/servant_of_ratvar, -/turf/open/floor/clockwork/reebe, -/area/reebe/city_of_cogs) -"aI" = ( -/obj/structure/table/reinforced/brass, -/obj/item/clockwork/slab, -/turf/open/floor/clockwork/reebe, -/area/reebe/city_of_cogs) "aJ" = ( /obj/structure/table/reinforced/brass, /obj/item/screwdriver/brass, @@ -182,162 +134,22 @@ /obj/item/weldingtool/experimental/brass, /turf/open/floor/clockwork/reebe, /area/reebe/city_of_cogs) -"aO" = ( -/obj/structure/lattice/catwalk/clockwork, -/obj/item/clockwork/component/belligerent_eye/lens_gem, -/turf/open/indestructible/reebe_void, -/area/reebe) -"aP" = ( -/obj/structure/lattice/catwalk/clockwork, -/obj/item/clockwork/component/hierophant_ansible/obelisk, -/turf/open/indestructible/reebe_void, -/area/reebe) -"aQ" = ( -/obj/structure/lattice/clockwork, -/obj/item/clockwork/alloy_shards/clockgolem_remains, -/turf/open/indestructible/reebe_void, -/area/reebe) -"aR" = ( -/obj/effect/landmark/city_of_cogs, -/turf/open/indestructible/clock_spawn_room, -/area/reebe/city_of_cogs) "aS" = ( -/obj/effect/clockwork/servant_blocker{ - dir = 1 - }, -/obj/structure/lattice/catwalk/clockwork, -/turf/open/indestructible/reebe_void, -/area/reebe/city_of_cogs) -"aT" = ( -/turf/open/indestructible/clock_spawn_room, -/area/reebe/city_of_cogs) -"aU" = ( -/obj/structure/grille/ratvar, -/obj/structure/window/reinforced/clockwork/fulltile, -/turf/open/indestructible/clock_spawn_room, -/area/reebe/city_of_cogs) -"aV" = ( -/obj/machinery/door/airlock/clockwork/brass, -/turf/open/indestructible/clock_spawn_room, -/area/reebe/city_of_cogs) -"aW" = ( -/obj/item/clockwork/component/replicant_alloy/replication_plate, -/turf/open/indestructible/reebe_void/spawning/lattices, -/area/reebe) -"aX" = ( -/obj/structure/table/reinforced/brass, -/obj/item/clockwork/component/belligerent_eye, -/turf/open/indestructible/clock_spawn_room, -/area/reebe/city_of_cogs) -"aY" = ( -/obj/effect/clockwork/servant_blocker{ - dir = 1 - }, -/obj/structure/lattice/clockwork, -/turf/open/indestructible/reebe_void, -/area/reebe) -"aZ" = ( -/obj/structure/table/reinforced/brass, -/obj/item/clockwork/component/belligerent_eye/blind_eye, -/turf/open/indestructible/clock_spawn_room, -/area/reebe/city_of_cogs) -"ba" = ( -/obj/structure/table/reinforced/brass, -/obj/item/clockwork/component/belligerent_eye/lens_gem, -/turf/open/indestructible/clock_spawn_room, -/area/reebe/city_of_cogs) -"bb" = ( -/obj/structure/table/reinforced/brass, -/obj/item/clockwork/component/geis_capacitor, -/turf/open/indestructible/clock_spawn_room, -/area/reebe/city_of_cogs) -"bc" = ( -/obj/structure/table/reinforced/brass, -/obj/item/clockwork/component/geis_capacitor/antennae, -/turf/open/indestructible/clock_spawn_room, -/area/reebe/city_of_cogs) -"bd" = ( -/obj/structure/table/reinforced/brass, -/obj/item/clockwork/component/geis_capacitor/fallen_armor, -/turf/open/indestructible/clock_spawn_room, -/area/reebe/city_of_cogs) -"be" = ( -/obj/structure/table/reinforced/brass, -/obj/item/clockwork/component/hierophant_ansible, -/turf/open/indestructible/clock_spawn_room, -/area/reebe/city_of_cogs) -"bf" = ( -/obj/structure/table/reinforced/brass, /obj/item/clockwork/component/hierophant_ansible/obelisk, -/turf/open/indestructible/clock_spawn_room, -/area/reebe/city_of_cogs) -"bg" = ( -/obj/structure/table/reinforced/brass, -/obj/item/clockwork/component/replicant_alloy, -/turf/open/indestructible/clock_spawn_room, -/area/reebe/city_of_cogs) -"bh" = ( -/obj/structure/lattice/catwalk/clockwork, -/obj/item/clockwork/integration_cog, -/turf/open/indestructible/reebe_void, -/area/reebe) -"bi" = ( -/obj/structure/lattice/catwalk/clockwork, -/obj/item/clockwork/component/vanguard_cogwheel/onyx_prism, -/turf/open/indestructible/reebe_void, -/area/reebe) -"bj" = ( -/obj/structure/destructible/clockwork/eminence_spire, /turf/open/floor/clockwork/reebe, -/area/reebe/city_of_cogs) -"bk" = ( -/obj/structure/table/reinforced/brass, -/obj/item/clockwork/component/replicant_alloy/replication_plate, -/turf/open/indestructible/clock_spawn_room, -/area/reebe/city_of_cogs) -"bl" = ( -/obj/structure/table/reinforced/brass, -/obj/item/clockwork/component/replicant_alloy/smashed_anima_fragment, -/turf/open/indestructible/clock_spawn_room, -/area/reebe/city_of_cogs) -"bm" = ( -/obj/structure/table/reinforced/brass, -/obj/item/clockwork/component/vanguard_cogwheel, -/turf/open/indestructible/clock_spawn_room, -/area/reebe/city_of_cogs) -"bn" = ( -/obj/structure/table/reinforced/brass, -/obj/item/clockwork/component/vanguard_cogwheel/onyx_prism, -/turf/open/indestructible/clock_spawn_room, -/area/reebe/city_of_cogs) -"bo" = ( -/obj/structure/window/reinforced/clockwork/fulltile, -/obj/structure/grille/ratvar, -/turf/open/indestructible/clock_spawn_room, -/area/reebe/city_of_cogs) -"bp" = ( -/obj/structure/window/reinforced/clockwork/fulltile, -/turf/open/indestructible/clock_spawn_room, -/area/reebe/city_of_cogs) +/area/reebe) +"aT" = ( +/obj/item/clockwork/component/geis_capacitor/antennae, +/turf/open/floor/clockwork/reebe, +/area/reebe) "bt" = ( /obj/structure/table/bronze, /turf/open/floor/clockwork/reebe, /area/reebe/city_of_cogs) -"bu" = ( -/obj/structure/table/reinforced/brass, -/turf/open/indestructible/clock_spawn_room, -/area/reebe/city_of_cogs) -"bw" = ( -/obj/structure/chair/brass{ - dir = 8 - }, -/turf/open/indestructible/clock_spawn_room, -/area/reebe/city_of_cogs) -"bx" = ( -/obj/structure/chair/brass{ - dir = 4 - }, -/turf/open/indestructible/clock_spawn_room, +"bC" = ( +/obj/structure/table/bronze, +/obj/item/storage/belt/utility/servant, +/turf/open/floor/clockwork/reebe, /area/reebe/city_of_cogs) "bE" = ( /obj/structure/table/reinforced/brass, @@ -348,53 +160,114 @@ /obj/item/healthanalyzer/advanced, /turf/open/floor/clockwork/reebe, /area/reebe/city_of_cogs) -"eV" = ( -/obj/structure/chair/stool/bar/brass, -/turf/open/indestructible/clock_spawn_room, +"dl" = ( +/turf/open/floor/clockwork/reebe, +/area/reebe) +"dx" = ( +/obj/structure/destructible/clockwork/powered/clockwork_obelisk, +/obj/effect/clockwork/sigil/transmission, +/turf/open/floor/clockwork/reebe, /area/reebe/city_of_cogs) -"nj" = ( -/obj/structure/table/bronze, -/turf/open/indestructible/clock_spawn_room, +"ew" = ( +/obj/structure/table/reinforced/brass, +/obj/item/clockwork/construct_chassis/cogscarab{ + pixel_y = 20 + }, +/obj/item/clockwork/construct_chassis/cogscarab{ + pixel_x = -7; + pixel_y = 6 + }, +/obj/item/clockwork/construct_chassis/cogscarab{ + pixel_x = 7; + pixel_y = 6 + }, +/turf/open/floor/clockwork/reebe, /area/reebe/city_of_cogs) -"ww" = ( -/obj/structure/table/bronze, -/obj/item/camera_film, -/turf/open/indestructible/clock_spawn_room, -/area/reebe/city_of_cogs) -"xH" = ( -/obj/structure/chair/stool/brass, -/turf/open/indestructible/clock_spawn_room, -/area/reebe/city_of_cogs) -"ym" = ( -/obj/structure/table/bronze, +"hY" = ( +/obj/item/clockwork/alloy_shards/pinion_lock, +/turf/open/floor/clockwork/reebe, +/area/reebe) +"nX" = ( +/obj/item/clockwork/alloy_shards/clockgolem_remains, +/obj/item/clockwork/weapon/ratvarian_spear, +/obj/item/clockwork/alloy_shards/pinion_lock, +/turf/open/floor/clockwork/reebe, +/area/reebe) +"om" = ( +/obj/item/clockwork/component/replicant_alloy/smashed_anima_fragment, +/obj/item/clockwork/component/geis_capacitor/fallen_armor, +/turf/open/floor/clockwork/reebe, +/area/reebe) +"sW" = ( +/obj/structure/table/reinforced/brass, +/obj/item/storage/belt/utility/servant, +/obj/item/storage/belt/utility/servant, +/obj/item/storage/belt/utility/servant, +/obj/item/storage/belt/utility/servant, /obj/item/storage/belt/utility/servant, /obj/item/storage/belt/utility/servant, /turf/open/floor/clockwork/reebe, /area/reebe/city_of_cogs) +"vx" = ( +/obj/effect/clockwork/sigil/transmission, +/turf/open/floor/clockwork/reebe, +/area/reebe/city_of_cogs) +"wV" = ( +/obj/item/clockwork/alloy_shards/large, +/turf/open/indestructible/reebe_void/spawning/lattices, +/area/reebe) +"xR" = ( +/obj/item/clockwork/alloy_shards/medium, +/turf/open/indestructible/reebe_void/spawning/lattices, +/area/reebe) +"yY" = ( +/obj/item/clockwork/alloy_shards/small, +/turf/open/floor/clockwork/reebe, +/area/reebe) "zb" = ( /turf/open/space/basic, /area/space) -"EE" = ( -/obj/structure/table/bronze, -/obj/item/camera, -/turf/open/indestructible/clock_spawn_room, +"Fd" = ( +/obj/item/clockwork/alloy_shards/clockgolem_remains, +/turf/open/floor/clockwork/reebe, +/area/reebe) +"Fj" = ( +/obj/machinery/sleeper/syndie/fullupgrade{ + desc = "A large cryogenics unit built from brass. Its surface is pleasantly cool the touch."; + enter_message = "You hear the gentle hum and click of machinery, and are lulled into a sense of peace."; + icon_state = "sleeper_clockwork"; + name = "soothing sleeper" + }, +/turf/open/floor/clockwork/reebe, /area/reebe/city_of_cogs) -"NH" = ( -/obj/structure/table/bronze, -/obj/item/taperecorder, -/turf/open/indestructible/clock_spawn_room, -/area/reebe/city_of_cogs) -"VP" = ( +"Ia" = ( +/obj/item/clockwork/alloy_shards/small, +/turf/open/indestructible/reebe_void/spawning/lattices, +/area/reebe) +"OB" = ( +/obj/item/clockwork/component/geis_capacitor/fallen_armor, +/turf/open/floor/clockwork/reebe, +/area/reebe) +"Rw" = ( /obj/structure/table/reinforced/brass, -/obj/item/clockwork/slab, -/obj/item/clockwork/slab, -/obj/item/clockwork/slab, -/obj/item/clockwork/slab, -/obj/item/clockwork/slab, -/obj/item/clockwork/slab, -/obj/item/clockwork/slab, -/obj/item/clockwork/slab, -/obj/item/clockwork/slab, +/obj/item/clockwork/replica_fabricator, +/obj/item/clockwork/replica_fabricator, +/turf/open/floor/clockwork/reebe, +/area/reebe/city_of_cogs) +"Sr" = ( +/obj/item/clockwork/component/replicant_alloy/smashed_anima_fragment, +/turf/open/floor/clockwork/reebe, +/area/reebe) +"TH" = ( +/obj/structure/lattice/catwalk/clockwork, +/turf/open/indestructible/reebe_void/spawning/lattices, +/area/reebe/city_of_cogs) +"Wv" = ( +/obj/item/clockwork/component/belligerent_eye/blind_eye, +/turf/open/floor/clockwork/reebe, +/area/reebe) +"WA" = ( +/obj/effect/clockwork/sigil/vitality, /turf/open/floor/clockwork/reebe, /area/reebe/city_of_cogs) "WT" = ( @@ -24671,7 +24544,7 @@ aa aa aa aa -ab +aa aa aa aa @@ -24908,58 +24781,58 @@ 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 -aF -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 +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 @@ -25155,76 +25028,76 @@ 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 -aF -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 +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa aa aa aa @@ -25411,78 +25284,78 @@ 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 -aF -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 +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa aa aa aa @@ -25668,79 +25541,79 @@ aa aa aa aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ae -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aF -ab -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 +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa aa aa aa @@ -25925,80 +25798,80 @@ 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 -ac -ae -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aF -ab -ab -ab -ab -ab -ab -aW -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 +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa aa aa aa @@ -26182,81 +26055,81 @@ aa aa aa aa -ab -ab -ab -ae -af -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ae -ab -aP -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aF -ab -ab -ab -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 +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa aa aa aa @@ -26439,82 +26312,82 @@ aa aa aa aa -ab -ab -ab -ab -ac -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aF -ab -ab -ab -ab -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 +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa aa aa aa @@ -26696,83 +26569,83 @@ 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 -aF -ab -ab -ab -ab -ab -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 +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa aa aa aa @@ -26953,84 +26826,84 @@ aa aa aa aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ae -ae -ae -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aF -aF -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ae -ae -ae -ae -ae -ae -ae -ae -ae -ae -ae -ae -ae -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 +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa aa aa aa @@ -27210,85 +27083,85 @@ aa aa aa aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ae -ag -ag -ag -ae -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aF -aF -aF -aF -aF -aF -aF -aF -aF -aF -aF -aG -aY -ae -ae -ae -ae -ae -ae -ae -ae -ae -ae -ae -ae -ah -ah -bo -bo -bo -bo -bo -bo -bo -ah -ah -ae -ae -ae -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 +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa aa aa aa @@ -27467,85 +27340,85 @@ aa aa aa aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ae -ag -ag -ag -ae -aF -aF -aF -aF -aF -aF -aF -aF -aF -aF -aF -aF -aF -aF -aF -aF -aF -aF -aF -aF -aF -aF -aF -aF -aF -aF -aF -aF -aF -aG -aS -ah -ah -ah -ah -ah -ah -ah -ah -ah -ah -ah -ah -ah -aT -aT -aT -aT -aT -aT -aT -nj -nj -ah -ah -ah -ae -ae -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 +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa aa aa aa @@ -27724,6 +27597,31 @@ aa aa aa aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa ab ab ab @@ -27733,76 +27631,51 @@ ab ab ab ab -ab -ab -ab -ah -ah -ai -ah -ah -aG -aG -aG -aG -aG -aG -aG -aG -aG -aG -aG -aG -aG -aG -aG -aG -aG -aG -aG -aG -aG -aG -aG -aG -aG -aG -aG -aG -aG -aj -aS -bu -bu -bu -bu -bu -bu -bu -bu -bu -bu -bu -bu -aU -aT -aT -aT -aT -aT -aT -aT -xH -EE -bo -aX -bo -ag +ae +ae ae ab ab ab ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aF +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa aa aa aa @@ -27974,6 +27847,38 @@ aa aa aa aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa ab ab ab @@ -27982,84 +27887,52 @@ ab ab ab ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ah -ar -aj -bt -ah -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aS -bw -bw -bw -bw -bw -bw -bw -bw -bw -bw -bw -bw -aU -aT -aT -aR -aT -aR -aT -aR -eV -NH -bo -aZ -bo +ae +ag +ag ag ae ab ab ab ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aF +aF +aF +aF +aF +aF +aF +aF +aF +aF +aF +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa aa aa aa @@ -28231,6 +28104,38 @@ aa aa aa aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa ab ab ab @@ -28239,84 +28144,52 @@ ab ab ab ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ah -as -aj -aj -ay -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aS -aT -aT -aT -aT -aT -aT -aT -aT -aT -aT -aT -aT -bo -aT -aT -aT -aT -aT -aT -aT -xH -nj -bo -ba -bo +ae +ag +ag ag ae -bi -ab +aF +aF +aF +aF +aF +aF +aF +aF +aF +aF +aF ab ab +aF +aF +aF +aF +aF +aF +aF +aF +aF +aF +aF +aF +aF +aF +aF +aF +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa aa aa aa @@ -28488,17 +28361,38 @@ aa aa aa aa -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 +aa +aa +aa +aa +aa ab ab ab @@ -28508,72 +28402,51 @@ ab ab ab ah -VP -aj -ym ah -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aS -aT -aT -aT -aT -aT -aT -aT -aT -aT -aT -aT -aT -aV -aT -aT -aR -aT -aR -aT -aR -eV -nj -bo -bb -bo -ag -ae +ai +ah +ah +aG +aG +aG +aG +aG +aG +aG +aF ab -ae -ac ab +ab +ab +ab +ab +aa +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 @@ -28745,17 +28618,38 @@ aa aa aa aa -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 +aa +aa +aa +aa +aa ab ab ab @@ -28765,9 +28659,9 @@ ab ab ab ah -ah -ay -ah +ar +aj +bt ah aj aj @@ -28775,62 +28669,41 @@ aj aj aj aj +TH aj aj aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aS -aT -aT -aT -aT -aT -aT -aT -aT -aT -aT -aT -aT -bo -aT -aT -aT -aT -aT -aT -aT -xH -ww -bo -bc -bo -ag -ae +aa +dl +ab +aa 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 @@ -29002,6 +28875,38 @@ aa aa aa aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa ab ab ab @@ -29010,84 +28915,52 @@ ab ab ab ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -an -au -aj -au ah +as +aj +aj +ay aj aj aj aj aj aj +TH aj aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aS -aT -aT -aT -aT -aT -aT -aT -aT -aT -aT -aT -aT -aU -aT -aT -aR -aT -aR -aT -aR -eV -nj -bo -bd -bo -ag -ae +aa +dl +aa +aa +ab +dl +ab +dl +dl +dl +ab +ab +dl ab ab ab ab +ab +ab +ab +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa aa aa aa @@ -29259,16 +29132,38 @@ aa aa aa aa -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 +aa +aa +aa +aa +aa ab ab ab @@ -29278,10 +29173,9 @@ ab ab ab ah -ah -av +aL aj -av +bC ah aj aj @@ -29289,62 +29183,41 @@ aj aj aj aj +TH +ab aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aS -aT -aT -aT -aT -aT -aT -aT -aT -aT -aT -aT -aT -aU -aT -aT -aT -aT -aT -aT -aT -xH -nj -bo -be -bo -ag -ae +aa +dl +aa +Wv +ab +Fd +yY +yY +dl +dl +dl ab ab ab ab +ab +ab +ab +ab +ab +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa aa aa aa @@ -29516,6 +29389,38 @@ aa aa aa aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa ab ab ab @@ -29524,84 +29429,52 @@ ab ab ab ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ae -ai -ao -aj -aj -aj -aD -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aS -aT -aT -aT -aT -aT -aT -aT -aT -aT -aT -bp -bp -ah -aT -aT -aT -aT -aT -aT -aT -EE -nj ah ah +ay ah -ae -ae +ah +aj +aj +aj +aj +aj +aj +aj +aj +aa +dl +ab +aa +Fd +ab +hY +Sr +dl +ab +ab +dl ab ab ab ab +ab +ab +ab +ab +ab +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa aa aa aa @@ -29773,6 +29646,38 @@ aa aa aa aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa ab ab ab @@ -29781,23 +29686,11 @@ ab ab ab ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ae +an +au +aj +au ah -ah -aw -aj -aw -ai -aH aj aj aj @@ -29806,59 +29699,39 @@ aj aj aj aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aS -aT -aT -aT -aT -aT -aT -aT -aT -aT -aT -bp -bg -ah -ah -bo -bo -bo -bo -bo -bo -bo -ah -ah -ae -ae -ae +aa +dl +aa +ab +ab +OB +ab +yY +dl 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 @@ -30030,6 +29903,38 @@ aa aa aa aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa ab ab ab @@ -30037,85 +29942,53 @@ ab ab ab ab -ab -ab -ab -ab -ab -ab -ab -ab -ae -ae -ag -ag -an -au -aj -au -ai -aI -aK -aH -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aS -aT -aT -aT -aT -aT -aT -aT -aT -aT -aT -bp -bp -ah -aT -aT -aT -aT -aT -aT -aT -ww -nj ah ah +av +aj +av ah -ae -ae +aj +aj +aj +aj +aj +aj +aj +aa +dl +dl +aa +aa +om +Fd ab ab ab ab +dl +dl +dl +dl +ab +ab +ab +ab +ab +ab +ab +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa aa aa aa @@ -30287,92 +30160,92 @@ aa aa aa aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa ab ab ab ab ab ab -ab -ab -ab -ab -ab -ab -ab -ah -ah -ah -ai -ah -ah -ah -ai -ap -ai -ah -aJ -aH -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aS -aT -aT -aT -aT -aT -aT -aT -aT -aT -aT -aT -aT -aU -aT -aT -aT -aT -aT -aT -aT -xH -nj -bo -bf -bo -ag ae +ai +ao +aj +aj +aj +aD +aj +aj +aj +aj +aj +aj +TH +aa +aa +aa +aT +Wv ab ab ab ab +ab +ab +ab +dl +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa aa aa aa @@ -30544,92 +30417,92 @@ aa aa aa aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa ab ab ab ab ab ab -ab -ab -ab -ab -ab -ab -ac -ah -aj -aj -aj -aj -aj -ai -aj -aj -aj -ai -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aS -aT -aT -aT -aT -aT -aT -aT -aT -aT -aT -aT -aT -aU -aT -aT -aR -aT -aR -aT -aR -eV -nj -bo -bg -bo -ag ae +ah +ah +aw +aj +aw +ai +aj +aj +aj +aj +aj +aj +aj +aj +aj +aa +ab +ab +ab +Ia +ab +yY +ab +ab +dl 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 @@ -30801,92 +30674,92 @@ 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 +aa +aa +aa +aa ab ab ab ab ae -ah -aj -aj -aj -aj -aj -ai -aj -az -aj -ai -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aS -aT -aT -aT -aT -aT -aT -aT -aT -aT -aT -aT -aT -ai -aT -aT -aT -aT -aT -aT -aT -xH -EE -bo -bk -bo +ae ag -ae +ag +an +au +aj +au +ai +aL +aK +aj +aj +aj +aj +aj +ab +ab +aa +Fd +ab +Ia +ab +ab +ab +Wv ab ab ab ab +dl +ab +dl +ab +dl +ab +ab +ab +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa aa aa aa @@ -31058,30 +30931,52 @@ aa aa aa aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa ab ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ae -ag +ah +ah +ah +ai +ah +ah +ah ai -aj -aj -ak -aj -aj -ap -aj -aj -aj ap +ai +ah +aJ aj aj aj @@ -31090,60 +30985,38 @@ aj aj aj aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aS -aT -aT -aT -aT -aT -aT -aT -aT -aT -aT -aT -aT -aV -aT -aT -aR -aT -aR -aT -aR -eV -nj -bo -bl -bo -ag -ae +aa +ab +ab +ab +Ia ab ab ab ab +ab +ab +ab +dl +ab +dl +ab +ab +ab +ab +ab +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa aa aa aa @@ -31317,17 +31190,38 @@ 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 -ab -ab -ab -ab -ab -ab -ab -ab -ae +ac ah aj aj @@ -31336,7 +31230,7 @@ aj aj ai aj -bj +aj aj ai aj @@ -31345,62 +31239,41 @@ aj aj aj aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aS -aT -aT -aT -aT -aT -aT -aT -aT -aT -aT -aT -aT -ai -aT -aT -aT -aT -aT -aT -aT -xH -nj -bo -bm -bo -ag -ae +TH +aa +aa +ab +ab +Sr +ab +ab +Ia +ab +ab +dl 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 @@ -31574,15 +31447,36 @@ aa aa aa aa -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 +aa +aa +aa ab ae ah @@ -31598,66 +31492,45 @@ aj ai aj aj -aH -aH -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj aj aj aj aj aj aj +aa aS -aT -aT -aT -aT -aT -aT -aT -aT -aT -aT -aT -aT -aU -aT -aT -aR -aT -aR -aT -aR -eV -nj -bo -bn -bo -ag -ae +ab +aa 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 @@ -31831,90 +31704,90 @@ aa aa aa aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ah -ah -ah -ai -ah -ah -ah -ai -ap -ai -ah -aj -aH -aL -aN -aH -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aS -aT -aT -aT -aT -aT -aT -aT -aT -aT -aT -aT -aT -aU -aT -aT -aT -aT -aT -aT -aT -xH -nj -bo -aX -bo -ag +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 ae +ag +ai +aj +aj +dx +aj +aj +ap +aj +aj +aj +ap +aj +aj +aj +aj +aj +aj +aj +ab +aa +ab +aa +xR +nX 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 @@ -32088,33 +31961,49 @@ aa aa aa aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa ab ae -ae -ag ah -aq -ax +aj +aj +aj aj aj ai aj -aH -aM -aL -aH +aj +aj +ai aj aj aj @@ -32124,54 +32013,38 @@ aj aj aj aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aS -aT -aT -aT -aT -aT -aT -aT -aT -aT -aT -bp -bp -ah -aT -aT -aT -aT -aT -aT -aT -NH -EE -ah -ah -ah -ae -ae +aa +ab +aa +ab +ab +ab +wV ab ab ab ab +ab +ab +dl +dl +ab +ab +ab +ab +ab +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa aa aa aa @@ -32345,32 +32218,49 @@ aa aa aa aa -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 +aa +aa +aa ab ae -ai -aq -ax +ah +aj +aj +aj aj aj ai aj aj -aH -aH +aj +ai aj aj aj @@ -32378,50 +32268,11 @@ aj aj aj aj +ab aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aS -aT -aT -aT -aT -aT -aT -aT -aT -aT -aT -bp -bk -ah -ah -bo -bo -bo -bo -bo -bo -bo -ah -ah -ae +ab +aa +xR ab ab ab @@ -32429,6 +32280,28 @@ ab ab ab ab +ab +ab +dl +ab +ab +ab +ab +ab +ab +ab +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa aa aa aa @@ -32602,90 +32475,90 @@ 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 -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ae +ah +ah +ah ai -aq -ax -aj -aj -aE -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aS -aT -aT -aT -aT -aT -aT -aT -aT -aT -aT -bp -bp -ah -aT -aT -aT -aT -aT -aT -aT -nj -nj ah ah ah -ae -ae +ai +ap +ai +ah +aj +aj +aL +aN +aj +aj +aj +ab +aa +dl +aa +ab +OB ab ab ab ab +ab +dl +ab +dl +ab +ab +ab +ab +ab +ab +ab +ab +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa aa aa aa @@ -32859,90 +32732,90 @@ 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 ab ab -ab -ad -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ai -aq -ax -aj -aB -ah -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aS -aT -aT -aT -aT -aT -aT -aT -aT -aT -aT -aT -aT -aU -aT -aT -aT -aT -aT -aT -aT -xH -EE -bo -aZ -bo -ag ae +ae +ag +ah +ew +aj +aj +aj +ai +aj +aj +aM +aL +aj +aj +aj +aa +aa +aa ab ab ab ab +ab +ab +ab +ab +dl +ab +ab +dl +ab +dl +ab +ab +ab +dl +dl +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa aa aa aa @@ -33116,90 +32989,90 @@ 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 ab ab ab ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ah -aq -ax -aj -aB -ah -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aS -aT -aT -aT -aT -aT -aT -aT -aT -aT -aT -aT -aT -aU -aT -aT -aR -aT -aR -aT -aR -eV -nj -bo -ba -bo -ag ae +ai +aj +aj +aj +aj +ai +aj +aj +aj +aj +aj +aj +TH +aa +dl +hY ab ab ab ab +ab +ab +ab +ab +dl +ab +ab +ab +ab +dl +ab +dl +ab +ab +ab +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa aa aa aa @@ -33373,90 +33246,90 @@ 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 ab ab ab ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ah -ah -ah -ah -aA -ah -ah -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aS -aT -aT -aT -aT -aT -aT -aT -aT -aT -aT -aT -aT -bo -aT -aT -aT -aT -aT -aT -aT -xH -NH -bo -bb -bo -ag ae +ai +az +vx +aj +aj +aE +aj +aj +aj +aj +aj +aj +aj +aa +aa +ab +ab +ab +aT +Wv +ab +ab +ab +dl 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 @@ -33630,6 +33503,36 @@ 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 ab @@ -33637,20 +33540,11 @@ ab ab ab ab -ab -ab -ab -ab -ab -ab -ab -ab -ah -al +ai aj aj aj -aC +sW ah aj aj @@ -33661,59 +33555,38 @@ aj aj aj aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aS +aa aT -aT -aT -aT -aT -aT -aT -aT -aT -aT -aT -aT -aV -aT -aT -aR -aT -aR -aT -aR -eV -nj -bo -bc -bo -ag -ae ab ab ab ab +ab +dl +ab +ab +dl +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa aa aa aa @@ -33887,6 +33760,68 @@ 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 +ab +ab +ab +ab +ab +ah +aj +aj +aj +Rw +ah +aj +aj +aj +aj +aj +aj +aj +ab +ab +aa +ab +ab +ab +ab +ab +ab +ab +ab +dl ab ab ab @@ -33897,80 +33832,18 @@ ab ab ab ab -ab -ab -ab -ab -ab -ai -bE -aj -aj -aj -aj -aA -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aS -aT -aT -aT -aT -aT -aT -aT -aT -aT -aT -aT -aT -bo -aT -aT -aT -aT -aT -aT -aT -xH -ww -bo -bd -bo -ag -ae -ab -ab -ab -ab +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa aa aa aa @@ -34144,15 +34017,36 @@ aa aa aa aa -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 +aa +aa +aa ab ab ab @@ -34160,11 +34054,11 @@ ab ab ab ah -al -aj -aj -aj -aC +ah +ah +ah +aA +ah ah aj aj @@ -34175,59 +34069,38 @@ aj aj aj aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aG -aS -bx -bx -bx -bx -bx -bx -bx -bx -bx -bx -bx -bx -aU -aT -aT -aR -aT -aR -aT -aR -eV -EE -bo -be -bo -ag -ae +aa +hY +ab +ab +dl +ab +dl ab ab ab ab +ab +dl +ab +ab +dl +dl +ab +ab +ab +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa aa aa aa @@ -34401,15 +34274,36 @@ aa aa aa aa -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 +aa +aa +aa ab ab ab @@ -34417,74 +34311,53 @@ ab ab ab ah +Fj +aj +aj +aj +WA ah -ah -ai -ah -ah -ah -aG -aG -aG -aG -aG -aG -aG -aG -aG -aG -aG -aG -aG -aG -aG -aG -aG -aG -aG -aG -aG -aG -aG -aG -aG -aG -aG -aG -aG -aG -aS -bu -bu -bu -bu -bu -bu -bu -bu -bu -bu -bu -bu -aU -aT -aT -aT -aT -aT -aT -aT -xH -nj -bo -bf -bo -ag -ae +aj +aj +aj +aj +aj +aj +aj +ab +ab +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 +aa +aa +aa +aa aa aa aa @@ -34658,6 +34531,62 @@ 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 +ab +ab +ab +ab +ai +bE +aj +aj +aj +aj +aA +aj +aj +aj +aj +aj +aj +TH +aj +aj +aj +ab +aa +Fd ab ab ab @@ -34669,79 +34598,23 @@ ab ab ab ab +dl ab ab +dl ab -ab -ab -ab -ae -ae -ag -ae -ae -aF -aF -aF -aF -aF -aF -aF -aF -aF -aF -aF -aF -aF -aF -aF -aF -aF -aF -aF -aF -aF -aF -aF -aF -aF -aF -aF -aF -aF -ab -aS -ah -ah -ah -ah -ah -ah -ah -ah -ah -ah -ah -ah -ah -aT -aT -aT -aT -aT -aT -aT -nj -nj -ah -ah -ah -ae -ae -ab -ab -ab -ab +dl +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa aa aa aa @@ -34915,11 +34788,61 @@ 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 ab ab ab +ab +ah +Fj +aj +aj +aj +WA +ah +aj +aj +aj +aj +aj +aj +aj +ab +ab +ab +dl +ab aa ab ab @@ -34937,68 +34860,18 @@ ab ab ab ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aY -ae -ae -ae -ae -ae -ae -ae -ae -ae -ae -ae -ae -ah -ah -bo -bo -bo -bo -bo -bo -bo -ah -ah -ae -ab -ab -ab -ab -ab -ab -ab +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa aa aa aa @@ -35178,6 +35051,50 @@ aa aa aa aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +ab +ab +ab +ab +ab +ab +ah +ah +ah +ai +ah +ah +ah +aG +aG +aG +aG +aG +aG +aG ab ab ab @@ -35200,61 +35117,17 @@ ab ab ab ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aF -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ae -ae -ae -ae -ae -ae -ae -ae -ae -ae -ae -ae -ae -ab -ab -ab -ab -ab -ab +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa aa aa aa @@ -35435,6 +35308,30 @@ aa aa aa aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa ab ab ab @@ -35443,74 +35340,50 @@ ab ab ab ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab +ae +ae +ag +ae +ae +aF +aF +aF +aF +aF +aF +aF +aF +aF +aF +aF +aF +aF aF ab +aF +aF +aF +aF +aF +aF +aF +aF +aF +aF +aF +aF +aF +aF ab -ab -ab -ab -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 @@ -35692,6 +35565,30 @@ aa aa aa aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa ab ab ab @@ -35735,38 +35632,14 @@ ab ab ab ab -ab -ab -ab -aF -ab -ab -ab -ab -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 @@ -35949,6 +35822,30 @@ aa aa aa aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa ab ab ab @@ -35969,37 +35866,6 @@ ab ab ab ab -aO -ac -ab -ab -ab -ab -ab -ab -ab -aQ -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aF -ab -ab -ab -ab ab ab ab @@ -36041,6 +35907,13 @@ aa aa aa aa +aa +aa +aa +aa +aa +aa +aa WT zb zb @@ -36206,10 +36079,30 @@ aa aa aa aa -ab -ab -ab -ab +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa ab ab ab @@ -36253,32 +36146,12 @@ ab ab ab aF -ab -ab -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 @@ -36463,78 +36336,78 @@ 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 -aF -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ac -bh -ae -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 +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa aa aa aa @@ -36720,77 +36593,77 @@ 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 -aF -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 +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa aa aa aa @@ -36977,76 +36850,76 @@ 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 -aF -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 +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa aa aa aa @@ -37244,58 +37117,58 @@ 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 aa -aF -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 +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/code/__DEFINES/_flags/_flags.dm b/code/__DEFINES/_flags/_flags.dm index 3a31eebb19..0734feaa42 100644 --- a/code/__DEFINES/_flags/_flags.dm +++ b/code/__DEFINES/_flags/_flags.dm @@ -138,14 +138,6 @@ GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 204 #define MOBILITY_FLAGS_DEFAULT (MOBILITY_MOVE | MOBILITY_STAND | MOBILITY_PICKUP | MOBILITY_USE | MOBILITY_UI | MOBILITY_STORAGE | MOBILITY_PULL | MOBILITY_RESIST) #define MOBILITY_FLAGS_ANY_INTERACTION (MOBILITY_USE | MOBILITY_PICKUP | MOBILITY_UI | MOBILITY_STORAGE) -// melee_attack_chain() attackchain_flags -/// The attack is from a parry counterattack. -#define ATTACKCHAIN_PARRY_COUNTERATTACK (1<<0) - -// UnarmedAttack() flags -/// Attack is from a parry counterattack -#define UNARMED_ATTACK_PARRY (1<<0) - /// If the thing can reflect light (lasers/energy) #define RICOCHET_SHINY (1<<0) /// If the thing can reflect matter (bullets/bomb shrapnel) diff --git a/code/__DEFINES/_flags/return_values.dm b/code/__DEFINES/_flags/return_values.dm new file mode 100644 index 0000000000..28606265b3 --- /dev/null +++ b/code/__DEFINES/_flags/return_values.dm @@ -0,0 +1,22 @@ +/////////// ATTACKCHAIN_FLAGS //////////// +// melee_attack_chain(), attackby(), pre_attack(), afterattack(), and tool_act(), attack() and **anything that is called by ClickOn()** return values. +// These are all passed down through the attack chain and are binary OR'd into each other! +/// Stop the attack chain if still in melee_attack_chain() +#define STOP_ATTACK_PROC_CHAIN (1<<0) +/// This attack should discard last_action instead of flushing (storing) it). You should probably know what you're doing if you use this considering this is how clickdelay is enforced. +#define DISCARD_LAST_ACTION (1<<1) +/// There are a number of "safety nets" intended to default-handle clickdelay. Return this flag to bypass ALL of them. Be sure +/// you know EXACTLY what you are doing! +#define NO_AUTO_CLICKDELAY_HANDLING (1<<2) +/// Only used with UnarmedAttack(). Interrupts unarmed attack from progressing. +#define INTERRUPT_UNARMED_ATTACK (1<<3) +/// Attack should not set next action even if the atom wants it to be an action +#define ATTACK_IGNORE_ACTION (1<<4) +/// Attack should not at all check last_action/attack_hand_speed even if the atom wants to +#define ATTACK_IGNORE_CLICKDELAY (1<<5) +/// This attack is from a parry counterattack +#define ATTACK_IS_PARRY_COUNTERATTACK (1<<6) + +// obj/item/dropped() +/// dropped() relocated this item, return FALSE for doUnEquip. +#define ITEM_RELOCATED_BY_DROPPED "relocated_by_dropped" diff --git a/code/__DEFINES/admin.dm b/code/__DEFINES/admin.dm index 0b2764c4a7..198356f804 100644 --- a/code/__DEFINES/admin.dm +++ b/code/__DEFINES/admin.dm @@ -74,6 +74,7 @@ #define ADMIN_PUNISHMENT_MAZING "Puzzle" #define ADMIN_PUNISHMENT_PIE "Cream Pie" #define ADMIN_PUNISHMENT_CUSTOM_PIE "Custom Cream Pie" +#define ADMIN_PUNISHMENT_SHOES "Knot Shoes" #define ADMIN_PUNISHMENT_CRACK ":B:oneless" #define ADMIN_PUNISHMENT_BLEED ":B:loodless" #define ADMIN_PUNISHMENT_SCARIFY "Scarify" diff --git a/code/__DEFINES/clockcult.dm b/code/__DEFINES/clockcult.dm index 2f2f94413b..f597eb4ae7 100644 --- a/code/__DEFINES/clockcult.dm +++ b/code/__DEFINES/clockcult.dm @@ -8,6 +8,7 @@ GLOBAL_VAR_INIT(clockwork_construction_value, 0) //The total value of all structures built by the clockwork cult GLOBAL_VAR_INIT(clockwork_vitality, 0) //How much Vitality is stored, total GLOBAL_VAR_INIT(clockwork_power, 0) //How many watts of power are globally available to the clockwork cult +GLOBAL_LIST_EMPTY(active_daemons) //A list of all active tinkerer's daemons GLOBAL_VAR_INIT(neovgre_exists, 0) //Does neovgre exist? GLOBAL_LIST_EMPTY(all_clockwork_objects) //All clockwork items, structures, and effects in existence @@ -19,7 +20,8 @@ GLOBAL_VAR_INIT(ark_of_the_clockwork_justiciar, FALSE) //The Ark on the Reebe z- GLOBAL_VAR_INIT(clockwork_gateway_activated, FALSE) //if a gateway to the celestial derelict has ever been successfully activated GLOBAL_VAR_INIT(script_scripture_unlocked, FALSE) //If script scripture is available, through converting at least one crewmember -GLOBAL_VAR_INIT(application_scripture_unlocked, FALSE) //If script scripture is available +GLOBAL_VAR_INIT(application_scripture_unlocked, FALSE) //If application scripture is available +GLOBAL_VAR_INIT(judgement_scripture_unlocked, FALSE) //If judgement scripture is available GLOBAL_LIST_EMPTY(all_scripture) //a list containing scripture instances; not used to track existing scripture //Scripture tiers and requirements; peripherals should never be used @@ -27,13 +29,13 @@ GLOBAL_LIST_EMPTY(all_scripture) //a list containing scripture instances; not us #define SCRIPTURE_DRIVER "Driver" #define SCRIPTURE_SCRIPT "Script" #define SCRIPTURE_APPLICATION "Application" +#define SCRIPTURE_JUDGEMENT "Judgement" //Various costs related to power. #define MAX_CLOCKWORK_POWER 80000 //The max power in W that the cult can stockpile #define SCRIPT_UNLOCK_THRESHOLD 35000 //Scripts will unlock if the total power reaches this amount -#define APPLICATION_UNLOCK_THRESHOLD 50000 //Applications will unlock if the total powre reaches this amount - -#define ABSCOND_ABDUCTION_COST 95 +#define APPLICATION_UNLOCK_THRESHOLD 50000 //Applications will unlock if the total power reaches this amount +#define JUDGEMENT_UNLOCK_THRESHOLD 80000 //might as well have this unlock at a power amount like the other scriptures, Judgement unlocks at this amount. //clockcult power defines #define MIN_CLOCKCULT_POWER 25 //the minimum amount of power clockcult machines will handle gracefully @@ -59,11 +61,11 @@ GLOBAL_LIST_EMPTY(all_scripture) //a list containing scripture instances; not us //Ark defines #define GATEWAY_SUMMON_RATE 1 //the time amount the Gateway to the Celestial Derelict gets each process tick; defaults to 1 per tick -#define GATEWAY_REEBE_FOUND 240 //when progress is at or above this, the gateway finds reebe and begins drawing power +#define GATEWAY_REEBE_FOUND 120 //when progress is at or above this, the gateway finds reebe and begins drawing power -#define GATEWAY_RATVAR_COMING 480 //when progress is at or above this, ratvar has entered and is coming through the gateway +#define GATEWAY_RATVAR_COMING 240 //when progress is at or above this, ratvar has entered and is coming through the gateway -#define GATEWAY_RATVAR_ARRIVAL 600 //when progress is at or above this, game over ratvar's here everybody go home +#define GATEWAY_RATVAR_ARRIVAL 300 //when progress is at or above this, game over ratvar's here everybody go home //Objective text define #define CLOCKCULT_OBJECTIVE "Construct the Ark of the Clockwork Justicar and free Ratvar." @@ -81,7 +83,7 @@ GLOBAL_LIST_EMPTY(all_scripture) //a list containing scripture instances; not us #define CLOCKWORK_ARMOR_COOLDOWN 1800 //The cooldown period between summoning suits of clockwork armor -#define RATVARIAN_SPEAR_COOLDOWN 300 //The cooldown period between summoning another Ratvarian spear +#define RATVARIAN_WEAPON_COOLDOWN 300 //The cooldown period between summoning another Ratvarian spear #define MARAUDER_SCRIPTURE_SCALING_THRESHOLD 600 //The amount of deciseconds that must pass before marauder scripture will not gain a recital penalty @@ -89,4 +91,8 @@ GLOBAL_LIST_EMPTY(all_scripture) //a list containing scripture instances; not us #define MARAUDER_SCRIPTURE_SCALING_MAX 300 //The maximum extra time applied to the marauder scripture -#define ARK_SCREAM_COOLDOWN 600 //This much time has to pass between instances of the Ark taking damage before it will "scream" again +#define GUARDIAN_EMERGE_THRESHOLD 65 //guardian cannot emerge unless host is at this% or less health + +#define ARK_SCREAM_COOLDOWN 300 //This much time has to pass between instances of the Ark taking damage before it will "scream" again + +#define PRISM_DELAY_DURATION 1200 //how long prolonging prisms delay the shuttle for; defaults to 2 minutes \ No newline at end of file diff --git a/code/__DEFINES/combat.dm b/code/__DEFINES/combat.dm index dff52f4748..1bf9b01403 100644 --- a/code/__DEFINES/combat.dm +++ b/code/__DEFINES/combat.dm @@ -108,7 +108,6 @@ #define CLICK_CD_RANGE 4 #define CLICK_CD_RAPID 2 #define CLICK_CD_CLICK_ABILITY 6 -#define CLICK_CD_BREAKOUT 100 #define CLICK_CD_HANDCUFFED 10 #define CLICK_CD_RESIST 20 #define CLICK_CD_GRABBING 10 @@ -281,7 +280,7 @@ GLOBAL_LIST_INIT(shove_disarming_types, typecacheof(list( /// changeNext_move penalty multiplier of the above. #define STAM_CRIT_ITEM_ATTACK_DELAY 1.75 /// Damage penalty when fighting prone. -#define LYING_DAMAGE_PENALTY 0.5 +#define LYING_DAMAGE_PENALTY 0.7 /// Added delay when firing guns stam-softcritted. Summed with a hardset CLICK_CD_RANGE delay, similar to STAM_CRIT_DAMAGE_DELAY otherwise. #define STAM_CRIT_GUN_DELAY 2.75 diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm index 071dab20b1..120fdcb72d 100644 --- a/code/__DEFINES/misc.dm +++ b/code/__DEFINES/misc.dm @@ -535,4 +535,9 @@ GLOBAL_LIST_INIT(pda_reskins, list(PDA_SKIN_CLASSIC = 'icons/obj/pda.dmi', PDA_S #define LOOT_RESTRICTION_MIND_PILE 3 //limited to the current pile. #define LOOT_RESTRICTION_CKEY_PILE 4 //Idem +//stages of shoe tying-ness +#define SHOES_UNTIED 0 +#define SHOES_TIED 1 +#define SHOES_KNOTTED 2 + #define WANTED_FILE "wanted_message.json" diff --git a/code/__DEFINES/misc/return_values.dm b/code/__DEFINES/misc/return_values.dm deleted file mode 100644 index d55f603de9..0000000000 --- a/code/__DEFINES/misc/return_values.dm +++ /dev/null @@ -1,3 +0,0 @@ -// obj/item/dropped -/// dropped() relocated this item, return FALSE for doUnEquip. -#define ITEM_RELOCATED_BY_DROPPED "relocated_by_dropped" diff --git a/code/__DEFINES/subsystems.dm b/code/__DEFINES/subsystems.dm index a6bd7a1c8e..7a188281d0 100644 --- a/code/__DEFINES/subsystems.dm +++ b/code/__DEFINES/subsystems.dm @@ -107,6 +107,7 @@ #define FIRE_PRIORITY_INSTRUMENTS 30 #define FIRE_PRIORITY_FIELDS 30 #define FIRE_PRIOTITY_SMOOTHING 35 +#define FIRE_PRIORITY_HUDS 40 #define FIRE_PRIORITY_NETWORKS 40 #define FIRE_PRIORITY_OBJ 40 #define FIRE_PRIORITY_ACID 40 diff --git a/code/__HELPERS/do_after.dm b/code/__HELPERS/do_after.dm index 614c3d73c4..30d40f3867 100644 --- a/code/__HELPERS/do_after.dm +++ b/code/__HELPERS/do_after.dm @@ -167,6 +167,7 @@ var/target_loc = target.loc LAZYADD(user.do_afters, target) + LAZYADD(target.targeted_by, user) var/holding = user.get_active_held_item() var/datum/progressbar/progbar @@ -189,6 +190,10 @@ . = FALSE break + if(!(target in user.do_afters)) + . = FALSE + break + if(drifting && !user.inertia_dir) drifting = 0 user_loc = user.loc @@ -198,12 +203,14 @@ break if(progress) qdel(progbar) + if(!QDELETED(target)) LAZYREMOVE(user.do_afters, target) + LAZYREMOVE(target.targeted_by, user) //some additional checks as a callback for for do_afters that want to break on losing health or on the mob taking action /mob/proc/break_do_after_checks(list/checked_health, check_clicks) - if(check_clicks && next_move > world.time) + if(check_clicks && !CheckActionCooldown()) return FALSE return TRUE @@ -224,6 +231,7 @@ if(target) LAZYADD(user.do_afters, target) + LAZYADD(target.targeted_by, user) var/atom/Uloc = user.loc @@ -288,6 +296,10 @@ if(!QDELETED(target)) LAZYREMOVE(user.do_afters, target) + if(!QDELETED(target)) + LAZYREMOVE(user.do_afters, target) + LAZYREMOVE(target.targeted_by, user) + /mob/proc/do_after_coefficent() // This gets added to the delay on a do_after, default 1 . = 1 return @@ -307,6 +319,7 @@ for(var/atom/target in targets) originalloc[target] = target.loc LAZYADD(user.do_afters, target) + LAZYADD(target.targeted_by, user) var/holding = user.get_active_held_item() var/datum/progressbar/progbar @@ -341,3 +354,4 @@ var/atom/target = thing if(!QDELETED(target)) LAZYREMOVE(user.do_afters, target) + LAZYREMOVE(target.targeted_by, user) diff --git a/code/_onclick/ai.dm b/code/_onclick/ai.dm index 7b40c96a6d..18aaf66659 100644 --- a/code/_onclick/ai.dm +++ b/code/_onclick/ai.dm @@ -19,10 +19,6 @@ A.move_camera_by_click() /mob/living/silicon/ai/ClickOn(var/atom/A, params) - if(world.time <= next_click) - return - next_click = world.time + 1 - if(!can_interact_with(A)) return @@ -74,16 +70,16 @@ CtrlClickOn(A) return - if(world.time <= next_move) + if(!CheckActionCooldown(immediate = TRUE)) return if(aicamera.in_camera_mode) aicamera.camera_mode_off() - aicamera.captureimage(pixel_turf, usr) + INVOKE_ASYNC(aicamera, /obj/item/camera.proc/captureimage, pixel_turf, usr) return if(waypoint_mode) - waypoint_mode = 0 - set_waypoint(A) + waypoint_mode = FALSE + INVOKE_ASYNC(src, .proc/set_waypoint, A) return A.attack_ai(src) diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm index 8a63339081..042ab3aaee 100644 --- a/code/_onclick/click.dm +++ b/code/_onclick/click.dm @@ -1,38 +1,3 @@ -/* - Click code cleanup - ~Sayu -*/ - -// 1 decisecond click delay (above and beyond mob/next_move) -//This is mainly modified by click code, to modify click delays elsewhere, use next_move and changeNext_move() -/mob/var/next_click = 0 - -// THESE DO NOT EFFECT THE BASE 1 DECISECOND DELAY OF NEXT_CLICK -/mob/var/next_move_adjust = 0 //Amount to adjust action/click delays by, + or - -/mob/var/next_move_modifier = 1 //Value to multiply action/click delays by - - -//Delays the mob's next click/action by num deciseconds -// eg: 10-3 = 7 deciseconds of delay -// eg: 10*0.5 = 5 deciseconds of delay -// DOES NOT EFFECT THE BASE 1 DECISECOND DELAY OF NEXT_CLICK - -/mob/proc/timeToNextMove() - return max(0, next_move - world.time) - -/mob/proc/changeNext_move(num) - next_move = world.time + ((num+next_move_adjust)*next_move_modifier) - -/mob/living/changeNext_move(num) - last_click_move = next_move - var/mod = next_move_modifier - var/adj = next_move_adjust - for(var/i in status_effects) - var/datum/status_effect/S = i - mod *= S.nextmove_modifier() - adj += S.nextmove_adjust() - next_move = world.time + ((num + adj)*mod) - /* Before anything else, defer these calls to a per-mobtype handler. This allows us to remove istype() spaghetti code, but requires the addition of other handler procs to simplify it. @@ -45,7 +10,7 @@ /atom/Click(location,control,params) if(flags_1 & INITIALIZED_1) SEND_SIGNAL(src, COMSIG_CLICK, location, control, params, usr) - usr.ClickOn(src, params) + usr.CommonClickOn(src, params) /atom/DblClick(location,control,params) if(flags_1 & INITIALIZED_1) @@ -55,6 +20,21 @@ if(flags_1 & INITIALIZED_1) usr.MouseWheelOn(src, delta_x, delta_y, params) +/** + * Common mob click code + */ +/mob/proc/CommonClickOn(atom/A, params) + SHOULD_NOT_SLEEP(TRUE) + if(mob_transforming) + return + if(SEND_SIGNAL(src, COMSIG_MOB_CLICKON, A, params) & COMSIG_MOB_CANCEL_CLICKON) + return + . = ClickOn(A, params) + if(!(. & DISCARD_LAST_ACTION)) + FlushCurrentAction() + else + DiscardCurrentAction() + /* Standard mob ClickOn() Handles exceptions: Buildmode, middle click, modified clicks, mech actions @@ -68,50 +48,34 @@ * item/afterattack(atom,user,adjacent,params) - used both ranged and adjacent * mob/RangedAttack(atom,params) - used only ranged, only used for tk and laser eyes but could be changed */ -/mob/proc/ClickOn( atom/A, params ) - if(world.time <= next_click) - return - next_click = world.time + world.tick_lag - +/mob/proc/ClickOn(atom/A, params) + SHOULD_NOT_SLEEP(TRUE) if(check_click_intercept(params,A)) return - if(mob_transforming) - return - - if(SEND_SIGNAL(src, COMSIG_MOB_CLICKON, A, params) & COMSIG_MOB_CANCEL_CLICKON) - return - var/list/modifiers = params2list(params) if(modifiers["shift"] && modifiers["middle"]) - ShiftMiddleClickOn(A) - return + return ShiftMiddleClickOn(A) if(modifiers["shift"] && modifiers["ctrl"]) - CtrlShiftClickOn(A) - return + return CtrlShiftClickOn(A) if(modifiers["middle"]) - MiddleClickOn(A) - return + return MiddleClickOn(A) if(modifiers["shift"] && (client && client.show_popup_menus || modifiers["right"])) //CIT CHANGE - makes shift-click examine use right click instead of left click in combat mode - ShiftClickOn(A) - return + return ShiftClickOn(A) if(modifiers["alt"]) // alt and alt-gr (rightalt) - AltClickOn(A) - return + return AltClickOn(A) if(modifiers["ctrl"]) - CtrlClickOn(A) - return + return CtrlClickOn(A) if(modifiers["right"]) //CIT CHANGE - allows right clicking to perform actions - RightClickOn(A,params) //CIT CHANGE - ditto - return //CIT CHANGE - ditto + return RightClickOn(A, params) //CIT CHANGE - ditto if(incapacitated(ignore_restraints = 1)) return face_atom(A) - if(next_move > world.time) // in the year 2000... + if(!CheckActionCooldown(immediate = TRUE)) return if(!modifiers["catcher"] && A.IsObscured()) @@ -119,12 +83,12 @@ if(ismecha(loc)) var/obj/mecha/M = loc - return M.click_action(A,src,params) + M.click_action(A,src,params) + return TRUE if(restrained()) - changeNext_move(CLICK_CD_HANDCUFFED) //Doing shit in cuffs shall be vey slow - RestrainedClickOn(A) - return + DelayNextAction(CLICK_CD_HANDCUFFED) + return RestrainedClickOn(A) if(in_throw_mode) throw_item(A) @@ -141,12 +105,12 @@ //User itself, current loc, and user inventory if(A in DirectAccess()) if(W) - W.melee_attack_chain(src, A, params) + return W.melee_attack_chain(src, A, params) else - if(ismob(A)) - changeNext_move(CLICK_CD_MELEE) - UnarmedAttack(A) - return + . = UnarmedAttack(A, TRUE, a_intent) + if(!(. & NO_AUTO_CLICKDELAY_HANDLING) && ismob(A)) + DelayNextAction(CLICK_CD_MELEE) + return //Can't reach anything else in lockers or other weirdness if(!loc.AllowClick()) @@ -155,16 +119,17 @@ //Standard reach turf to turf or reaching inside storage if(CanReach(A,W)) if(W) - W.melee_attack_chain(src, A, params) + return W.melee_attack_chain(src, A, params) else - if(ismob(A)) - changeNext_move(CLICK_CD_MELEE) - UnarmedAttack(A, 1) + . = UnarmedAttack(A, TRUE, a_intent) + if(!(. & NO_AUTO_CLICKDELAY_HANDLING) && ismob(A)) + DelayNextAction(CLICK_CD_MELEE) + return else if(W) - W.ranged_attack_chain(src, A, params) + return W.ranged_attack_chain(src, A, params) else - RangedAttack(A,params) + return RangedAttack(A,params) //Is the atom obscured by a PREVENT_CLICK_UNDER_1 object above it /atom/proc/IsObscured() @@ -270,8 +235,6 @@ in human click code to allow glove touches only at melee range. */ /mob/proc/UnarmedAttack(atom/A, proximity, intent = a_intent, flags = NONE) - if(ismob(A)) - changeNext_move(CLICK_CD_MELEE) /* Ranged unarmed attack: @@ -304,7 +267,6 @@ var/datum/antagonist/changeling/C = mind.has_antag_datum(/datum/antagonist/changeling) if(C && C.chosen_sting) C.chosen_sting.try_to_sting(src,A) - next_click = world.time + 5 return swap_hand() @@ -337,24 +299,24 @@ */ /mob/proc/CtrlClickOn(atom/A) - A.CtrlClick(src) - return + return A.CtrlClick(src) /atom/proc/CtrlClick(mob/user) SEND_SIGNAL(src, COMSIG_CLICK_CTRL, user) var/mob/living/ML = user if(istype(ML)) - ML.pulled(src) + INVOKE_ASYNC(ML, /mob/living.verb/pulled, src) /mob/living/carbon/human/CtrlClick(mob/user) if(ishuman(user) && Adjacent(user) && !user.incapacitated()) - if(world.time < user.next_move) + if(!user.CheckActionCooldown()) return FALSE var/mob/living/carbon/human/H = user H.dna.species.grab(H, src, H.mind.martial_art) - H.changeNext_move(CLICK_CD_MELEE) + H.DelayNextAction(CLICK_CD_MELEE) + return TRUE else - ..() + return ..() /* Alt click Unused except for AI @@ -377,8 +339,8 @@ var/datum/antagonist/changeling/C = mind.has_antag_datum(/datum/antagonist/changeling) if(C && C.chosen_sting) C.chosen_sting.try_to_sting(src,A) - next_click = world.time + 5 - return + DelayNextAction(CLICK_CD_RANGE) + return TRUE ..() /atom/proc/AltClick(mob/user) @@ -413,9 +375,11 @@ return /mob/living/LaserEyes(atom/A, params) - changeNext_move(CLICK_CD_RANGE) + if(!CheckActionCooldown(CLICK_CD_RANGE)) + return + DelayNextAction() - var/obj/item/projectile/beam/LE = new /obj/item/projectile/beam( loc ) + var/obj/item/projectile/beam/LE = new /obj/item/projectile/beam(loc) LE.icon = 'icons/effects/genetics.dmi' LE.icon_state = "eyelasers" playsound(usr.loc, 'sound/weapons/taser2.ogg', 75, 1) @@ -424,6 +388,7 @@ LE.def_zone = get_organ_target() LE.preparePixelProjectile(A, src, params) LE.fire() + return TRUE // Simple helper to face what you clicked on, in case it should be needed in more than one place /mob/proc/face_atom(atom/A, ismousemovement = FALSE) diff --git a/code/_onclick/cyborg.dm b/code/_onclick/cyborg.dm index 82288ee0d1..372fe46046 100644 --- a/code/_onclick/cyborg.dm +++ b/code/_onclick/cyborg.dm @@ -7,10 +7,6 @@ */ /mob/living/silicon/robot/ClickOn(var/atom/A, var/params) - if(world.time <= next_click) - return - next_click = world.time + 1 - if(check_click_intercept(params,A)) return @@ -19,25 +15,19 @@ var/list/modifiers = params2list(params) if(modifiers["shift"] && modifiers["ctrl"]) - CtrlShiftClickOn(A) - return + return CtrlShiftClickOn(A) if(modifiers["shift"] && modifiers["middle"]) - ShiftMiddleClickOn(A) - return + return ShiftMiddleClickOn(A) if(modifiers["middle"]) - MiddleClickOn(A) - return + return MiddleClickOn(A) if(modifiers["shift"]) - ShiftClickOn(A) - return + return ShiftClickOn(A) if(modifiers["alt"]) // alt and alt-gr (rightalt) - AltClickOn(A) - return + return AltClickOn(A) if(modifiers["ctrl"]) - CtrlClickOn(A) - return + return CtrlClickOn(A) - if(next_move >= world.time) + if(!CheckActionCooldown(immediate = TRUE)) return face_atom(A) // change direction to face what you clicked on @@ -50,7 +40,7 @@ */ if(aicamera.in_camera_mode) //Cyborg picture taking aicamera.camera_mode_off() - aicamera.captureimage(A, usr) + INVOKE_ASYNC(aicamera, /obj/item/camera.proc/captureimage, A, usr) return var/obj/item/W = get_active_held_item() @@ -58,13 +48,8 @@ if(!W && A.Adjacent(src) && (isobj(A) || ismob(A))) var/atom/movable/C = A if(C.can_buckle && C.has_buckled_mobs()) - if(C.buckled_mobs.len > 1) - var/unbuckled = input(src, "Who do you wish to unbuckle?","Unbuckle Who?") as null|mob in C.buckled_mobs - if(C.user_unbuckle_mob(unbuckled,src)) - return - else - if(C.user_unbuckle_mob(C.buckled_mobs[1],src)) - return + INVOKE_ASYNC(C, /atom/movable.proc/precise_user_unbuckle_mob, src) + return if(!W && (get_dist(src,A) <= interaction_range)) A.attack_robot(src) @@ -81,7 +66,9 @@ // cyborgs are prohibited from using storage items so we can I think safely remove (A.loc in contents) if(A == loc || (A in loc) || (A in contents)) - W.melee_attack_chain(src, A, params) + . = W.melee_attack_chain(src, A, params) + if(!(. & NO_AUTO_CLICKDELAY_HANDLING) && ismob(A)) + DelayNextAction(CLICK_CD_MELEE) return if(!isturf(loc)) @@ -90,11 +77,12 @@ // cyborgs are prohibited from using storage items so we can I think safely remove (A.loc && isturf(A.loc.loc)) if(isturf(A) || isturf(A.loc)) if(A.Adjacent(src)) // see adjacent.dm - W.melee_attack_chain(src, A, params) + . = W.melee_attack_chain(src, A, params) + if(!(. & NO_AUTO_CLICKDELAY_HANDLING) && ismob(A)) + DelayNextAction(CLICK_CD_MELEE) return else - W.afterattack(A, src, 0, params) - return + return W.afterattack(A, src, 0, params) //Middle click cycles through selected modules. /mob/living/silicon/robot/MiddleClickOn(atom/A) diff --git a/code/_onclick/hud/_defines.dm b/code/_onclick/hud/_defines.dm index 4b963c730d..467c67e0c3 100644 --- a/code/_onclick/hud/_defines.dm +++ b/code/_onclick/hud/_defines.dm @@ -168,6 +168,8 @@ //UI position overrides for 1:1 screen layout. (default is 7:5) #define ui_stamina "EAST-1:28,CENTER:17" // replacing internals button #define ui_overridden_resist "EAST-3:24,SOUTH+1:7" +#define ui_clickdelay "CENTER,SOUTH+1:-31" +#define ui_resistdelay "EAST-3:24,SOUTH+1:4" #define ui_combat_toggle "EAST-4:22,SOUTH:5" #define ui_boxcraft "EAST-4:22,SOUTH+1:6" diff --git a/code/_onclick/hud/action_button.dm b/code/_onclick/hud/action_button.dm index 0ed3a9cf26..8a66374029 100644 --- a/code/_onclick/hud/action_button.dm +++ b/code/_onclick/hud/action_button.dm @@ -56,9 +56,6 @@ if(id && usr.client) //try to (un)remember position usr.client.prefs.action_buttons_screen_locs["[name]_[id]"] = locked ? moved : null return TRUE - if(usr.next_click > world.time) - return - usr.next_click = world.time + 1 linked_action.Trigger() return TRUE diff --git a/code/_onclick/hud/alert.dm b/code/_onclick/hud/alert.dm index 11531a701e..8111680c41 100644 --- a/code/_onclick/hud/alert.dm +++ b/code/_onclick/hud/alert.dm @@ -22,7 +22,7 @@ if(alerts[category]) thealert = alerts[category] if(thealert.override_alerts) - return 0 + return thealert if(new_master && new_master != thealert.master) WARNING("[src] threw alert [category] with new_master [new_master] while already having that alert with master [thealert.master]") @@ -36,7 +36,7 @@ clear_alert(category) return .() else //no need to update - return 0 + return thealert else thealert = new type() thealert.override_alerts = override @@ -272,7 +272,7 @@ or shoot a gun to move around via Newton's 3rd Law of Motion." var/mob/living/L = usr if(!istype(L) || !L.can_resist()) return - L.changeNext_move(CLICK_CD_RESIST) + L.MarkResistTime() if(CHECK_MOBILITY(L, MOBILITY_MOVE)) return L.resist_fire() //I just want to start a flame in your hearrrrrrtttttt. @@ -447,8 +447,6 @@ or shoot a gun to move around via Newton's 3rd Law of Motion." var/time_name if(G.seconds_until_activation) time_name = "until the Ark activates" - else if(G.grace_period) - time_name = "of grace period remaining" else if(G.progress_in_seconds) time_name = "until the Ark finishes summoning" if(time_info) @@ -600,17 +598,32 @@ so as to remain in compliance with the most up-to-date laws." var/mob/living/L = usr if(!istype(L) || !L.can_resist()) return - L.changeNext_move(CLICK_CD_RESIST) - if(CHECK_MOBILITY(L, MOBILITY_MOVE) && (L.last_special <= world.time)) - return L.resist_restraints() + L.MarkResistTime() + return L.resist_restraints() /obj/screen/alert/restrained/buckled/Click() var/mob/living/L = usr if(!istype(L) || !L.can_resist()) return - L.changeNext_move(CLICK_CD_RESIST) - if(L.last_special <= world.time) - return L.resist_buckle() + L.MarkResistTime() + return L.resist_buckle() + +/obj/screen/alert/shoes/untied + name = "Untied Shoes" + desc = "Your shoes are untied! Click the alert or your shoes to tie them." + icon_state = "shoealert" + +/obj/screen/alert/shoes/knotted + name = "Knotted Shoes" + desc = "Someone tied your shoelaces together! Click the alert or your shoes to undo the knot." + icon_state = "shoealert" + +/obj/screen/alert/shoes/Click() + var/mob/living/carbon/C = usr + if(!istype(C) || !C.can_resist() || C != mob_viewer || !C.shoes) + return + C.MarkResistTime() + C.shoes.handle_tying(C) // PRIVATE = only edit, use, or override these if you're editing the system as a whole diff --git a/code/_onclick/hud/clockwork_marauder.dm b/code/_onclick/hud/clockwork_marauder.dm new file mode 100644 index 0000000000..09f85db574 --- /dev/null +++ b/code/_onclick/hud/clockwork_marauder.dm @@ -0,0 +1,45 @@ +/datum/hud/marauder + var/obj/screen/hosthealth + var/obj/screen/blockchance + var/obj/screen/counterchance + +/datum/hud/marauder/New(mob/living/simple_animal/hostile/clockwork/marauder/guardian/owner) + ..() + var/obj/screen/using + + healths = new /obj/screen/healths/clock() + infodisplay += healths + + hosthealth = new /obj/screen/healths/clock() + hosthealth.screen_loc = ui_internal + infodisplay += hosthealth + + using = new /obj/screen/marauder/emerge() + using.screen_loc = ui_zonesel + static_inventory += using + +/datum/hud/marauder/Destroy() + blockchance = null + counterchance = null + hosthealth = null + return ..() + +/mob/living/simple_animal/hostile/clockwork/marauder/guardian/create_mob_hud() + if(client && !hud_used) + hud_used = new /datum/hud/marauder(src, ui_style2icon(client.prefs.UI_style)) + +/obj/screen/marauder + icon = 'icons/mob/clockwork_mobs.dmi' + +/obj/screen/marauder/emerge + icon_state = "clockguard_emerge" + name = "Emerge/Return" + desc = "Emerge or Return." + +/obj/screen/marauder/emerge/Click() + if(istype(usr, /mob/living/simple_animal/hostile/clockwork/marauder/guardian)) + var/mob/living/simple_animal/hostile/clockwork/marauder/guardian/G = usr + if(G.is_in_host()) + G.try_emerge() + else + G.return_to_host() diff --git a/code/_onclick/hud/human.dm b/code/_onclick/hud/human.dm index 9380cf98aa..04141becf2 100644 --- a/code/_onclick/hud/human.dm +++ b/code/_onclick/hud/human.dm @@ -140,6 +140,17 @@ sprint_buffer.hud = src static_inventory += sprint_buffer + // clickdelay + clickdelay = new + clickdelay.hud = src + clickdelay.screen_loc = ui_clickdelay + static_inventory += clickdelay + + // resistdelay + resistdelay = new + resistdelay.hud = src + resistdelay.screen_loc = ui_resistdelay + static_inventory += resistdelay using = new /obj/screen/drop() using.icon = ui_style diff --git a/code/_onclick/hud/parallax.dm b/code/_onclick/hud/parallax.dm index 94374c5cb6..9050bcb5f0 100755 --- a/code/_onclick/hud/parallax.dm +++ b/code/_onclick/hud/parallax.dm @@ -219,6 +219,7 @@ L.screen_loc = "CENTER-7:[round(L.offset_x,1)],CENTER-7:[round(L.offset_y,1)]" /atom/movable/proc/update_parallax_contents() + set waitfor = FALSE if(length(client_mobs_in_contents)) for(var/thing in client_mobs_in_contents) var/mob/M = thing diff --git a/code/_onclick/hud/screen_objects.dm b/code/_onclick/hud/screen_objects.dm index 0088dde15a..126cc18907 100644 --- a/code/_onclick/hud/screen_objects.dm +++ b/code/_onclick/hud/screen_objects.dm @@ -47,17 +47,7 @@ name = "swap hand" /obj/screen/swap_hand/Click() - // At this point in client Click() code we have passed the 1/10 sec check and little else - // We don't even know if it's a middle click - if(world.time <= usr.next_move) - return 1 - - if(usr.incapacitated()) - return 1 - - if(ismob(usr)) - var/mob/M = usr - M.swap_hand() + usr.swap_hand() return 1 /obj/screen/craft @@ -101,15 +91,9 @@ plane = HUD_PLANE /obj/screen/inventory/Click(location, control, params) - // At this point in client Click() code we have passed the 1/10 sec check and little else - // We don't even know if it's a middle click - if(world.time <= usr.next_move) - return TRUE - - if(usr.incapacitated()) - return TRUE - if(ismecha(usr.loc)) // stops inventory actions in a mech - return TRUE + if(hud?.mymob && (hud.mymob != usr)) + return + // just redirect clicks if(hud?.mymob && slot_id) var/obj/item/inv_item = hud.mymob.get_item_by_slot(slot_id) @@ -190,17 +174,10 @@ /obj/screen/inventory/hand/Click(location, control, params) - // At this point in client Click() code we have passed the 1/10 sec check and little else - // We don't even know if it's a middle click - var/mob/user = hud?.mymob - if(usr != user) - return TRUE - if(world.time <= user.next_move) - return TRUE - if(user.incapacitated()) - return TRUE - if (ismecha(user.loc)) // stops inventory actions in a mech - return TRUE + if(hud?.mymob && (hud.mymob != usr)) + return + var/mob/user = hud.mymob + // just redirect clicks if(user.active_hand_index == held_index) var/obj/item/I = user.get_active_held_item() diff --git a/code/_onclick/hud/screen_objects/clickdelay.dm b/code/_onclick/hud/screen_objects/clickdelay.dm new file mode 100644 index 0000000000..e0ad039cdf --- /dev/null +++ b/code/_onclick/hud/screen_objects/clickdelay.dm @@ -0,0 +1,58 @@ +/obj/screen/action_bar + +/obj/screen/action_bar/Destroy() + STOP_PROCESSING(SShuds, src) + return ..() + +/obj/screen/action_bar/proc/mark_dirty() + var/mob/living/L = hud?.mymob + if(L?.client && update_to_mob(L)) + START_PROCESSING(SShuds, src) + +/obj/screen/action_bar/process() + var/mob/living/L = hud?.mymob + if(!L?.client || !update_to_mob(L)) + return PROCESS_KILL + +/obj/screen/action_bar/proc/update_to_mob(mob/living/L) + return FALSE + +/datum/hud/var/obj/screen/action_bar/clickdelay/clickdelay + +/obj/screen/action_bar/clickdelay + name = "click delay" + icon = 'icons/effects/progessbar.dmi' + icon_state = "prog_bar_100" + layer = 20 // under hand buttons + +/obj/screen/action_bar/clickdelay/Initialize() + . = ..() + var/matrix/M = new + M.Scale(2, 1) + transform = M + +/obj/screen/action_bar/clickdelay/update_to_mob(mob/living/L) + var/estimated = L.EstimatedNextActionTime() + var/diff = estimated - L.last_action + var/left = estimated - world.time + if(left < 0 || diff < 0) + icon_state = "prog_bar_100" + return FALSE + icon_state = "prog_bar_[round(clamp(((diff - left)/diff) * 100, 0, 100), 5)]" + return TRUE + +/datum/hud/var/obj/screen/action_bar/resistdelay/resistdelay + +/obj/screen/action_bar/resistdelay + name = "resist delay" + icon = 'icons/effects/progessbar.dmi' + icon_state = "prog_bar_100" + +/obj/screen/action_bar/resistdelay/update_to_mob(mob/living/L) + var/diff = L.next_resist - L.last_resist + var/left = L.next_resist - world.time + if(left < 0 || diff < 0) + icon_state = "prog_bar_100" + return FALSE + icon_state = "prog_bar_[round(clamp(((diff - left)/diff) * 100, 0, 100), 5)]" + return TRUE diff --git a/modular_citadel/code/_onclick/hud/sprint.dm b/code/_onclick/hud/screen_objects/sprint.dm similarity index 100% rename from modular_citadel/code/_onclick/hud/sprint.dm rename to code/_onclick/hud/screen_objects/sprint.dm diff --git a/modular_citadel/code/_onclick/hud/stamina.dm b/code/_onclick/hud/screen_objects/stamina.dm similarity index 100% rename from modular_citadel/code/_onclick/hud/stamina.dm rename to code/_onclick/hud/screen_objects/stamina.dm diff --git a/code/_onclick/hud/screen_objects/storage.dm b/code/_onclick/hud/screen_objects/storage.dm index 7e8bfe12ab..ce7bc96c96 100644 --- a/code/_onclick/hud/screen_objects/storage.dm +++ b/code/_onclick/hud/screen_objects/storage.dm @@ -9,12 +9,9 @@ /obj/screen/storage/Click(location, control, params) if(!insertion_click) return ..() - if(world.time <= usr.next_move) - return TRUE - if(usr.incapacitated()) - return TRUE - if (ismecha(usr.loc)) // stops inventory actions in a mech - return TRUE + if(hud?.mymob && (hud.mymob != usr)) + return + // just redirect clicks if(master) var/obj/item/I = usr.get_active_held_item() if(I) diff --git a/modular_citadel/code/_onclick/hud/screen_objects.dm b/code/_onclick/hud/screen_objects/vore.dm similarity index 100% rename from modular_citadel/code/_onclick/hud/screen_objects.dm rename to code/_onclick/hud/screen_objects/vore.dm diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm index bef06a69e9..6a26a6f116 100644 --- a/code/_onclick/item_attack.dm +++ b/code/_onclick/item_attack.dm @@ -7,21 +7,22 @@ *and lastly *afterattack. The return value does not matter. */ -/obj/item/proc/melee_attack_chain(mob/user, atom/target, params, flags, damage_multiplier = 1) +/obj/item/proc/melee_attack_chain(mob/user, atom/target, params, attackchain_flags, damage_multiplier = 1) if(isliving(user)) var/mob/living/L = user - if(!CHECK_MOBILITY(L, MOBILITY_USE) && !(flags & ATTACKCHAIN_PARRY_COUNTERATTACK)) + if(!CHECK_MOBILITY(L, MOBILITY_USE) && !(attackchain_flags & ATTACK_IS_PARRY_COUNTERATTACK)) to_chat(L, "You are unable to swing [src] right now!") return - if(tool_behaviour && target.tool_act(user, src, tool_behaviour)) + . = attackchain_flags + if(tool_behaviour && ((. = target.tool_act(user, src, tool_behaviour)) & STOP_ATTACK_PROC_CHAIN)) return - if(pre_attack(target, user, params)) + if((. |= pre_attack(target, user, params, ., damage_multiplier)) & STOP_ATTACK_PROC_CHAIN) return - if(target.attackby(src, user, params, flags, damage_multiplier)) + if((. |= target.attackby(src, user, params, ., damage_multiplier)) & STOP_ATTACK_PROC_CHAIN) return if(QDELETED(src) || QDELETED(target)) return - afterattack(target, user, TRUE, params) + . |= afterattack(target, user, TRUE, params) /// Like melee_attack_chain but for ranged. /obj/item/proc/ranged_attack_chain(mob/user, atom/target, params) @@ -30,7 +31,7 @@ if(!CHECK_MOBILITY(L, MOBILITY_USE)) to_chat(L, "You are unable to raise [src] right now!") return - afterattack(target, user, FALSE, params) + return afterattack(target, user, FALSE, params) // Called when the item is in the active hand, and clicked; alternately, there is an 'activate held object' verb or you can hit pagedown. /obj/item/proc/attack_self(mob/user) @@ -38,28 +39,43 @@ return interact(user) -/obj/item/proc/pre_attack(atom/A, mob/living/user, params) //do stuff before attackby! +/obj/item/proc/pre_attack(atom/A, mob/living/user, params, attackchain_flags, damage_multiplier) //do stuff before attackby! if(SEND_SIGNAL(src, COMSIG_ITEM_PRE_ATTACK, A, user, params) & COMPONENT_NO_ATTACK) - return TRUE - return FALSE //return TRUE to avoid calling attackby after this proc does stuff + return STOP_ATTACK_PROC_CHAIN + if(!(attackchain_flags & ATTACK_IGNORE_CLICKDELAY) && !CheckAttackCooldown(user, A)) + return STOP_ATTACK_PROC_CHAIN // No comment /atom/proc/attackby(obj/item/W, mob/user, params) if(SEND_SIGNAL(src, COMSIG_PARENT_ATTACKBY, W, user, params) & COMPONENT_NO_AFTERATTACK) - return TRUE - return FALSE + return STOP_ATTACK_PROC_CHAIN /obj/attackby(obj/item/I, mob/living/user, params) - return ..() || ((obj_flags & CAN_BE_HIT) && I.attack_obj(src, user)) + . = ..() + if(. & STOP_ATTACK_PROC_CHAIN) + return + if(obj_flags & CAN_BE_HIT) + . |= I.attack_obj(src, user) /mob/living/attackby(obj/item/I, mob/living/user, params, attackchain_flags, damage_multiplier) - if(..()) - return TRUE - I.attack_delay_done = FALSE //Should be set TRUE in pre_attacked_by() - . = I.attack(src, user, attackchain_flags, damage_multiplier) - if(!I.attack_delay_done) //Otherwise, pre_attacked_by() should handle it. - user.changeNext_move(I.click_delay) + . = ..() + if(. & STOP_ATTACK_PROC_CHAIN) + return + . |= I.attack(src, user, attackchain_flags, damage_multiplier) + if(!(. & NO_AUTO_CLICKDELAY_HANDLING)) // SAFETY NET - unless the proc tells us we should not handle this, give them the basic melee cooldown! + I.ApplyAttackCooldown(user, src, attackchain_flags) +/** + * Called when someone uses us to attack a mob in melee combat. + * + * This proc respects CheckAttackCooldown() default clickdelay handling. + * + * @params + * * mob/living/M - target + * * mob/living/user - attacker + * * attackchain_Flags - see [code/__DEFINES/_flags/return_values.dm] + * * damage_multiplier - what to multiply the damage by + */ /obj/item/proc/attack(mob/living/M, mob/living/user, attackchain_flags = NONE, damage_multiplier = 1) if(SEND_SIGNAL(src, COMSIG_ITEM_ATTACK, M, user) & COMPONENT_ITEM_NO_ATTACK) return @@ -88,6 +104,17 @@ if(weight) user.adjustStaminaLossBuffered(weight) + // CIT SCREENSHAKE + if(force >= 15) + shake_camera(user, ((force - 10) * 0.01 + 1), ((force - 10) * 0.01)) + if(M.client) + switch (M.client.prefs.damagescreenshake) + if (1) + shake_camera(M, ((force - 10) * 0.015 + 1), ((force - 10) * 0.015)) + if (2) + if(!CHECK_MOBILITY(M, MOBILITY_MOVE)) + shake_camera(M, ((force - 10) * 0.015 + 1), ((force - 10) * 0.015)) + //the equivalent of the standard version of attack() but for object targets. /obj/item/proc/attack_obj(obj/O, mob/living/user) if(SEND_SIGNAL(src, COMSIG_ITEM_ATTACK_OBJ, O, user) & COMPONENT_NO_ATTACK_OBJ) @@ -95,8 +122,7 @@ if(item_flags & NOBLUDGEON) return user.do_attack_animation(O) - if(!O.attacked_by(src, user)) - user.changeNext_move(click_delay) + O.attacked_by(src, user) var/weight = getweight(user, STAM_COST_ATTACK_OBJ_MULT) if(weight) user.adjustStaminaLossBuffered(weight)//CIT CHANGE - makes attacking things cause stamina loss @@ -109,12 +135,9 @@ var/bad_trait var/stamloss = user.getStaminaLoss() - var/next_move_mult = 1 if(stamloss > STAMINA_NEAR_SOFTCRIT) //The more tired you are, the less damage you do. var/penalty = (stamloss - STAMINA_NEAR_SOFTCRIT)/(STAMINA_NEAR_CRIT - STAMINA_NEAR_SOFTCRIT)*STAM_CRIT_ITEM_ATTACK_PENALTY totitemdamage *= 1 - penalty - next_move_mult += penalty*STAM_CRIT_ITEM_ATTACK_DELAY - user.changeNext_move(I.click_delay*next_move_mult) if(SEND_SIGNAL(user, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_INACTIVE)) bad_trait = SKILL_COMBAT_MODE //blacklist combat skills. @@ -126,18 +149,18 @@ if(!(SKILL_TRAIN_ATTACK_OBJ in I.used_skills[skill])) continue user.mind.auto_gain_experience(skill, I.skill_gain) - + if(!(attackchain_flags & NO_AUTO_CLICKDELAY_HANDLING)) + I.ApplyAttackCooldown(user, src, attackchain_flags) if(totitemdamage) visible_message("[user] has hit [src] with [I]!", null, null, COMBAT_MESSAGE_RANGE) //only witnesses close by and the victim see a hit message. log_combat(user, src, "attacked", I) take_damage(totitemdamage, I.damtype, "melee", 1) - return TRUE /mob/living/attacked_by(obj/item/I, mob/living/user, attackchain_flags = NONE, damage_multiplier = 1) var/list/block_return = list() var/totitemdamage = pre_attacked_by(I, user) * damage_multiplier - if((user != src) && mob_run_block(I, totitemdamage, "the [I.name]", ((attackchain_flags & ATTACKCHAIN_PARRY_COUNTERATTACK)? ATTACK_TYPE_PARRY_COUNTERATTACK : NONE) | ATTACK_TYPE_MELEE, I.armour_penetration, user, null, block_return) & BLOCK_SUCCESS) + if((user != src) && mob_run_block(I, totitemdamage, "the [I.name]", ((attackchain_flags & ATTACK_IS_PARRY_COUNTERATTACK)? ATTACK_IS_PARRY_COUNTERATTACK : NONE) | ATTACK_TYPE_MELEE, I.armour_penetration, user, null, block_return) & BLOCK_SUCCESS) return FALSE totitemdamage = block_calculate_resultant_damage(totitemdamage, block_return) send_item_attack_message(I, user, null, totitemdamage) @@ -155,8 +178,7 @@ /mob/living/simple_animal/attacked_by(obj/item/I, mob/living/user, attackchain_flags = NONE, damage_multiplier = 1) if(I.force < force_threshold || I.damtype == STAMINA) - playsound(loc, 'sound/weapons/tap.ogg', I.get_clamped_volume(), 1, -1) - user.changeNext_move(I.click_delay) //pre_attacked_by not called + playsound(src, 'sound/weapons/tap.ogg', I.get_clamped_volume(), 1, -1) else return ..() @@ -167,25 +189,21 @@ var/stamloss = user.getStaminaLoss() var/stam_mobility_mult = 1 - var/next_move_mult = 1 if(stamloss > STAMINA_NEAR_SOFTCRIT) //The more tired you are, the less damage you do. var/penalty = (stamloss - STAMINA_NEAR_SOFTCRIT)/(STAMINA_NEAR_CRIT - STAMINA_NEAR_SOFTCRIT)*STAM_CRIT_ITEM_ATTACK_PENALTY stam_mobility_mult -= penalty - next_move_mult += penalty*STAM_CRIT_ITEM_ATTACK_DELAY if(stam_mobility_mult > LYING_DAMAGE_PENALTY && !CHECK_MOBILITY(user, MOBILITY_STAND)) //damage penalty for fighting prone, doesn't stack with the above. stam_mobility_mult = LYING_DAMAGE_PENALTY . *= stam_mobility_mult - user.changeNext_move(I.click_delay*next_move_mult) - I.attack_delay_done = TRUE var/bad_trait if(!(I.item_flags & NO_COMBAT_MODE_FORCE_MODIFIER)) if(SEND_SIGNAL(user, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_INACTIVE)) bad_trait = SKILL_COMBAT_MODE //blacklist combat skills. if(SEND_SIGNAL(src, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_ACTIVE)) - . *= 0.5 + . *= 0.8 else if(SEND_SIGNAL(src, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_INACTIVE)) - . *= 1.5 + . *= 1.2 if(!user.mind || !I.used_skills) return @@ -197,8 +215,18 @@ var/datum/skill/S = GLOB.skill_datums[skill] user.mind.auto_gain_experience(skill, I.skill_gain*S.item_skill_gain_multi) -// Proximity_flag is 1 if this afterattack was called on something adjacent, in your square, or on your person. -// Click parameters is the params string from byond Click() code, see that documentation. +/** + * Called after attacking something if the melee attack chain isn't interrupted before. + * Also called when clicking on something with an item without being in melee range + * + * WARNING: This does not automatically check clickdelay if not in a melee attack! Be sure to account for this! + * + * @params + * * target - The thing we clicked + * * user - mob of person clicking + * * proximity_flag - are we in melee range/doing it in a melee attack + * * click_parameters - mouse control parameters, check BYOND ref. + */ /obj/item/proc/afterattack(atom/target, mob/user, proximity_flag, click_parameters) SEND_SIGNAL(src, COMSIG_ITEM_AFTERATTACK, target, user, proximity_flag, click_parameters) SEND_SIGNAL(user, COMSIG_MOB_ITEM_AFTERATTACK, target, user, proximity_flag, click_parameters) diff --git a/code/_onclick/observer.dm b/code/_onclick/observer.dm index ed7384697c..8a1e745308 100644 --- a/code/_onclick/observer.dm +++ b/code/_onclick/observer.dm @@ -37,7 +37,7 @@ CtrlClickOn(A) return - if(world.time <= next_move) + if(!CheckActionCooldown()) return // You are responsible for checking config.ghost_interaction when you override this function // Not all of them require checking, see below diff --git a/code/_onclick/other_mobs.dm b/code/_onclick/other_mobs.dm index 48b652b6f3..975c6e62d4 100644 --- a/code/_onclick/other_mobs.dm +++ b/code/_onclick/other_mobs.dm @@ -5,7 +5,7 @@ Otherwise pretty standard. */ -/mob/living/carbon/human/UnarmedAttack(atom/A, proximity, intent = a_intent, flags = NONE) +/mob/living/carbon/human/UnarmedAttack(atom/A, proximity, intent = a_intent, attackchain_flags = NONE) if(!has_active_hand()) //can't attack without a hand. to_chat(src, "You look at your arm and sigh.") @@ -16,33 +16,45 @@ to_chat(src, "The damage in your [check_arm.name] is preventing you from using it! Get it fixed, or at least splinted!") return + . = attackchain_flags // Special glove functions: // If the gloves do anything, have them return 1 to stop // normal attack_hand() here. var/obj/item/clothing/gloves/G = gloves // not typecast specifically enough in defines - if(proximity && istype(G) && G.Touch(A,1)) - return - - var/override = 0 + if(proximity && istype(G)) + . |= G.Touch(A, TRUE) + if(. & INTERRUPT_UNARMED_ATTACK) + return for(var/datum/mutation/human/HM in dna.mutations) - override += HM.on_attack_hand(A, proximity, intent, flags) + . |= HM.on_attack_hand(A, proximity, intent, .) - if(override) + if(. & INTERRUPT_UNARMED_ATTACK) return SEND_SIGNAL(src, COMSIG_HUMAN_MELEE_UNARMED_ATTACK, A) - A.attack_hand(src, intent, flags) + return . | A.attack_hand(src, intent, .) -//Return TRUE to cancel other attack hand effects that respect it. -/atom/proc/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) - . = FALSE +/atom/proc/attack_hand(mob/user, act_intent = user.a_intent, attackchain_flags) + SHOULD_NOT_SLEEP(TRUE) if(!(interaction_flags_atom & INTERACT_ATOM_NO_FINGERPRINT_ATTACK_HAND)) add_fingerprint(user) if(SEND_SIGNAL(src, COMSIG_ATOM_ATTACK_HAND, user) & COMPONENT_NO_ATTACK_HAND) - . = TRUE + return + . = attackchain_flags + if(attack_hand_speed && !(. & ATTACK_IGNORE_CLICKDELAY)) + if(!user.CheckActionCooldown(attack_hand_speed)) + return if(interaction_flags_atom & INTERACT_ATOM_ATTACK_HAND) . = _try_interact(user) + INVOKE_ASYNC(src, .proc/on_attack_hand, user, act_intent, .) + if(!(. & ATTACK_IGNORE_ACTION)) + if(attack_hand_unwieldlyness) + user.DelayNextAction(attack_hand_unwieldlyness, considered_action = attack_hand_is_action) + else if(attack_hand_is_action) + user.DelayNextAction() + +/atom/proc/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) //Return a non FALSE value to cancel whatever called this from propagating, if it respects it. /atom/proc/_try_interact(mob/user) @@ -50,7 +62,6 @@ return interact(user) if(can_interact(user)) return interact(user) - return FALSE /atom/proc/can_interact(mob/user) if(!user.can_interact_with(src)) @@ -80,8 +91,7 @@ else add_fingerprint(user) if(interaction_flags_atom & INTERACT_ATOM_UI_INTERACT) - return ui_interact(user) - return FALSE + ui_interact(user) /* /mob/living/carbon/human/RestrainedClickOn(var/atom/A) ---carbons will handle this @@ -95,13 +105,19 @@ . = ..() if(gloves) var/obj/item/clothing/gloves/G = gloves - if(istype(G) && G.Touch(A,0)) // for magic gloves + . |= G.Touch(A, FALSE) + if(. & INTERRUPT_UNARMED_ATTACK) + return + if(istype(glasses)) + . |= glasses.ranged_attack(src, A, mouseparams) + if(. & INTERRUPT_UNARMED_ATTACK) return - if (istype(glasses) && glasses.ranged_attack(src,A,mouseparams)) - return for(var/datum/mutation/human/HM in dna.mutations) - HM.on_ranged_attack(A, mouseparams) + . |= HM.on_ranged_attack(A, mouseparams) + + if(. & INTERRUPT_UNARMED_ATTACK) + return if(isturf(A) && get_dist(src,A) <= 1) src.Move_Pulled(A) @@ -123,7 +139,9 @@ Monkeys */ /mob/living/carbon/monkey/UnarmedAttack(atom/A, proximity, intent = a_intent, flags = NONE) - A.attack_paw(src, intent, flags) + if(!CheckActionCooldown(CLICK_CD_MELEE)) + return + return !isnull(A.attack_paw(src, intent, flags)) /atom/proc/attack_paw(mob/user) if(SEND_SIGNAL(src, COMSIG_ATOM_ATTACK_PAW, user) & COMPONENT_NO_ATTACK_HAND) @@ -144,6 +162,8 @@ return if(is_muzzled()) return + if(!CheckActionCooldown(CLICK_CD_MELEE)) + return var/mob/living/carbon/ML = A if(istype(ML)) var/dam_zone = pick(BODY_ZONE_CHEST, BODY_ZONE_PRECISE_L_HAND, BODY_ZONE_PRECISE_R_HAND, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG) @@ -163,6 +183,7 @@ ML.ForceContractDisease(D) else ML.visible_message("[src] has attempted to bite [ML]!") + DelayNextAction() /* Aliens @@ -243,7 +264,7 @@ /mob/living/simple_animal/hostile/UnarmedAttack(atom/A, proximity, intent = a_intent, flags = NONE) target = A if(dextrous && !ismob(A)) - ..() + return ..() else AttackingTarget() diff --git a/modular_citadel/code/_onclick/click.dm b/code/_onclick/right_click.dm similarity index 60% rename from modular_citadel/code/_onclick/click.dm rename to code/_onclick/right_click.dm index 004cc2fe80..4b2480eb8c 100644 --- a/modular_citadel/code/_onclick/click.dm +++ b/code/_onclick/right_click.dm @@ -5,7 +5,7 @@ face_atom(A) - if(next_move > world.time) // in the year 2000... + if(!CheckActionCooldown()) return if(!modifiers["catcher"] && A.IsObscured()) @@ -16,9 +16,8 @@ return M.click_action(A,src,params) if(restrained()) - changeNext_move(CLICK_CD_HANDCUFFED) //Doing shit in cuffs shall be vey slow - RestrainedClickOn(A) - return + DelayNextAction(CLICK_CD_HANDCUFFED) + return RestrainedClickOn(A) if(in_throw_mode) throw_item(A)//todo: make it plausible to lightly toss items via right-click @@ -36,13 +35,14 @@ //User itself, current loc, and user inventory if(A in DirectAccess()) if(W) - W.rightclick_melee_attack_chain(src, A, params) + return W.rightclick_melee_attack_chain(src, A, params) else - if(ismob(A)) - changeNext_move(CLICK_CD_MELEE) - if(!AltUnarmedAttack(A)) - UnarmedAttack(A) - return + if(!AltUnarmedAttack(A, TRUE)) + . = UnarmedAttack(A, TRUE, a_intent) + if(!(. & NO_AUTO_CLICKDELAY_HANDLING) && ismob(A)) + DelayNextAction(CLICK_CD_MELEE) + return + return //Can't reach anything else in lockers or other weirdness if(!loc.AllowClick()) @@ -51,23 +51,25 @@ //Standard reach turf to turf or reaching inside storage if(CanReach(A,W)) if(W) - W.rightclick_melee_attack_chain(src, A, params) + return W.rightclick_melee_attack_chain(src, A, params) else - if(ismob(A)) - changeNext_move(CLICK_CD_MELEE) - if(!AltUnarmedAttack(A,1)) - UnarmedAttack(A,1) + if(!AltUnarmedAttack(A, TRUE)) + . = UnarmedAttack(A, TRUE, a_intent) + if(!(. & NO_AUTO_CLICKDELAY_HANDLING) && ismob(A)) + DelayNextAction(CLICK_CD_MELEE) + return + return else if(W) if(!W.altafterattack(A, src, FALSE, params)) - W.afterattack(A, src, FALSE, params) + return W.afterattack(A, src, FALSE, params) else - if(!AltRangedAttack(A,params)) - RangedAttack(A,params) + if(!AltRangedAttack(A, params)) + return RangedAttack(A, params) /mob/proc/AltUnarmedAttack(atom/A, proximity_flag) if(ismob(A)) - changeNext_move(CLICK_CD_MELEE) + DelayNextAction(CLICK_CD_MELEE) return FALSE /mob/proc/AltRangedAttack(atom/A, params) diff --git a/modular_citadel/code/_onclick/item_attack.dm b/code/_onclick/right_item_attack.dm similarity index 82% rename from modular_citadel/code/_onclick/item_attack.dm rename to code/_onclick/right_item_attack.dm index bba3b14e2e..4ac9c96c8e 100644 --- a/modular_citadel/code/_onclick/item_attack.dm +++ b/code/_onclick/right_item_attack.dm @@ -1,10 +1,9 @@ /obj/item/proc/rightclick_melee_attack_chain(mob/user, atom/target, params) if(!alt_pre_attack(target, user, params)) //Hey, does this item have special behavior that should override all normal right-click functionality? if(!target.altattackby(src, user, params)) //Does the target do anything special when we right-click on it? - melee_attack_chain(user, target, params) //Ugh. Lame! I'm filing a legal complaint about the discrimination against the right mouse button! + . = melee_attack_chain(user, target, params) //Ugh. Lame! I'm filing a legal complaint about the discrimination against the right mouse button! else - altafterattack(target, user, TRUE, params) - return + . = altafterattack(target, user, TRUE, params) /obj/item/proc/alt_pre_attack(atom/A, mob/living/user, params) return FALSE //return something other than false if you wanna override attacking completely diff --git a/modular_citadel/code/_onclick/other_mobs.dm b/code/_onclick/right_other_mobs.dm similarity index 93% rename from modular_citadel/code/_onclick/other_mobs.dm rename to code/_onclick/right_other_mobs.dm index ec740f023b..2dc9fddeef 100644 --- a/modular_citadel/code/_onclick/other_mobs.dm +++ b/code/_onclick/right_other_mobs.dm @@ -3,15 +3,14 @@ to_chat(src, "You look at the state of the universe and sigh.") //lets face it, people rarely ever see this message in its intended condition. return TRUE - if(!A.alt_attack_hand(src)) - A.attack_hand(src) - return TRUE - return TRUE + return A.alt_attack_hand(src) /mob/living/carbon/human/AltRangedAttack(atom/A, params) if(isturf(A) || incapacitated()) // pretty annoying to wave your fist at floors and walls. And useless. - return TRUE - changeNext_move(CLICK_CD_RANGE) + return + if(!CheckActionCooldown(CLICK_CD_RANGE)) + return + DelayNextAction() var/list/target_viewers = fov_viewers(11, A) //doesn't check for blindness. if(!(src in target_viewers)) //click catcher issuing calls for out of view objects. return TRUE diff --git a/code/_onclick/telekinesis.dm b/code/_onclick/telekinesis.dm index f95ebf82b5..f8a14b8c30 100644 --- a/code/_onclick/telekinesis.dm +++ b/code/_onclick/telekinesis.dm @@ -123,7 +123,8 @@ . = ..() if(!target || !user) return - + if(!user.CheckActionCooldown(CLICK_CD_MELEE)) + return if(!focus) focus_object(target) return @@ -145,7 +146,7 @@ else apply_focus_overlay() focus.throw_at(target, 10, 1,user) - user.changeNext_move(CLICK_CD_MELEE) + user.DelayNextAction(considered_action = TRUE, flush = TRUE) update_icon() /proc/tkMaxRangeCheck(mob/user, atom/target) diff --git a/code/controllers/configuration/entries/general.dm b/code/controllers/configuration/entries/general.dm index 1be413f065..2d5e69f149 100644 --- a/code/controllers/configuration/entries/general.dm +++ b/code/controllers/configuration/entries/general.dm @@ -470,3 +470,5 @@ /datum/config_entry/flag/minimaps_enabled config_entry_value = TRUE + +/datum/config_entry/string/centcom_ban_db // URL for the CentCom Galactic Ban DB API diff --git a/code/controllers/subsystem/processing/huds.dm b/code/controllers/subsystem/processing/huds.dm new file mode 100644 index 0000000000..aea23d2400 --- /dev/null +++ b/code/controllers/subsystem/processing/huds.dm @@ -0,0 +1,6 @@ +// Smooth HUD updates, but low priority +PROCESSING_SUBSYSTEM_DEF(huds) + name = "HUD updates" + wait = 0.5 + priority = FIRE_PRIORITY_HUDS + stat_tag = "HUDS" diff --git a/code/datums/brain_damage/special.dm b/code/datums/brain_damage/special.dm index 13cf2add97..7cc5348a0a 100644 --- a/code/datums/brain_damage/special.dm +++ b/code/datums/brain_damage/special.dm @@ -103,8 +103,7 @@ . = ..() QDEL_IN(src, 300) -//ATTACK HAND IGNORING PARENT RETURN VALUE -/obj/effect/hallucination/simple/bluespace_stream/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/effect/hallucination/simple/bluespace_stream/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(user != seer || !linked_to) return var/slip_in_message = pick("slides sideways in an odd way, and disappears", "jumps into an unseen dimension",\ diff --git a/code/datums/components/crafting/recipes/recipes_clothing.dm b/code/datums/components/crafting/recipes/recipes_clothing.dm index 7a7379c834..2a24c0b451 100644 --- a/code/datums/components/crafting/recipes/recipes_clothing.dm +++ b/code/datums/components/crafting/recipes/recipes_clothing.dm @@ -263,6 +263,14 @@ time = 30 category = CAT_CLOTHING +/datum/crafting_recipe/durathread_reinforcement_kit + name = "Durathread Reinforcement Kit" + result = /obj/item/armorkit + reqs = list(/obj/item/stack/sheet/durathread = 4) + tools = list(/obj/item/stack/sheet/mineral/titanium, TOOL_WIRECUTTER) // tough needle for a tough fabric + time = 40 + category = CAT_CLOTHING + /datum/crafting_recipe/durathread_duffelbag name = "Durathread Dufflebag" result = /obj/item/storage/backpack/duffelbag/durathread diff --git a/code/datums/components/rotation.dm b/code/datums/components/rotation.dm index f5da669c3a..129faabdb7 100644 --- a/code/datums/components/rotation.dm +++ b/code/datums/components/rotation.dm @@ -98,16 +98,16 @@ /datum/component/simple_rotation/proc/HandRot(datum/source, mob/user, rotation = default_rotation_direction) if(can_be_rotated) - if(!can_be_rotated.Invoke(user, default_rotation_direction)) + if(!can_be_rotated.Invoke(user, rotation)) return else - if(!default_can_be_rotated(user, default_rotation_direction)) + if(!default_can_be_rotated(user, rotation)) return if(can_user_rotate) - if(!can_user_rotate.Invoke(user, default_rotation_direction)) + if(!can_user_rotate.Invoke(user, rotation)) return else - if(!default_can_user_rotate(user, default_rotation_direction)) + if(!default_can_user_rotate(user, rotation)) return BaseRot(user, rotation) return TRUE diff --git a/code/datums/components/uplink.dm b/code/datums/components/uplink.dm index a269e24974..c7bbe01b2f 100644 --- a/code/datums/components/uplink.dm +++ b/code/datums/components/uplink.dm @@ -102,6 +102,15 @@ GLOBAL_LIST_EMPTY(uplinks) return //no hitting everyone/everything just to try to slot tcs in! if(istype(I, /obj/item/stack/telecrystal)) LoadTC(user, I) + if(active) + if(I.GetComponent(/datum/component/uplink)) + var/datum/component/uplink/hidden_uplink = I.GetComponent(/datum/component/uplink) + var/amt = hidden_uplink.telecrystals + hidden_uplink.telecrystals -= amt + src.telecrystals += amt + to_chat(user, "You connect the [I] to your uplink, siphoning [amt] telecrystals before quickly undoing the connection.") + else + return for(var/category in uplink_items) for(var/item in uplink_items[category]) var/datum/uplink_item/UI = uplink_items[category][item] diff --git a/code/datums/http.dm b/code/datums/http.dm new file mode 100644 index 0000000000..2a9b53f131 --- /dev/null +++ b/code/datums/http.dm @@ -0,0 +1,74 @@ +/datum/http_request + var/id + var/in_progress = FALSE + + var/method + var/body + var/headers + var/url + + var/_raw_response + +/datum/http_request/proc/prepare(method, url, body = "", list/headers) + if (!length(headers)) + headers = "" + else + headers = json_encode(headers) + + src.method = method + src.url = url + src.body = body + src.headers = headers + +/datum/http_request/proc/execute_blocking() + _raw_response = rustg_http_request_blocking(method, url, body, headers) + +/datum/http_request/proc/begin_async() + if (in_progress) + CRASH("Attempted to re-use a request object.") + + id = rustg_http_request_async(method, url, body, headers) + + if (isnull(text2num(id))) + stack_trace("Proc error: [id]") + _raw_response = "Proc error: [id]" + else + in_progress = TRUE + +/datum/http_request/proc/is_complete() + if (isnull(id)) + return TRUE + + if (!in_progress) + return TRUE + + var/r = rustg_http_check_request(id) + + if (r == RUSTG_JOB_NO_RESULTS_YET) + return FALSE + else + _raw_response = r + in_progress = FALSE + return TRUE + +/datum/http_request/proc/into_response() + var/datum/http_response/R = new() + + try + var/list/L = json_decode(_raw_response) + R.status_code = L["status_code"] + R.headers = L["headers"] + R.body = L["body"] + catch + R.errored = TRUE + R.error = _raw_response + + return R + +/datum/http_response + var/status_code + var/body + var/list/headers + + var/errored = FALSE + var/error diff --git a/code/datums/martial/_martial.dm b/code/datums/martial/_martial.dm index 8241f685d7..1581323f89 100644 --- a/code/datums/martial/_martial.dm +++ b/code/datums/martial/_martial.dm @@ -44,11 +44,11 @@ //Here we roll for our damage to be added into the damage var in the various attack procs. This is changed depending on whether we are in combat mode, lying down, or if our target is in combat mode. var/damage = rand(A.dna.species.punchdamagelow, A.dna.species.punchdamagehigh) if(SEND_SIGNAL(D, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_INACTIVE)) - damage *= 1.5 + damage *= 1.2 if(!CHECK_MOBILITY(A, MOBILITY_STAND)) - damage *= 0.5 + damage *= 0.7 if(SEND_SIGNAL(A, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_INACTIVE)) - damage *= 0.25 + damage *= 0.8 return damage /datum/martial_art/proc/teach(mob/living/carbon/human/H, make_temporary = FALSE) diff --git a/code/datums/mood_events/generic_negative_events.dm b/code/datums/mood_events/generic_negative_events.dm index a2078a82e4..787d6375a7 100644 --- a/code/datums/mood_events/generic_negative_events.dm +++ b/code/datums/mood_events/generic_negative_events.dm @@ -274,3 +274,13 @@ description = "I've produced better art than that from my ass.\n" mood_change = -2 timeout = 1200 + +/datum/mood_event/tripped + description = "I can't believe I fell for the oldest trick in the book!\n" + mood_change = -6 + timeout = 2 MINUTES + +/datum/mood_event/untied + description = "I hate when my shoes come untied!\n" + mood_change = -3 + timeout = 1 MINUTES diff --git a/code/datums/mutations/hulk.dm b/code/datums/mutations/hulk.dm index 2df2b20cbc..bc7b9171a8 100644 --- a/code/datums/mutations/hulk.dm +++ b/code/datums/mutations/hulk.dm @@ -21,7 +21,11 @@ /datum/mutation/human/hulk/on_attack_hand(atom/target, proximity, act_intent, unarmed_attack_flags) if(proximity && (act_intent == INTENT_HARM)) //no telekinetic hulk attack - return target.attack_hulk(owner) + if(!owner.CheckActionCooldown(CLICK_CD_MELEE)) + return INTERRUPT_UNARMED_ATTACK | NO_AUTO_CLICKDELAY_HANDLING + owner.DelayNextAction() + target.attack_hulk(owner) + return INTERRUPT_UNARMED_ATTACK | NO_AUTO_CLICKDELAY_HANDLING /datum/mutation/human/hulk/on_life() if(owner.health < 0) diff --git a/code/datums/status_effects/debuffs.dm b/code/datums/status_effects/debuffs.dm index 561329f02a..aa27c6424e 100644 --- a/code/datums/status_effects/debuffs.dm +++ b/code/datums/status_effects/debuffs.dm @@ -144,7 +144,6 @@ id = "tased" alert_type = null var/movespeed_mod = /datum/movespeed_modifier/status_effect/tased - var/nextmove_modifier = 1 var/stamdmg_per_ds = 0 //a 20 duration would do 20 stamdmg, disablers do 24 or something var/last_tick = 0 //fastprocess processing speed is a goddamn sham, don't trust it. @@ -173,13 +172,9 @@ C.adjustStaminaLoss(max(0, stamdmg_per_ds * diff)) //if you really want to try to stamcrit someone with a taser alone, you can, but it'll take time and good timing. last_tick = world.time -/datum/status_effect/electrode/nextmove_modifier() //why is this a proc. its no big deal since this doesnt get called often at all but literally w h y - return nextmove_modifier - /datum/status_effect/electrode/no_combat_mode id = "tased_strong" movespeed_mod = /datum/movespeed_modifier/status_effect/tased/no_combat_mode - nextmove_modifier = 2 blocks_combatmode = TRUE stamdmg_per_ds = 1 diff --git a/code/datums/status_effects/status_effect.dm b/code/datums/status_effects/status_effect.dm index dd5fef61d7..461ae9c65d 100644 --- a/code/datums/status_effects/status_effect.dm +++ b/code/datums/status_effects/status_effect.dm @@ -90,13 +90,12 @@ return duration = world.time + original_duration -//clickdelay/nextmove modifiers! -/datum/status_effect/proc/nextmove_modifier() +/** + * Multiplied to clickdelays + */ +/datum/status_effect/proc/action_cooldown_mod() return 1 -/datum/status_effect/proc/nextmove_adjust() - return 0 - //////////////// // ALERT HOOK // //////////////// diff --git a/code/datums/status_effects/wound_effects.dm b/code/datums/status_effects/wound_effects.dm index 2c0c030425..91440d36de 100644 --- a/code/datums/status_effects/wound_effects.dm +++ b/code/datums/status_effects/wound_effects.dm @@ -151,7 +151,7 @@ return 1 -/datum/status_effect/wound/bone/nextmove_modifier() +/datum/status_effect/wound/bone/action_cooldown_mod() var/mob/living/carbon/C = owner if(C.get_active_hand() == linked_limb) diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 7623a88065..de9df3a23e 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -70,6 +70,9 @@ /// A luminescence-shifted value of the last color calculated for chatmessage overlays var/chat_color_darkened + ///Mobs that are currently do_after'ing this atom, to be cleared from on Destroy() + var/list/targeted_by + /atom/New(loc, ...) //atom creation method that preloads variables at creation if(GLOB.use_preloader && (src.type == GLOB._preloader.target_path))//in case the instanciated atom is creating other atoms in New() @@ -144,6 +147,11 @@ LAZYCLEARLIST(overlays) LAZYCLEARLIST(priority_overlays) + for(var/i in targeted_by) + var/mob/M = i + LAZYREMOVE(M.do_afters, src) + targeted_by = null + QDEL_NULL(light) return ..() @@ -219,7 +227,7 @@ /atom/proc/attack_hulk(mob/living/carbon/human/user, does_attack_animation = FALSE) SEND_SIGNAL(src, COMSIG_ATOM_HULK_ATTACK, user) if(does_attack_animation) - user.changeNext_move(CLICK_CD_MELEE) + user.DelayNextAction(CLICK_CD_MELEE) log_combat(user, src, "punched", "hulk powers") user.do_attack_animation(src, ATTACK_EFFECT_SMASH) diff --git a/code/game/gamemodes/clock_cult/clock_cult.dm b/code/game/gamemodes/clock_cult/clock_cult.dm index 5666f2442f..154d2df563 100644 --- a/code/game/gamemodes/clock_cult/clock_cult.dm +++ b/code/game/gamemodes/clock_cult/clock_cult.dm @@ -38,7 +38,8 @@ Credit where due: 5. Xhuis from /tg/ for coding the first iteration of the mode, and the new, reworked version 6. ChangelingRain from /tg/ for maintaining the gamemode for months after its release prior to its rework 7. Clockwork cult code as of now, at least the one being pulled from Citadel Station's master branch, is being, or already is, fixed by Coolgat3 and Avunia. - +8. Modern clockwork cult code mixed with original clockwork code, with various changes to make it less of a fustercluck, done by KeRSe. \ + Fixes and assistance done by TimothyTeakettle, Kevinz000, and Deltafire15. -Very glad for the help they gave. */ /////////// @@ -133,7 +134,7 @@ Credit where due: config_tag = "clockwork_cult" antag_flag = ROLE_SERVANT_OF_RATVAR false_report_weight = 10 - required_players = 35 + required_players = 24 //Fixing this directly for now since apparently config machine for forcing modes broke. required_enemies = 3 recommended_enemies = 5 enemy_minimum_age = 7 @@ -143,13 +144,12 @@ Credit where due: announce_text = "Servants of Ratvar are trying to summon the Justiciar!\n\ Servants: Construct defenses to protect the Ark. Sabotage the station!\n\ Crew: Stop the servants before they can summon the Clockwork Justiciar." - var/servants_to_serve = list() + var/list/servants_to_serve = list() //Yes this list is made out of list var/roundstart_player_count - var/ark_time //In minutes, how long the Ark waits before activation; this is equal to 30 + (number of players / 5) (max 40 mins.) var/datum/team/clockcult/main_clockcult -/datum/game_mode/clockwork_cult/pre_setup() +/datum/game_mode/clockwork_cult/pre_setup() //Gamemode and job code is pain. Have fun codediving all of that stuff, whoever works on this next - Delta var/list/errorList = list() var/list/reebes = SSmapping.LoadGroup(errorList, "Reebe", "map_files/generic", "City_of_Cogs.dmm", default_traits = ZTRAITS_REEBE, silent = TRUE) if(errorList.len) // reebe failed to load @@ -162,38 +162,36 @@ Credit where due: restricted_jobs += protected_jobs if(CONFIG_GET(flag/protect_assistant_from_antagonist)) restricted_jobs += "Assistant" - var/starter_servants = 4 //Guaranteed four servants + var/starter_servants = 4 //Try to go for at least four var/number_players = num_players() roundstart_player_count = number_players if(number_players > 30) //plus one servant for every additional 10 players above 30 number_players -= 30 starter_servants += round(number_players / 10) - starter_servants = min(starter_servants, 8) //max 8 servants (that sould only happen with a ton of players) - GLOB.clockwork_vitality += 50 * starter_servants //some starter Vitality to help recover from initial fuck ups + starter_servants = min(starter_servants, 8) //max 8 servants (that sould only happen with a ton of players) while(starter_servants) + if(!antag_candidates.len) + break //Skip setup, DO NOT RUNTIME var/datum/mind/servant = antag_pick(antag_candidates) servants_to_serve += servant antag_candidates -= servant - servant.assigned_role = ROLE_SERVANT_OF_RATVAR servant.special_role = ROLE_SERVANT_OF_RATVAR + servant.restricted_roles = restricted_jobs starter_servants-- - ark_time = 30 + round((roundstart_player_count / 5)) //In minutes, how long the Ark will wait before activation - ark_time = min(ark_time, 35) //35 minute maximum for the activation timer - return 1 + if(!servants_to_serve.len) //Uh oh, something went wrong + setup_error = "There are no clockcult candidates! (Or something went very wrong)" + return FALSE + GLOB.clockwork_vitality += 50 * servants_to_serve.len //some starter Vitality to help recover from initial fuck ups + return TRUE //Haha yes it works time to not touch it any more than that. /datum/game_mode/clockwork_cult/post_setup() for(var/S in servants_to_serve) var/datum/mind/servant = S log_game("[key_name(servant)] was made an initial servant of Ratvar") var/mob/living/L = servant.current - var/turf/T = pick(GLOB.servant_spawns) - L.forceMove(T) - GLOB.servant_spawns -= T greet_servant(L) equip_servant(L) add_servant_of_ratvar(L, TRUE) - var/obj/structure/destructible/clockwork/massive/celestial_gateway/G = GLOB.ark_of_the_clockwork_justiciar //that's a mouthful - G.final_countdown(ark_time) ..() return 1 @@ -201,20 +199,18 @@ Credit where due: if(!M) return 0 to_chat(M, "You are a servant of Ratvar, the Clockwork Justiciar!") - to_chat(M, "You have approximately [ark_time] minutes until the Ark activates.") - to_chat(M, "Unlock Script scripture by converting a new servant.") - to_chat(M, "Application scripture will be unlocked halfway until the Ark's activation.") + to_chat(M, "Unlock Script scripture by converting a new servant or when 35kw of power is reached.") + to_chat(M, "Application scripture will be unlocked when 50kw of power is reached.") M.playsound_local(get_turf(M), 'sound/ambience/antag/clockcultalr.ogg', 100, FALSE, pressure_affected = FALSE) return 1 -/datum/game_mode/proc/equip_servant(mob/living/M) //Grants a clockwork slab to the mob, with one of each component +/datum/game_mode/proc/equip_servant(mob/living/M) //Grants a clockwork slab to the mob if(!M || !ishuman(M)) return FALSE var/mob/living/carbon/human/L = M - L.equipOutfit(/datum/outfit/servant_of_ratvar) var/obj/item/clockwork/slab/S = new var/slot = "At your feet" - var/list/slots = list("In your left pocket" = SLOT_L_STORE, "In your right pocket" = SLOT_R_STORE, "In your backpack" = SLOT_IN_BACKPACK, "On your belt" = SLOT_BELT) + var/list/slots = list("In your left pocket" = SLOT_L_STORE, "In your right pocket" = SLOT_R_STORE, "In your backpack" = SLOT_IN_BACKPACK) if(ishuman(L)) var/mob/living/carbon/human/H = L slot = H.equip_in_one_of_slots(S, slots) @@ -224,7 +220,6 @@ Credit where due: if(!S.forceMove(get_turf(L))) qdel(S) if(S && !QDELETED(S)) - to_chat(L, "There is a paper in your backpack! It'll tell you if anything's changed, as well as what to expect.") to_chat(L, "[slot] is a clockwork slab, a multipurpose tool used to construct machines and invoke ancient words of power. If this is your first time \ as a servant, you can find a concise tutorial in the Recollection category of its interface.") to_chat(L, "If you want more information, you can read the wiki page to learn more.") @@ -278,7 +273,7 @@ Credit where due: gloves = /obj/item/clothing/gloves/color/yellow belt = /obj/item/storage/belt/utility/servant backpack_contents = list(/obj/item/storage/box/engineer = 1, \ - /obj/item/clockwork/replica_fabricator = 1, /obj/item/stack/tile/brass/fifty = 1, /obj/item/paper/servant_primer = 1, /obj/item/reagent_containers/food/drinks/bottle/holyoil = 1) + /obj/item/clockwork/replica_fabricator = 1, /obj/item/stack/tile/brass/fifty = 1, /obj/item/reagent_containers/food/drinks/bottle/holyoil = 1) id = /obj/item/pda var/plasmaman //We use this to determine if we should activate internals in post_equip() @@ -305,54 +300,3 @@ Credit where due: PDA.update_label() PDA.id_check(H, W) H.sec_hud_set_ID() - - -//This paper serves as a quick run-down to the cult as well as a changelog to refer to. -//Check strings/clockwork_cult_changelog.txt for the changelog, and update it when you can! -/obj/item/paper/servant_primer - name = "The Ark And You: A Primer On Servitude" - color = "#DAAA18" - info = "DON'T PANIC.

\ - Here's a quick primer on what you should know here.\ -
    \ -
  1. You're in a place called Reebe right now. The crew can't get here normally.
  2. \ -
  3. In the north is your base camp, with supplies, consoles, and the Ark. In the south is an inaccessible area that the crew can walk between \ - once they arrive (more on that later.) Everything between that space is an open area.
  4. \ -
  5. Your job as a servant is to build fortifications and defenses to protect the Ark and your base once the Ark activates. You can do this \ - however you like, but work with your allies and coordinate your efforts.
  6. \ -
  7. Once the Ark activates, the station will be alerted. Portals to Reebe will open up in nearly every room. When they take these portals, \ - the crewmembers will arrive in the area that you can't access, but can get through it freely - whereas you can't. Treat this as the \"spawn\" of the \ - crew and defend it accordingly.
  8. \ -
\ -
\ - Here is the layout of Reebe, from left to right:\ - \ -
\ -

Things that have changed:

\ - \ -
\ - Good luck!" - -/obj/item/paper/servant_primer/Initialize() - . = ..() - var/changelog = world.file2list("strings/clockwork_cult_changelog.txt") - var/changelog_contents = "" - for(var/entry in changelog) - changelog_contents += "
  • [entry]
  • " - info = replacetext(info, "CLOCKCULTCHANGELOG", changelog_contents) -/* -/obj/item/paper/servant_primer/oui_getcontent(mob/target) - if(!is_servant_of_ratvar(target) && !isobserver(target)) - return "[name][stars(info)]
    [stamps]" - return ..() -*/ diff --git a/code/game/gamemodes/gangs/dominator.dm b/code/game/gamemodes/gangs/dominator.dm index b4028dc0fd..a7e44ef325 100644 --- a/code/game/gamemodes/gangs/dominator.dm +++ b/code/game/gamemodes/gangs/dominator.dm @@ -149,7 +149,7 @@ add_fingerprint(user) return ..() -/obj/machinery/dominator/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/machinery/dominator/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(operating || (stat & BROKEN)) examine(user) return diff --git a/code/game/gamemodes/sandbox/airlock_maker.dm b/code/game/gamemodes/sandbox/airlock_maker.dm index ddb622ab08..3d8eb7f7fc 100644 --- a/code/game/gamemodes/sandbox/airlock_maker.dm +++ b/code/game/gamemodes/sandbox/airlock_maker.dm @@ -7,7 +7,7 @@ /obj/structure/door_assembly var/datum/airlock_maker/maker = null -/obj/structure/door_assembly/attack_hand() +/obj/structure/door_assembly/on_attack_hand() . = ..() if(.) return diff --git a/code/game/machinery/PDApainter.dm b/code/game/machinery/PDApainter.dm index 634ed2da48..6bac63dff0 100644 --- a/code/game/machinery/PDApainter.dm +++ b/code/game/machinery/PDApainter.dm @@ -107,10 +107,7 @@ stat |= BROKEN update_icon() -/obj/machinery/pdapainter/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) - . = ..() - if(.) - return +/obj/machinery/pdapainter/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(!storedpda) to_chat(user, "[src] is empty.") diff --git a/code/game/machinery/_machinery.dm b/code/game/machinery/_machinery.dm index 6ef13ac36f..3faf6d5727 100644 --- a/code/game/machinery/_machinery.dm +++ b/code/game/machinery/_machinery.dm @@ -313,7 +313,7 @@ Class Procs: if(user.a_intent != INTENT_HARM) return attack_hand(user) else - user.changeNext_move(CLICK_CD_MELEE) + user.DelayNextAction(CLICK_CD_MELEE) user.do_attack_animation(src, ATTACK_EFFECT_PUNCH) user.visible_message("[user.name] smashes against \the [src.name] with its paws.", null, null, COMBAT_MESSAGE_RANGE) take_damage(4, BRUTE, "melee", 1) diff --git a/code/game/machinery/airlock_control.dm b/code/game/machinery/airlock_control.dm index 31fdf675ca..4b5e4088d7 100644 --- a/code/game/machinery/airlock_control.dm +++ b/code/game/machinery/airlock_control.dm @@ -122,10 +122,7 @@ else icon_state = "airlock_sensor_off" -/obj/machinery/airlock_sensor/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) - . = ..() - if(.) - return +/obj/machinery/airlock_sensor/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) var/datum/signal/signal = new(list( "tag" = master_tag, "command" = "cycle" diff --git a/code/game/machinery/aug_manipulator.dm b/code/game/machinery/aug_manipulator.dm index d13c167a22..28733a6b6c 100644 --- a/code/game/machinery/aug_manipulator.dm +++ b/code/game/machinery/aug_manipulator.dm @@ -100,10 +100,7 @@ stat |= BROKEN update_icon() -/obj/machinery/aug_manipulator/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) - . = ..() - if(.) - return +/obj/machinery/aug_manipulator/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) add_fingerprint(user) if(storedpart) diff --git a/code/game/machinery/buttons.dm b/code/game/machinery/buttons.dm index 4661e1bd8f..b5031b68a1 100644 --- a/code/game/machinery/buttons.dm +++ b/code/game/machinery/buttons.dm @@ -138,7 +138,7 @@ var/obj/item/assembly/control/A = device A.id = "[idnum][id]" -/obj/machinery/button/attack_hand(mob/user) +/obj/machinery/button/on_attack_hand(mob/user) . = ..() if(.) return diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm index 5a1547aae0..2795ba45a9 100644 --- a/code/game/machinery/camera/camera.dm +++ b/code/game/machinery/camera/camera.dm @@ -235,7 +235,7 @@ itemname = P.name info = P.notehtml to_chat(U, "You hold \the [itemname] up to the camera...") - U.changeNext_move(CLICK_CD_MELEE) + U.DelayNextAction(CLICK_CD_MELEE) for(var/mob/O in GLOB.player_list) if(isAI(O)) var/mob/living/silicon/ai/AI = O diff --git a/code/game/machinery/cell_charger.dm b/code/game/machinery/cell_charger.dm index 01f73a3c75..effd70e9ab 100644 --- a/code/game/machinery/cell_charger.dm +++ b/code/game/machinery/cell_charger.dm @@ -79,10 +79,7 @@ charging = null update_icon() -/obj/machinery/cell_charger/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) - . = ..() - if(.) - return +/obj/machinery/cell_charger/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(!charging) return diff --git a/code/game/machinery/computer/arcade/misc_arcade.dm b/code/game/machinery/computer/arcade/misc_arcade.dm index 9b7d3d3f6f..24516740f9 100644 --- a/code/game/machinery/computer/arcade/misc_arcade.dm +++ b/code/game/machinery/computer/arcade/misc_arcade.dm @@ -8,7 +8,7 @@ icon_state = "arcade" circuit = /obj/item/circuitboard/computer/arcade/amputation -/obj/machinery/computer/arcade/amputation/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/machinery/computer/arcade/amputation/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(!iscarbon(user)) return var/mob/living/carbon/c_user = user diff --git a/code/game/machinery/computer/camera_advanced.dm b/code/game/machinery/computer/camera_advanced.dm index 9f1390c69b..4b5806b8fd 100644 --- a/code/game/machinery/computer/camera_advanced.dm +++ b/code/game/machinery/computer/camera_advanced.dm @@ -103,10 +103,7 @@ return FALSE return ..() -/obj/machinery/computer/camera_advanced/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) - . = ..() - if(.) - return +/obj/machinery/computer/camera_advanced/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(current_user) to_chat(user, "The console is already in use!") return @@ -276,112 +273,4 @@ C.overlay_fullscreen("flash", /obj/screen/fullscreen/flash/static) C.clear_fullscreen("flash", 3) //Shorter flash than normal since it's an ~~advanced~~ console! else - playsound(origin, 'sound/machines/terminal_prompt_deny.ogg', 25, 0) - - -//Used by servants of Ratvar! They let you beam to the station. -/obj/machinery/computer/camera_advanced/ratvar - name = "ratvarian camera observer" - desc = "A console used to snoop on the station's goings-on. A jet of steam occasionally whooshes out from slats on its sides." - use_power = FALSE - networks = list("ss13", "minisat") //:eye: - var/datum/action/innate/servant_warp/warp_action = new - -/obj/machinery/computer/camera_advanced/ratvar/Initialize() - . = ..() - ratvar_act() - -/obj/machinery/computer/camera_advanced/ratvar/process() - if(prob(1)) - playsound(src, 'sound/machines/clockcult/steam_whoosh.ogg', 25, TRUE) - new/obj/effect/temp_visual/steam_release(get_turf(src)) - -/obj/machinery/computer/camera_advanced/ratvar/CreateEye() - ..() - eyeobj.visible_icon = TRUE - eyeobj.icon = 'icons/mob/cameramob.dmi' //in case you still had any doubts - eyeobj.icon_state = "generic_camera" - -/obj/machinery/computer/camera_advanced/ratvar/GrantActions(mob/living/carbon/user) - ..() - if(warp_action) - warp_action.Grant(user) - warp_action.target = src - actions += warp_action - -/obj/machinery/computer/camera_advanced/ratvar/can_use(mob/living/user) - if(!is_servant_of_ratvar(user)) - to_chat(user, "[src]'s keys are in a language foreign to you, and you don't understand anything on its screen.") - return - if(clockwork_ark_active()) - to_chat(user, "The Ark is active, and [src] has shut down.") - return - . = ..() - -/datum/action/innate/servant_warp - name = "Warp" - desc = "Warps to the tile you're viewing. You can use the Abscond scripture to return. Clicking this button again cancels the warp." - icon_icon = 'icons/mob/actions/actions_clockcult.dmi' - button_icon_state = "warp_down" - background_icon_state = "bg_clock" - buttontooltipstyle = "clockcult" - var/cancel = FALSE //if TRUE, an active warp will be canceled - var/obj/effect/temp_visual/ratvar/warp_marker/warping - -/datum/action/innate/servant_warp/Activate() - if(QDELETED(target) || !(ishuman(owner) || iscyborg(owner)) || !owner.canUseTopic(target)) - return - if(!GLOB.servants_active) //No leaving unless there's servants from the get-go - return - if(warping) - cancel = TRUE - return - var/mob/living/carbon/human/user = owner - var/mob/camera/aiEye/remote/remote_eye = user.remote_control - var/obj/machinery/computer/camera_advanced/ratvar/R = target - var/turf/T = get_turf(remote_eye) - if(!is_reebe(user.z) || !is_station_level(T.z)) - return - if(isclosedturf(T)) - to_chat(user, "You can't teleport into a wall.") - return - else if(isspaceturf(T)) - to_chat(user, "[prob(1) ? "Servant cannot into space." : "You can't teleport into space."]") - return - else if(T.flags_1 & NOJAUNT_1) - to_chat(user, "This tile is blessed by holy water and deflects the warp.") - return - var/area/AR = get_area(T) - if(!AR.clockwork_warp_allowed) - to_chat(user, "[AR.clockwork_warp_fail]") - return - if(alert(user, "Are you sure you want to warp to [AR]?", target.name, "Warp", "Cancel") == "Cancel" || QDELETED(R) || !user.canUseTopic(R)) - return - do_sparks(5, TRUE, user) - do_sparks(5, TRUE, T) - warping = new(T) - user.visible_message("[user]'s [target.name] flares!", "You begin warping to [AR]...") - button_icon_state = "warp_cancel" - owner.update_action_buttons() - if(!do_after(user, 50, target = warping, extra_checks = CALLBACK(src, .proc/is_canceled))) - to_chat(user, "Warp interrupted.") - QDEL_NULL(warping) - button_icon_state = "warp_down" - owner.update_action_buttons() - cancel = FALSE - return - button_icon_state = "warp_down" - owner.update_action_buttons() - QDEL_NULL(warping) - if(!do_teleport(user, T, channel = TELEPORT_CHANNEL_CULT, forced = TRUE)) - to_chat(user, "Warp Failed. Something deflected our attempt to warp to [AR].") - return - T.visible_message("[user] warps in!") - playsound(user, 'sound/magic/magic_missile.ogg', 50, TRUE) - playsound(T, 'sound/magic/magic_missile.ogg', 50, TRUE) - user.setDir(SOUTH) - flash_color(user, flash_color = "#AF0AAF", flash_time = 5) - R.remove_eye_control(user) - -/datum/action/innate/servant_warp/proc/is_canceled() - return !cancel + playsound(origin, 'sound/machines/terminal_prompt_deny.ogg', 25, 0) \ No newline at end of file diff --git a/code/game/machinery/defibrillator_mount.dm b/code/game/machinery/defibrillator_mount.dm index f91fd66fb5..677cbe1208 100644 --- a/code/game/machinery/defibrillator_mount.dm +++ b/code/game/machinery/defibrillator_mount.dm @@ -59,7 +59,7 @@ return defib.get_cell() //defib interaction -/obj/machinery/defibrillator_mount/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/machinery/defibrillator_mount/on_attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) if(!defib) to_chat(user, "There's no defibrillator unit loaded!") return diff --git a/code/game/machinery/dish_drive.dm b/code/game/machinery/dish_drive.dm index 5bf16d4638..3cfd8fdfc4 100644 --- a/code/game/machinery/dish_drive.dm +++ b/code/game/machinery/dish_drive.dm @@ -31,7 +31,7 @@ if(user.Adjacent(src)) . += "Alt-click it to beam its contents to any nearby disposal bins." -/obj/machinery/dish_drive/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/machinery/dish_drive/on_attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) if(!contents.len) to_chat(user, "There's nothing in [src]!") return diff --git a/code/game/machinery/dna_scanner.dm b/code/game/machinery/dna_scanner.dm index 95552d931b..e721e986d2 100644 --- a/code/game/machinery/dna_scanner.dm +++ b/code/game/machinery/dna_scanner.dm @@ -70,8 +70,6 @@ if(!locked) open_machine() return - user.changeNext_move(CLICK_CD_BREAKOUT) - user.last_special = world.time + CLICK_CD_BREAKOUT user.visible_message("You see [user] kicking against the door of [src]!", \ "You lean on the back of [src] and start pushing the door open... (this will take about [DisplayTimeText(breakout_time)].)", \ "You hear a metallic creaking from [src].") diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index a950cb7e7d..b5e752cc6b 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -763,10 +763,7 @@ /obj/machinery/door/airlock/attack_paw(mob/user) return attack_hand(user) -/obj/machinery/door/airlock/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) - . = ..() - if(.) - return +/obj/machinery/door/airlock/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(!(issilicon(user) || IsAdminGhost(user))) if(src.isElectrified()) if(src.shock(user, 100)) @@ -783,6 +780,8 @@ H.apply_damage(10, BRUTE, BODY_ZONE_HEAD) else visible_message("[user] headbutts the airlock. Good thing [user.p_theyre()] wearing a helmet.") + else + return ..() /obj/machinery/door/airlock/attempt_wire_interaction(mob/user) if(security_level) diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm index fd1a8690df..f3886d0036 100644 --- a/code/game/machinery/doors/door.dm +++ b/code/game/machinery/doors/door.dm @@ -140,10 +140,7 @@ do_animate("deny") return -/obj/machinery/door/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) - . = ..() - if(.) - return +/obj/machinery/door/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) return try_to_activate_door(user) /obj/machinery/door/attack_tk(mob/user) diff --git a/code/game/machinery/doors/firedoor.dm b/code/game/machinery/doors/firedoor.dm index 4855280b86..2d41575e70 100644 --- a/code/game/machinery/doors/firedoor.dm +++ b/code/game/machinery/doors/firedoor.dm @@ -24,6 +24,8 @@ armor = list("melee" = 30, "bullet" = 30, "laser" = 20, "energy" = 20, "bomb" = 10, "bio" = 100, "rad" = 100, "fire" = 95, "acid" = 70) interaction_flags_machine = INTERACT_MACHINE_WIRES_IF_OPEN | INTERACT_MACHINE_ALLOW_SILICON | INTERACT_MACHINE_OPEN_SILICON | INTERACT_MACHINE_REQUIRES_SILICON | INTERACT_MACHINE_OPEN air_tight = TRUE + attack_hand_is_action = TRUE + attack_hand_speed = CLICK_CD_MELEE var/emergency_close_timer = 0 var/nextstate = null var/boltslocked = TRUE @@ -80,7 +82,6 @@ return TRUE return FALSE - /obj/machinery/door/firedoor/power_change() if(powered(power_channel)) stat &= ~NOPOWER @@ -88,11 +89,7 @@ else stat |= NOPOWER -/obj/machinery/door/firedoor/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) - . = ..() - if(.) - return - +/obj/machinery/door/firedoor/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(!welded && !operating && !(stat & NOPOWER) && (!density || allow_hand_open(user))) add_fingerprint(user) if(density) @@ -103,7 +100,6 @@ return TRUE if(operating || !density) return - user.changeNext_move(CLICK_CD_MELEE) user.visible_message("[user] bangs on \the [src].", "You bang on \the [src].") diff --git a/code/game/machinery/firealarm.dm b/code/game/machinery/firealarm.dm index 4c68d0b0b5..000b3dc7b5 100644 --- a/code/game/machinery/firealarm.dm +++ b/code/game/machinery/firealarm.dm @@ -141,7 +141,7 @@ if(user) log_game("[user] reset a fire alarm at [COORD(src)]") -/obj/machinery/firealarm/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/machinery/firealarm/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(buildstage != 2) return ..() add_fingerprint(user) diff --git a/code/game/machinery/gulag_teleporter.dm b/code/game/machinery/gulag_teleporter.dm index fb41ac986d..da64699dd4 100644 --- a/code/game/machinery/gulag_teleporter.dm +++ b/code/game/machinery/gulag_teleporter.dm @@ -101,8 +101,6 @@ The console is located at computer/gulag_teleporter.dm if(!locked) open_machine() return - user.changeNext_move(CLICK_CD_BREAKOUT) - user.last_special = world.time + CLICK_CD_BREAKOUT user.visible_message("You see [user] kicking against the door of [src]!", \ "You lean on the back of [src] and start pushing the door open... (this will take about [DisplayTimeText(breakout_time)].)", \ "You hear a metallic creaking from [src].") diff --git a/code/game/machinery/harvester.dm b/code/game/machinery/harvester.dm index 8cb7ca1e8d..191967ac1a 100644 --- a/code/game/machinery/harvester.dm +++ b/code/game/machinery/harvester.dm @@ -50,7 +50,7 @@ harvesting = FALSE warming_up = FALSE -/obj/machinery/harvester/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/machinery/harvester/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(state_open) close_machine() else if(!harvesting) diff --git a/code/game/machinery/hologram.dm b/code/game/machinery/hologram.dm index f43114f7cb..25f4248d6d 100644 --- a/code/game/machinery/hologram.dm +++ b/code/game/machinery/hologram.dm @@ -78,7 +78,7 @@ GLOBAL_LIST_EMPTY(network_holopads) new_disk.forceMove(src) disk = new_disk -/obj/machinery/holopad/tutorial/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/machinery/holopad/tutorial/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(!istype(user)) return if(user.incapacitated() || !is_operational()) diff --git a/code/game/machinery/hypnochair.dm b/code/game/machinery/hypnochair.dm index 5677a09f12..16b464ced6 100644 --- a/code/game/machinery/hypnochair.dm +++ b/code/game/machinery/hypnochair.dm @@ -178,8 +178,6 @@ icon_state += "_occupied" /obj/machinery/hypnochair/container_resist(mob/living/user) - user.changeNext_move(CLICK_CD_BREAKOUT) - user.last_special = world.time + CLICK_CD_BREAKOUT user.visible_message("You see [user] kicking against the door of [src]!", \ "You lean on the back of [src] and start pushing the door open... (this will take about [DisplayTimeText(600)].)", \ "You hear a metallic creaking from [src].") diff --git a/code/game/machinery/igniter.dm b/code/game/machinery/igniter.dm index 7cf21ed767..ba4d01cfe5 100644 --- a/code/game/machinery/igniter.dm +++ b/code/game/machinery/igniter.dm @@ -26,10 +26,7 @@ on = TRUE icon_state = "igniter1" -/obj/machinery/igniter/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) - . = ..() - if(.) - return +/obj/machinery/igniter/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) add_fingerprint(user) use_power(50) diff --git a/code/game/machinery/iv_drip.dm b/code/game/machinery/iv_drip.dm index 7bb08fdbc1..bf71786a05 100644 --- a/code/game/machinery/iv_drip.dm +++ b/code/game/machinery/iv_drip.dm @@ -158,10 +158,7 @@ attached.transfer_blood_to(beaker, amount) update_icon() -/obj/machinery/iv_drip/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) - . = ..() - if(.) - return +/obj/machinery/iv_drip/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(attached) visible_message("[attached] is detached from [src]") attached = null diff --git a/code/game/machinery/porta_turret/portable_turret.dm b/code/game/machinery/porta_turret/portable_turret.dm index 1887ee46c0..2a60711a81 100644 --- a/code/game/machinery/porta_turret/portable_turret.dm +++ b/code/game/machinery/porta_turret/portable_turret.dm @@ -17,6 +17,7 @@ active_power_usage = 300 //when active, this turret takes up constant 300 Equipment power req_access = list(ACCESS_SEC_DOORS) power_channel = EQUIP //drains power from the EQUIPMENT channel + speed_process = TRUE var/base_icon_state = "standard" var/scan_range = 7 @@ -53,7 +54,7 @@ var/last_fired = 0 //world.time the turret last fired var/shot_delay = 15 //ticks until next shot (1.5 ?) - + var/shot_stagger = 0 // sleep() shots to stagger attacks var/check_records = 1 //checks if it can use the security records var/criminals = 1 //checks if it can shoot people on arrest @@ -436,6 +437,9 @@ else if(!always_up) popDown() // no valid targets, close the cover +/obj/machinery/porta_turret/proc/randomize_shot_stagger() + shot_stagger = rand(0, min(2 SECONDS, round(shot_delay/3, world.tick_lag))) + /obj/machinery/porta_turret/proc/tryToShootAt(list/atom/movable/targets) while(targets.len > 0) var/atom/movable/M = pick(targets) @@ -443,7 +447,6 @@ if(target(M)) return 1 - /obj/machinery/porta_turret/proc/popUp() //pops the turret up if(!anchored) return @@ -525,11 +528,14 @@ if(target) popUp() //pop the turret up if it's not already up. setDir(get_dir(base, target))//even if you can't shoot, follow the target - shootAt(target) + INVOKE_ASYNC(src, .proc/shootAt, target) return 1 return -/obj/machinery/porta_turret/proc/shootAt(atom/movable/target) +/obj/machinery/porta_turret/proc/shootAt(atom/movable/target, stagger_enabled = FALSE) + if(stagger_enabled) + randomize_shot_stagger() + sleep(shot_stagger) if(!raised) //the turret has to be raised in order to fire - makes sense, right? return diff --git a/code/game/machinery/porta_turret/portable_turret_construct.dm b/code/game/machinery/porta_turret/portable_turret_construct.dm index bf70ee8a9d..7c2000175e 100644 --- a/code/game/machinery/porta_turret/portable_turret_construct.dm +++ b/code/game/machinery/porta_turret/portable_turret_construct.dm @@ -79,6 +79,9 @@ if(PTURRET_INTERNAL_ARMOUR_ON) if(istype(I, /obj/item/gun/energy)) //the gun installation part var/obj/item/gun/energy/E = I + if(!E.can_turret) + to_chat(user, "[src] can't be fit into turrets.") + return if(!user.transferItemToLoc(E, src)) return installed_gun = E @@ -168,10 +171,7 @@ return ..() -/obj/machinery/porta_turret_construct/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) - . = ..() - if(.) - return +/obj/machinery/porta_turret_construct/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) switch(build_step) if(PTURRET_GUN_EQUIPPED) build_step = PTURRET_INTERNAL_ARMOUR_ON diff --git a/code/game/machinery/porta_turret/portable_turret_cover.dm b/code/game/machinery/porta_turret/portable_turret_cover.dm index 3899f07685..e0746bda78 100644 --- a/code/game/machinery/porta_turret/portable_turret_cover.dm +++ b/code/game/machinery/porta_turret/portable_turret_cover.dm @@ -31,10 +31,7 @@ return parent_turret.attack_ai(user) -/obj/machinery/porta_turret_cover/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) - . = ..() - if(.) - return +/obj/machinery/porta_turret_cover/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) return parent_turret.attack_hand(user) diff --git a/code/game/machinery/recharger.dm b/code/game/machinery/recharger.dm index 5d0d39e3a4..1d118023c9 100755 --- a/code/game/machinery/recharger.dm +++ b/code/game/machinery/recharger.dm @@ -108,10 +108,7 @@ return ..() -/obj/machinery/recharger/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) - . = ..() - if(.) - return +/obj/machinery/recharger/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) add_fingerprint(user) if(charging) diff --git a/code/game/machinery/suit_storage_unit.dm b/code/game/machinery/suit_storage_unit.dm index 7de414fd63..75772786fc 100644 --- a/code/game/machinery/suit_storage_unit.dm +++ b/code/game/machinery/suit_storage_unit.dm @@ -301,8 +301,6 @@ open_machine() dump_contents() return - user.changeNext_move(CLICK_CD_BREAKOUT) - user.last_special = world.time + CLICK_CD_BREAKOUT user.visible_message("You see [user] kicking against the doors of [src]!", \ "You start kicking against the doors... (this will take about [DisplayTimeText(breakout_time)].)", \ "You hear a thump from [src].") diff --git a/code/game/machinery/syndicatebeacon.dm b/code/game/machinery/syndicatebeacon.dm index 8b9aa64c58..1b3f942c51 100644 --- a/code/game/machinery/syndicatebeacon.dm +++ b/code/game/machinery/syndicatebeacon.dm @@ -68,10 +68,7 @@ GLOBAL_VAR_INIT(singularity_counter, 0) /obj/machinery/power/singularity_beacon/attack_ai(mob/user) return -/obj/machinery/power/singularity_beacon/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) - . = ..() - if(.) - return +/obj/machinery/power/singularity_beacon/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(anchored) return active ? Deactivate(user) : Activate(user) else diff --git a/code/game/machinery/telecomms/machines/message_server.dm b/code/game/machinery/telecomms/machines/message_server.dm index c6386241ee..04fd5f6af5 100644 --- a/code/game/machinery/telecomms/machines/message_server.dm +++ b/code/game/machinery/telecomms/machines/message_server.dm @@ -21,7 +21,7 @@ . = ..() stored = new /obj/item/blackbox(src) -/obj/machinery/blackbox_recorder/attack_hand(mob/living/user) +/obj/machinery/blackbox_recorder/on_attack_hand(mob/living/user, act_intent, unarmed_attack_flags) . = ..() if(stored) to_chat(user, "You start struggling to pry the [stored] from the [src]...") diff --git a/code/game/machinery/washing_machine.dm b/code/game/machinery/washing_machine.dm index 9e277b9d8e..3441ac7eaa 100644 --- a/code/game/machinery/washing_machine.dm +++ b/code/game/machinery/washing_machine.dm @@ -297,10 +297,7 @@ GLOBAL_LIST_INIT(dye_registry, list( else return ..() -/obj/machinery/washing_machine/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) - . = ..() - if(.) - return +/obj/machinery/washing_machine/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(busy) to_chat(user, "[src] is busy.") return diff --git a/code/game/machinery/wishgranter.dm b/code/game/machinery/wishgranter.dm index dcd86c9f24..12fdc2193b 100644 --- a/code/game/machinery/wishgranter.dm +++ b/code/game/machinery/wishgranter.dm @@ -10,7 +10,7 @@ var/charges = 1 var/insisting = 0 -/obj/machinery/wish_granter/attack_hand(mob/living/carbon/user) +/obj/machinery/wish_granter/on_attack_hand(mob/living/carbon/user) if(charges <= 0) to_chat(user, "The Wish Granter lies silent.") return @@ -31,7 +31,7 @@ user.dna.add_mutation(XRAY) user.dna.add_mutation(SPACEMUT) user.dna.add_mutation(TK) - user.next_move_modifier *= 0.5 //half the delay between attacks! + user.action_cooldown_mod *= 0.5 to_chat(user, "Things around you feel slower!") charges-- insisting = FALSE @@ -101,7 +101,7 @@ to_chat(user, "[killreward] materializes into your hands!") else to_chat(user, "[killreward] materializes onto the floor.") - user.next_move_modifier *= 0.8 //20% less delay between attacks! + user.action_cooldown_mod *= 0.8 to_chat(user, "Things around you feel slightly slower!") var/mob/living/simple_animal/hostile/venus_human_trap/killwish = new /mob/living/simple_animal/hostile/venus_human_trap(loc) killwish.maxHealth = 1500 diff --git a/code/game/mecha/combat/neovgre.dm b/code/game/mecha/combat/neovgre.dm index fdcc4df151..1bd68546c8 100644 --- a/code/game/mecha/combat/neovgre.dm +++ b/code/game/mecha/combat/neovgre.dm @@ -15,6 +15,8 @@ internals_req_access = list() add_req_access = 0 wreckage = /obj/structure/mecha_wreckage/durand/neovgre + stepsound = 'sound/mecha/neostep2.ogg' + turnsound = 'sound/mecha/powerloader_step.ogg' /obj/mecha/combat/neovgre/GrantActions(mob/living/user, human_occupant = 0) //No Eject action for you sonny jim, your life for Ratvar! internals_action.Grant(user, src) @@ -32,7 +34,7 @@ /obj/mecha/combat/neovgre/MouseDrop_T(mob/M, mob/user) if(!is_servant_of_ratvar(user)) - to_chat(user, "BEGONE HERETIC!") + to_chat(user, "BEGONE HEATHEN!") return else ..() @@ -91,7 +93,7 @@ /obj/item/mecha_parts/mecha_equipment/weapon/energy/laser/heavy/neovgre equip_cooldown = 8 //Rapid fire heavy laser cannon, simple yet elegant energy_drain = 30 - name = "Aribter Laser Cannon" + name = "Arbiter Laser Cannon" desc = "Please re-attach this to neovgre and stop asking questions about why it looks like a normal Nanotrasen issue Solaris laser cannon - Nezbere" fire_sound = 'sound/weapons/neovgre_laser.ogg' diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm index d2340a15ea..5b691607db 100644 --- a/code/game/mecha/mecha.dm +++ b/code/game/mecha/mecha.dm @@ -24,6 +24,8 @@ infra_luminosity = 15 //byond implementation is bugged. force = 5 flags_1 = HEAR_1|BLOCK_FACE_ATOM_1 + attack_hand_speed = CLICK_CD_MELEE + attack_hand_is_action = TRUE var/can_move = 0 //time of next allowed movement var/mob/living/occupant = null var/step_in = 10 //make a step in step_in/10 sec. diff --git a/code/game/mecha/mecha_defense.dm b/code/game/mecha/mecha_defense.dm index dedbef1906..40336fb01e 100644 --- a/code/game/mecha/mecha_defense.dm +++ b/code/game/mecha/mecha_defense.dm @@ -54,11 +54,7 @@ . *= booster_damage_modifier -/obj/mecha/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) - . = ..() - if(.) - return - user.changeNext_move(CLICK_CD_MELEE) // Ugh. Ideally we shouldn't be setting cooldowns outside of click code. +/obj/mecha/on_attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) user.do_attack_animation(src, ATTACK_EFFECT_PUNCH) playsound(loc, 'sound/weapons/tap.ogg', 40, 1, -1) user.visible_message("[user] hits [name]. Nothing happens", null, null, COMBAT_MESSAGE_RANGE) @@ -255,7 +251,7 @@ return else if(istype(W, /obj/item/weldingtool) && user.a_intent != INTENT_HARM) - user.changeNext_move(CLICK_CD_MELEE) + user.DelayNextAction(CLICK_CD_MELEE) if(obj_integrity < max_integrity) if(W.use_tool(src, user, 0, volume=50, amount=1)) if (internal_damage & MECHA_INT_TANK_BREACH) diff --git a/code/game/objects/buckling.dm b/code/game/objects/buckling.dm index eabbdfad88..bdb748925c 100644 --- a/code/game/objects/buckling.dm +++ b/code/game/objects/buckling.dm @@ -9,7 +9,7 @@ var/buckle_prevents_pull = FALSE //Interaction -/atom/movable/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) +/atom/movable/on_attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return @@ -145,3 +145,13 @@ var/mob/living/L = M.pulledby L.set_pull_offsets(M, L.grab_state) return M + +/atom/movable/proc/precise_user_unbuckle_mob(mob/user) + if(!buckled_mobs) + return + else if(length(buckled_mobs) == 1) + return user_unbuckle_mob(buckled_mobs[1], user) + else + var/unbuckled = input(user, "Who do you wish to unbuckle?","Unbuckle Who?") as null|mob in buckled_mobs + return user_unbuckle_mob(unbuckled, user) + diff --git a/code/game/objects/effects/contraband.dm b/code/game/objects/effects/contraband.dm index e4f1c854d0..8e2f39d0df 100644 --- a/code/game/objects/effects/contraband.dm +++ b/code/game/objects/effects/contraband.dm @@ -101,10 +101,7 @@ to_chat(user, "You carefully remove the poster from the wall.") roll_and_drop(user.loc) -/obj/structure/sign/poster/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) - . = ..() - if(.) - return +/obj/structure/sign/poster/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(ruined) return visible_message("[user] rips [src] in a single, decisive motion!" ) diff --git a/code/game/objects/effects/decals/cleanable/misc.dm b/code/game/objects/effects/decals/cleanable/misc.dm index 01f0b6f957..044c5c6e86 100644 --- a/code/game/objects/effects/decals/cleanable/misc.dm +++ b/code/game/objects/effects/decals/cleanable/misc.dm @@ -137,10 +137,7 @@ random_icon_states = list("vomit_1", "vomit_2", "vomit_3", "vomit_4") beauty = -150 -/obj/effect/decal/cleanable/vomit/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) - . = ..() - if(.) - return +/obj/effect/decal/cleanable/vomit/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(ishuman(user)) var/mob/living/carbon/human/H = user if(isflyperson(H)) diff --git a/code/game/objects/effects/effect_system/effects_foam.dm b/code/game/objects/effects/effect_system/effects_foam.dm index 0cf95ea263..640675bea5 100644 --- a/code/game/objects/effects/effect_system/effects_foam.dm +++ b/code/game/objects/effects/effect_system/effects_foam.dm @@ -268,6 +268,8 @@ gender = PLURAL max_integrity = 20 CanAtmosPass = ATMOS_PASS_DENSITY + attack_hand_speed = CLICK_CD_MELEE + attack_hand_is_action = TRUE /obj/structure/foamedmetal/Initialize() . = ..() @@ -284,11 +286,7 @@ /obj/structure/foamedmetal/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0) playsound(src.loc, 'sound/weapons/tap.ogg', 100, 1) -/obj/structure/foamedmetal/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) - . = ..() - if(.) - return - user.changeNext_move(CLICK_CD_MELEE) +/obj/structure/foamedmetal/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) user.do_attack_animation(src, ATTACK_EFFECT_PUNCH) to_chat(user, "You hit [src] but bounce off it!") playsound(src.loc, 'sound/weapons/tap.ogg', 100, 1) diff --git a/code/game/objects/effects/portals.dm b/code/game/objects/effects/portals.dm index e363529c46..0b227be247 100644 --- a/code/game/objects/effects/portals.dm +++ b/code/game/objects/effects/portals.dm @@ -60,10 +60,7 @@ /obj/effect/portal/attack_tk(mob/user) return -/obj/effect/portal/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) - . = ..() - if(.) - return +/obj/effect/portal/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(get_turf(user) == get_turf(src)) teleport(user) if(Adjacent(user)) diff --git a/code/game/objects/effects/spiders.dm b/code/game/objects/effects/spiders.dm index 745b281d2a..4b04606401 100644 --- a/code/game/objects/effects/spiders.dm +++ b/code/game/objects/effects/spiders.dm @@ -120,6 +120,8 @@ var/poison_type = "toxin" var/poison_per_bite = 5 var/list/faction = list("spiders") + attack_hand_speed = CLICK_CD_MELEE + attack_hand_is_action = TRUE /obj/structure/spider/spiderling/Destroy() new/obj/item/reagent_containers/food/snacks/spiderling(get_turf(src)) @@ -153,10 +155,9 @@ else ..() -/obj/structure/spider/spiderling/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/structure/spider/spiderling/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(user.a_intent != INTENT_HELP) - user.changeNext_move(CLICK_CD_MELEE) user.do_attack_animation(src) user.visible_message("[user] splats [src].", "You splat [src].", "You hear a splat...") playsound(loc, 'sound/effects/snap.ogg', 25) @@ -253,8 +254,6 @@ /obj/structure/spider/cocoon/container_resist(mob/living/user) var/breakout_time = 600 - user.changeNext_move(CLICK_CD_BREAKOUT) - user.last_special = world.time + CLICK_CD_BREAKOUT to_chat(user, "You struggle against the tight bonds... (This will take about [DisplayTimeText(breakout_time)].)") visible_message("You see something struggling and writhing in \the [src]!") if(do_after(user,(breakout_time), target = src)) @@ -262,8 +261,6 @@ return qdel(src) - - /obj/structure/spider/cocoon/Destroy() var/turf/T = get_turf(src) src.visible_message("\The [src] splits open.") diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index a3bbf95413..5870c8a780 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -11,6 +11,10 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb name = "item" icon = 'icons/obj/items_and_weapons.dmi' blocks_emissive = EMISSIVE_BLOCK_GENERIC + + attack_hand_speed = 0 + attack_hand_is_action = FALSE + attack_hand_unwieldlyness = 0 ///icon state name for inhand overlays var/item_state = null @@ -58,15 +62,6 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb /// How long, in deciseconds, this staggers for, if null it will autocalculate from w_class and force. Unlike total mass this supports 0 and negatives. var/stagger_force - /** - * Set FALSE and then checked at the end of on mob/living/attackby(), set TRUE on living/pre_attacked_by(). - * Should it be FALSE by the end of the item/attack(), that means the item overrode the standard attack behaviour - * and the user still needs the delay applied. We can't be using return values since that'll stop afterattack() from being triggered. - */ - var/attack_delay_done = FALSE - ///next_move click/attack delay of this item. - var/click_delay = CLICK_CD_MELEE - var/slot_flags = 0 //This is used to determine on which slots an item can fit. var/current_equipped_slot pass_flags = PASSTABLE @@ -313,10 +308,7 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb add_fingerprint(usr) return ..() -/obj/item/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) - . = ..() - if(.) - return +/obj/item/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(!user) return if(anchored) @@ -473,6 +465,7 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb usr.UnarmedAttack(src, TRUE) if(usr.get_active_held_item() == src) melee_attack_chain(usr, over) + usr.FlushCurrentAction() return TRUE //returning TRUE as a "is this overridden?" flag if(!Adjacent(usr) || !over.Adjacent(usr)) return // should stop you from dragging through windows diff --git a/code/game/objects/items/armor_kits.dm b/code/game/objects/items/armor_kits.dm new file mode 100644 index 0000000000..fa88b77600 --- /dev/null +++ b/code/game/objects/items/armor_kits.dm @@ -0,0 +1,44 @@ +// Armor kits! Reinforcing uniforms to maintain fashion and also armor capabilities. + +/obj/item/armorkit + name = "durathread armor kit" + desc = "A glorified sewing kit with durathread sheets, thread, and a titanium needle, for reinforcing jumpsuits and uniforms." + icon = 'icons/obj/clothing/reinf_kits.dmi' + w_class = WEIGHT_CLASS_SMALL + icon_state = "durathread_kit" // shoutout to my guy Toriate for being good at sprites tho + +/obj/item/armorkit/afterattack(atom/target, mob/user, proximity_flag, click_parameters) + // yeah have fun making subtypes and modifying the afterattack if you want to make variants + // idiot + // - hatter + var/used = FALSE + + if(isobj(target) && istype(target, /obj/item/clothing/under)) + var/obj/item/clothing/under/C = target + if(C.armor.melee < 10) + C.armor.melee = 10 + used = TRUE + if(C.armor.laser < 10) + C.armor.laser = 10 + used = TRUE + if(C.armor.fire < 40) + C.armor.fire = 40 + used = TRUE + if(C.armor.acid < 10) + C.armor.acid = 10 + used = TRUE + if(C.armor.bomb < 5) + C.armor.bomb = 5 + used = TRUE + + if(used) + user.visible_message("[user] uses [src] on [C], reinforcing it and tossing the empty case away afterwards.", \ + "You reinforce [C] with [src], making it a little more protective! You toss the empty casing away afterwards.") + C.name = "durathread [C.name]" // this disappears if it gets repaired, which is annoying + qdel(src) + return + else + to_chat(user, "You stare at [src] and [C], coming to the conclusion that you probably don't need to reinforce it any further.") + return + else + return diff --git a/code/game/objects/items/bodybag.dm b/code/game/objects/items/bodybag.dm index dbc66b1899..428efe4abe 100644 --- a/code/game/objects/items/bodybag.dm +++ b/code/game/objects/items/bodybag.dm @@ -71,8 +71,6 @@ if(user.incapacitated()) to_chat(user, "You can't get out while you're restrained like this!") return - user.changeNext_move(CLICK_CD_BREAKOUT) - user.last_special = world.time + CLICK_CD_BREAKOUT to_chat(user, "You claw at the fabric of [src], trying to tear it open...") to_chat(loc, "Someone starts trying to break free of [src]!") if(!do_after(user, 200, target = src)) diff --git a/code/game/objects/items/cardboard_cutouts.dm b/code/game/objects/items/cardboard_cutouts.dm index 3d444b7eca..a8ff7b9004 100644 --- a/code/game/objects/items/cardboard_cutouts.dm +++ b/code/game/objects/items/cardboard_cutouts.dm @@ -6,6 +6,8 @@ icon_state = "cutout_basic" w_class = WEIGHT_CLASS_BULKY resistance_flags = FLAMMABLE + attack_hand_speed = CLICK_CD_MELEE + attack_hand_is_action = TRUE /// Possible restyles for the cutout, add an entry in change_appearance() if you add to here var/static/list/possible_appearances /// If the cutout is pushed over and has to be righted @@ -43,8 +45,7 @@ "Monkey" = image(icon = src.icon, icon_state = "cutout_monky"), )) -//ATTACK HAND IGNORING PARENT RETURN VALUE -/obj/item/cardboard_cutout/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/item/cardboard_cutout/on_attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) if(user.a_intent == INTENT_HELP || pushed_over) return ..() user.visible_message("[user] pushes over [src]!", "You push over [src]!") @@ -81,7 +82,6 @@ else if(I.hitsound) playsound(loc, I.hitsound, get_clamped_volume(), 1, -1) - user.changeNext_move(CLICK_CD_MELEE) user.do_attack_animation(src) if(I.force) diff --git a/code/game/objects/items/cosmetics.dm b/code/game/objects/items/cosmetics.dm index 4dcaed2cf7..592f238cec 100644 --- a/code/game/objects/items/cosmetics.dm +++ b/code/game/objects/items/cosmetics.dm @@ -188,4 +188,4 @@ else ..() else - ..() \ No newline at end of file + ..() diff --git a/code/game/objects/items/courtroom.dm b/code/game/objects/items/courtroom.dm index c0e81ed3d5..13b83c9425 100644 --- a/code/game/objects/items/courtroom.dm +++ b/code/game/objects/items/courtroom.dm @@ -32,6 +32,6 @@ if(istype(I, /obj/item/gavelhammer)) playsound(loc, 'sound/items/gavel.ogg', 100, 1) user.visible_message("[user] strikes [src] with [I].") - user.changeNext_move(CLICK_CD_MELEE) + return TRUE else - return ..() \ No newline at end of file + return ..() diff --git a/code/game/objects/items/crayons.dm b/code/game/objects/items/crayons.dm index 620fbbf100..a366a2ef88 100644 --- a/code/game/objects/items/crayons.dm +++ b/code/game/objects/items/crayons.dm @@ -273,7 +273,9 @@ . = ..() if(!proximity || !check_allowed_items(target)) return + draw_on(target, user, proximity, params) +/obj/item/toy/crayon/proc/draw_on(atom/target, mob/user, proximity, params) var/static/list/punctuation = list("!","?",".",",","/","+","-","=","%","#","&") var/cost = 1 @@ -568,9 +570,9 @@ dye_color = DYE_RAINBOW charges = -1 -/obj/item/toy/crayon/rainbow/afterattack(atom/target, mob/user, proximity, params) +/obj/item/toy/crayon/rainbow/draw_on(atom/target, mob/user, proximity, params) paint_color = rgb(rand(0,255), rand(0,255), rand(0,255)) - . = ..() + return ..() /* * Crayon Box @@ -693,7 +695,7 @@ . += "It is empty." . += "Alt-click [src] to [ is_capped ? "take the cap off" : "put the cap on"]." -/obj/item/toy/crayon/spraycan/afterattack(atom/target, mob/user, proximity, params) +/obj/item/toy/crayon/spraycan/draw_on(atom/target, mob/user, proximity, params) if(!proximity) return @@ -766,7 +768,7 @@ desc = "A metallic container containing shiny synthesised paint." charges = -1 -/obj/item/toy/crayon/spraycan/borg/afterattack(atom/target,mob/user,proximity, params) +/obj/item/toy/crayon/spraycan/borg/draw_on(atom/target,mob/user,proximity, params) var/diff = ..() if(!iscyborg(user)) to_chat(user, "How did you get this?") diff --git a/code/game/objects/items/defib.dm b/code/game/objects/items/defib.dm index e15dc72838..767f8fc395 100644 --- a/code/game/objects/items/defib.dm +++ b/code/game/objects/items/defib.dm @@ -77,8 +77,7 @@ /obj/item/defibrillator/ui_action_click() toggle_paddles() -//ATTACK HAND IGNORING PARENT RETURN VALUE -/obj/item/defibrillator/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/item/defibrillator/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(loc == user) if(slot_flags == ITEM_SLOT_BACK) if(user.get_item_by_slot(SLOT_BACK) == src) diff --git a/code/game/objects/items/devices/chameleonproj.dm b/code/game/objects/items/devices/chameleonproj.dm index 57443de973..a45f26062b 100644 --- a/code/game/objects/items/devices/chameleonproj.dm +++ b/code/game/objects/items/devices/chameleonproj.dm @@ -132,8 +132,7 @@ /obj/effect/dummy/chameleon/attackby() master.disrupt() -//ATTACK HAND IGNORING PARENT RETURN VALUE -/obj/effect/dummy/chameleon/attack_hand() +/obj/effect/dummy/chameleon/on_attack_hand() master.disrupt() /obj/effect/dummy/chameleon/attack_animal() diff --git a/code/game/objects/items/devices/dogborg_sleeper.dm b/code/game/objects/items/devices/dogborg_sleeper.dm index 41a12136ef..d8abccb336 100644 --- a/code/game/objects/items/devices/dogborg_sleeper.dm +++ b/code/game/objects/items/devices/dogborg_sleeper.dm @@ -116,8 +116,6 @@ if(!hound) go_out(user) return - user.changeNext_move(CLICK_CD_BREAKOUT) - user.last_special = world.time + CLICK_CD_BREAKOUT if(user.a_intent == INTENT_HELP) return var/voracious = TRUE diff --git a/code/game/objects/items/devices/forcefieldprojector.dm b/code/game/objects/items/devices/forcefieldprojector.dm index 03ca110ec8..9ef9d73705 100644 --- a/code/game/objects/items/devices/forcefieldprojector.dm +++ b/code/game/objects/items/devices/forcefieldprojector.dm @@ -43,7 +43,7 @@ user.visible_message("[user] projects a forcefield!","You project a forcefield.") var/obj/structure/projected_forcefield/F = new(T, src) current_fields += F - user.changeNext_move(CLICK_CD_MELEE) + user.DelayNextAction(CLICK_CD_MELEE) /obj/item/forcefield_projector/attack_self(mob/user) if(LAZYLEN(current_fields)) diff --git a/code/game/objects/items/devices/multitool.dm b/code/game/objects/items/devices/multitool.dm index 4d0ed362fc..7a8a523a18 100644 --- a/code/game/objects/items/devices/multitool.dm +++ b/code/game/objects/items/devices/multitool.dm @@ -263,3 +263,11 @@ icon = 'icons/obj/advancedtools.dmi' icon_state = "multitool" toolspeed = 0.2 + +/obj/item/multitool/advanced/brass + name = "clockwork multitool" + desc = "A brass...multitool? With three prongs arcing electricity between them. It vibrates subtly in your hand." + icon = 'icons/obj/tools.dmi' + icon_state = "clockitool" + toolspeed = 0.2 + diff --git a/code/game/objects/items/devices/polycircuit.dm b/code/game/objects/items/devices/polycircuit.dm index a9f7cd46c8..0308f19b5f 100644 --- a/code/game/objects/items/devices/polycircuit.dm +++ b/code/game/objects/items/devices/polycircuit.dm @@ -11,7 +11,7 @@ /obj/item/stack/circuit_stack/attack_self(mob/user)// Prevents the crafting menu, and tells you how to use it. to_chat(user, "You can't use [src] by itself, you'll have to try and remove one of these circuits by hand... carefully.") -/obj/item/stack/circuit_stack/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/item/stack/circuit_stack/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) var/mob/living/carbon/human/H = user if(!user.get_inactive_held_item() == src) return ..() diff --git a/code/game/objects/items/devices/powersink.dm b/code/game/objects/items/devices/powersink.dm index ec59009794..c3127c246f 100644 --- a/code/game/objects/items/devices/powersink.dm +++ b/code/game/objects/items/devices/powersink.dm @@ -97,10 +97,7 @@ GLOBAL_LIST_EMPTY(power_sinks) /obj/item/powersink/attack_ai() return -/obj/item/powersink/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) - . = ..() - if(.) - return +/obj/item/powersink/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) switch(mode) if(DISCONNECTED) ..() diff --git a/code/game/objects/items/devices/radio/electropack.dm b/code/game/objects/items/devices/radio/electropack.dm index cdb8c09527..0cf7ceb55b 100644 --- a/code/game/objects/items/devices/radio/electropack.dm +++ b/code/game/objects/items/devices/radio/electropack.dm @@ -31,8 +31,7 @@ SSradio.remove_object(src, frequency) . = ..() -//ATTACK HAND IGNORING PARENT RETURN VALUE -/obj/item/electropack/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/item/electropack/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(iscarbon(user)) var/mob/living/carbon/C = user if(src == C.back) @@ -162,7 +161,7 @@ materials = list(/datum/material/iron = 5000, /datum/material/glass =2000) category = list("hacked", "Misc") -/obj/item/electropack/shockcollar/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/item/electropack/shockcollar/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(loc == user && user.get_item_by_slot(SLOT_NECK)) to_chat(user, "The collar is fastened tight! You'll need help taking this off!") return diff --git a/code/game/objects/items/devices/radio/intercom.dm b/code/game/objects/items/devices/radio/intercom.dm index ec19c0c05e..8657684ff4 100644 --- a/code/game/objects/items/devices/radio/intercom.dm +++ b/code/game/objects/items/devices/radio/intercom.dm @@ -86,10 +86,7 @@ /obj/item/radio/intercom/attack_ai(mob/user) interact(user) -/obj/item/radio/intercom/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) - . = ..() - if(.) - return +/obj/item/radio/intercom/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) interact(user) /obj/item/radio/intercom/interact(mob/user) diff --git a/code/game/objects/items/devices/reverse_bear_trap.dm b/code/game/objects/items/devices/reverse_bear_trap.dm index 46b9547e9d..f2a0ea5450 100644 --- a/code/game/objects/items/devices/reverse_bear_trap.dm +++ b/code/game/objects/items/devices/reverse_bear_trap.dm @@ -45,7 +45,7 @@ to_chat(loc, "*ding*") addtimer(CALLBACK(src, .proc/snap), 2) -/obj/item/reverse_bear_trap/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/item/reverse_bear_trap/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(iscarbon(user)) var/mob/living/carbon/C = user if(C.get_item_by_slot(SLOT_HEAD) == src) diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm index 2011943bfb..fae2833c8a 100644 --- a/code/game/objects/items/devices/scanners.dm +++ b/code/game/objects/items/devices/scanners.dm @@ -624,54 +624,13 @@ GENETICS SCANNER if (user.stat || user.eye_blind) return - var/turf/location = user.loc + //Functionality moved down to proc/scan_turf() + var/turf/location = get_turf(user) if(!istype(location)) return - - var/datum/gas_mixture/environment = location.return_air() - - var/pressure = environment.return_pressure() - var/total_moles = environment.total_moles() - - to_chat(user, "Results:") - if(abs(pressure - ONE_ATMOSPHERE) < 10) - to_chat(user, "Pressure: [round(pressure, 0.01)] kPa") - else - to_chat(user, "Pressure: [round(pressure, 0.01)] kPa") - if(total_moles) - - var/o2_concentration = environment.get_moles(/datum/gas/oxygen)/total_moles - var/n2_concentration = environment.get_moles(/datum/gas/nitrogen)/total_moles - var/co2_concentration = environment.get_moles(/datum/gas/carbon_dioxide)/total_moles - var/plasma_concentration = environment.get_moles(/datum/gas/plasma)/total_moles - - if(abs(n2_concentration - N2STANDARD) < 20) - to_chat(user, "Nitrogen: [round(n2_concentration*100, 0.01)] % ([round(environment.get_moles(/datum/gas/nitrogen), 0.01)] mol)") - else - to_chat(user, "Nitrogen: [round(n2_concentration*100, 0.01)] % ([round(environment.get_moles(/datum/gas/nitrogen), 0.01)] mol)") - - if(abs(o2_concentration - O2STANDARD) < 2) - to_chat(user, "Oxygen: [round(o2_concentration*100, 0.01)] % ([round(environment.get_moles(/datum/gas/oxygen), 0.01)] mol)") - else - to_chat(user, "Oxygen: [round(o2_concentration*100, 0.01)] % ([round(environment.get_moles(/datum/gas/oxygen), 0.01)] mol)") - - if(co2_concentration > 0.01) - to_chat(user, "CO2: [round(co2_concentration*100, 0.01)] % ([round(environment.get_moles(/datum/gas/carbon_dioxide), 0.01)] mol)") - else - to_chat(user, "CO2: [round(co2_concentration*100, 0.01)] % ([round(environment.get_moles(/datum/gas/carbon_dioxide), 0.01)] mol)") - - if(plasma_concentration > 0.005) - to_chat(user, "Plasma: [round(plasma_concentration*100, 0.01)] % ([round(environment.get_moles(/datum/gas/plasma), 0.01)] mol)") - else - to_chat(user, "Plasma: [round(plasma_concentration*100, 0.01)] % ([round(environment.get_moles(/datum/gas/plasma), 0.01)] mol)") - - for(var/id in environment.get_gases()) - if(id in GLOB.hardcoded_gases) - continue - var/gas_concentration = environment.get_moles(id)/total_moles - to_chat(user, "[GLOB.meta_gas_names[id]]: [round(gas_concentration*100, 0.01)] % ([round(environment.get_moles(id), 0.01)] mol)") - to_chat(user, "Temperature: [round(environment.return_temperature()-T0C, 0.01)] °C ([round(environment.return_temperature(), 0.01)] K)") - + + scan_turf(user, location) + /obj/item/analyzer/AltClick(mob/user) //Barometer output for measuring when the next storm happens . = ..() @@ -749,7 +708,7 @@ GENETICS SCANNER var/total_moles = air_contents.total_moles() var/pressure = air_contents.return_pressure() - var/volume = air_contents.return_volume() + var/volume = air_contents.return_volume() //could just do mixture.volume... but safety, I guess? var/temperature = air_contents.return_temperature() var/cached_scan_results = air_contents.analyzer_results @@ -776,6 +735,73 @@ GENETICS SCANNER to_chat(user, "Power of the last fusion reaction: [fusion_power]\n This power indicates it was a [tier]-tier fusion reaction.") return +/obj/item/analyzer/proc/scan_turf(mob/user, turf/location) + + var/datum/gas_mixture/environment = location.return_air() + + var/pressure = environment.return_pressure() + var/total_moles = environment.total_moles() + var/cached_scan_results = environment.analyzer_results + + to_chat(user, "Results:") + if(abs(pressure - ONE_ATMOSPHERE) < 10) + to_chat(user, "Pressure: [round(pressure, 0.01)] kPa") + else + to_chat(user, "Pressure: [round(pressure, 0.01)] kPa") + if(total_moles) + + var/o2_concentration = environment.get_moles(/datum/gas/oxygen)/total_moles + var/n2_concentration = environment.get_moles(/datum/gas/nitrogen)/total_moles + var/co2_concentration = environment.get_moles(/datum/gas/carbon_dioxide)/total_moles + var/plasma_concentration = environment.get_moles(/datum/gas/plasma)/total_moles + + if(abs(n2_concentration - N2STANDARD) < 20) + to_chat(user, "Nitrogen: [round(n2_concentration*100, 0.01)] % ([round(environment.get_moles(/datum/gas/nitrogen), 0.01)] mol)") + else + to_chat(user, "Nitrogen: [round(n2_concentration*100, 0.01)] % ([round(environment.get_moles(/datum/gas/nitrogen), 0.01)] mol)") + + if(abs(o2_concentration - O2STANDARD) < 2) + to_chat(user, "Oxygen: [round(o2_concentration*100, 0.01)] % ([round(environment.get_moles(/datum/gas/oxygen), 0.01)] mol)") + else + to_chat(user, "Oxygen: [round(o2_concentration*100, 0.01)] % ([round(environment.get_moles(/datum/gas/oxygen), 0.01)] mol)") + + if(co2_concentration > 0.01) + to_chat(user, "CO2: [round(co2_concentration*100, 0.01)] % ([round(environment.get_moles(/datum/gas/carbon_dioxide), 0.01)] mol)") + else + to_chat(user, "CO2: [round(co2_concentration*100, 0.01)] % ([round(environment.get_moles(/datum/gas/carbon_dioxide), 0.01)] mol)") + + if(plasma_concentration > 0.005) + to_chat(user, "Plasma: [round(plasma_concentration*100, 0.01)] % ([round(environment.get_moles(/datum/gas/plasma), 0.01)] mol)") + else + to_chat(user, "Plasma: [round(plasma_concentration*100, 0.01)] % ([round(environment.get_moles(/datum/gas/plasma), 0.01)] mol)") + + for(var/id in environment.get_gases()) + if(id in GLOB.hardcoded_gases) + continue + var/gas_concentration = environment.get_moles(id)/total_moles + to_chat(user, "[GLOB.meta_gas_names[id]]: [round(gas_concentration*100, 0.01)] % ([round(environment.get_moles(id), 0.01)] mol)") + to_chat(user, "Temperature: [round(environment.return_temperature()-T0C, 0.01)] °C ([round(environment.return_temperature(), 0.01)] K)") + + if(cached_scan_results && cached_scan_results["fusion"]) //notify the user if a fusion reaction was detected + var/fusion_power = round(cached_scan_results["fusion"], 0.01) + var/tier = fusionpower2text(fusion_power) + to_chat(user, "Large amounts of free neutrons detected in the air indicate that a fusion reaction took place.") + to_chat(user, "Power of the last fusion reaction: [fusion_power]\n This power indicates it was a [tier]-tier fusion reaction.") + +/obj/item/analyzer/ranged + desc = "A hand-held scanner which uses advanced spectroscopy and infrared readings to analyze gases as a distance. Alt-Click to use the built in barometer function." + name = "long-range analyzer" + icon = 'icons/obj/device.dmi' + icon_state = "ranged_analyzer" + +/obj/item/analyzer/ranged/afterattack(atom/target, mob/user, proximity_flag, click_parameters) + . = ..() + if(target.tool_act(user, src, tool_behaviour)) + return + // Tool act didn't scan it, so let's get it's turf. + var/turf/location = get_turf(target) + scan_turf(user, location) + //slime scanner /obj/item/slime_scanner @@ -966,4 +992,4 @@ GENETICS SCANNER #undef SCANMODE_CHEMICAL #undef SCANMODE_WOUND #undef SCANNER_CONDENSED -#undef SCANNER_VERBOSE +#undef SCANNER_VERBOSE \ No newline at end of file diff --git a/code/game/objects/items/devices/taperecorder.dm b/code/game/objects/items/devices/taperecorder.dm index 5765ac71f1..cef06bfde8 100644 --- a/code/game/objects/items/devices/taperecorder.dm +++ b/code/game/objects/items/devices/taperecorder.dm @@ -54,8 +54,7 @@ mytape.ruin() //Fires destroy the tape ..() -//ATTACK HAND IGNORING PARENT RETURN VALUE -/obj/item/taperecorder/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/item/taperecorder/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(loc == user) if(mytape) if(!user.is_holding(src)) diff --git a/code/game/objects/items/devices/transfer_valve.dm b/code/game/objects/items/devices/transfer_valve.dm index ccf9dcd253..c791b7e323 100644 --- a/code/game/objects/items/devices/transfer_valve.dm +++ b/code/game/objects/items/devices/transfer_valve.dm @@ -79,7 +79,7 @@ if(attached_device) attached_device.Crossed(AM) -/obj/item/transfer_valve/attack_hand()//Triggers mousetraps +/obj/item/transfer_valve/on_attack_hand()//Triggers mousetraps . = ..() if(.) return diff --git a/code/game/objects/items/eightball.dm b/code/game/objects/items/eightball.dm index 837f57ceb5..dbc4c297ca 100644 --- a/code/game/objects/items/eightball.dm +++ b/code/game/objects/items/eightball.dm @@ -229,4 +229,4 @@ else votes[selected_answer] += 1 voted[user.ckey] = selected_answer - . = TRUE \ No newline at end of file + . = TRUE diff --git a/code/game/objects/items/electrostaff.dm b/code/game/objects/items/electrostaff.dm index 8d1fe4ebd1..9750994c87 100644 --- a/code/game/objects/items/electrostaff.dm +++ b/code/game/objects/items/electrostaff.dm @@ -15,6 +15,7 @@ attack_verb = list("struck", "beaten", "thwacked", "pulped") total_mass = 5 //yeah this is a heavy thing, beating people with it while it's off is not going to do you any favors. (to curb stun-kill rampaging without it being on) block_parry_data = /datum/block_parry_data/electrostaff + attack_speed = CLICK_CD_MELEE var/obj/item/stock_parts/cell/cell = /obj/item/stock_parts/cell/high var/on = FALSE var/can_block_projectiles = FALSE //can't block guns diff --git a/code/game/objects/items/flamethrower.dm b/code/game/objects/items/flamethrower.dm index f293e6579a..515f5715dd 100644 --- a/code/game/objects/items/flamethrower.dm +++ b/code/game/objects/items/flamethrower.dm @@ -131,6 +131,7 @@ /obj/item/flamethrower/analyzer_act(mob/living/user, obj/item/I) if(ptank) ptank.analyzer_act(user, I) + return TRUE /obj/item/flamethrower/attack_self(mob/user) diff --git a/code/game/objects/items/granters.dm b/code/game/objects/items/granters.dm index 4ad71f7c46..1554142c8c 100644 --- a/code/game/objects/items/granters.dm +++ b/code/game/objects/items/granters.dm @@ -477,6 +477,23 @@ name = "empty scroll" icon_state = "blankscroll" +/obj/item/book/granter/martial/krav_maga + martial = /datum/martial_art/krav_maga + name = "parchment scroll" + martialname = "krav maga" + desc = "A worn parchment scrap written in an ancient language. Somehow you can still understand the lessons!" + greet = "You have learned the ancient martial art of Krav Maga. You have special attacks with which to take down your foes." + icon = 'icons/obj/wizard.dmi' + icon_state ="scroll2" + remarks = list("Sweep the legs...", "Chop the throat...", "Punch the lungs...", "Get the gold...", "Where are my sick gloves..?") + +/obj/item/book/granter/martial/krav_maga/onlearned(mob/living/carbon/user) + . = ..() + if(oneuse == TRUE) + desc = "It's completely blank." + name = "empty scroll" + icon_state = "blankscroll" + // I did not include mushpunch's grant, it is not a book and the item does it just fine. diff --git a/code/game/objects/items/grenades/flashbang.dm b/code/game/objects/items/grenades/flashbang.dm index bd25169fe4..bf9fab5f04 100644 --- a/code/game/objects/items/grenades/flashbang.dm +++ b/code/game/objects/items/grenades/flashbang.dm @@ -124,9 +124,11 @@ /obj/item/grenade/primer/attack_self(mob/user) . = ..() if(active) + if(!user.CheckActionCooldown()) + return user.playsound_local(user, 'sound/misc/box_deploy.ogg', 50, TRUE) rots++ - user.changeNext_move(CLICK_CD_RAPID) + user.DelayNextAction(CLICK_CD_RAPID) /obj/item/grenade/primer/prime(mob/living/lanced_by) shrapnel_radius = round(rots / rots_per_mag) diff --git a/code/game/objects/items/handcuffs.dm b/code/game/objects/items/handcuffs.dm index e3388b12eb..4c9ea06620 100644 --- a/code/game/objects/items/handcuffs.dm +++ b/code/game/objects/items/handcuffs.dm @@ -320,7 +320,7 @@ do_sparks(1, TRUE, src) qdel(src) -/obj/item/restraints/legcuffs/beartrap/energy/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/item/restraints/legcuffs/beartrap/energy/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) Crossed(user) //honk . = ..() diff --git a/code/game/objects/items/implants/implantchair.dm b/code/game/objects/items/implants/implantchair.dm index 3ea27c84bb..b3c1f79e94 100644 --- a/code/game/objects/items/implants/implantchair.dm +++ b/code/game/objects/items/implants/implantchair.dm @@ -121,8 +121,6 @@ update_icon() /obj/machinery/implantchair/container_resist(mob/living/user) - user.changeNext_move(CLICK_CD_BREAKOUT) - user.last_special = world.time + CLICK_CD_BREAKOUT user.visible_message("You see [user] kicking against the door of [src]!", \ "You lean on the back of [src] and start pushing the door open... (this will take about [DisplayTimeText(breakout_time)].)", \ "You hear a metallic creaking from [src].") @@ -191,4 +189,4 @@ brainwash(C, objective) message_admins("[ADMIN_LOOKUPFLW(user)] brainwashed [key_name_admin(C)] with objective '[objective]'.") log_game("[key_name(user)] brainwashed [key_name(C)] with objective '[objective]'.") - return TRUE \ No newline at end of file + return TRUE diff --git a/code/game/objects/items/melee/energy.dm b/code/game/objects/items/melee/energy.dm index 20960da7c6..e0b08ba8ef 100644 --- a/code/game/objects/items/melee/energy.dm +++ b/code/game/objects/items/melee/energy.dm @@ -147,6 +147,12 @@ return NONE return ..() +/obj/item/melee/transforming/energy/sword/on_active_parry(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, list/block_return, parry_efficiency, parry_time) + . = ..() + if(parry_efficiency >= 80) // perfect parry + block_return[BLOCK_RETURN_REDIRECT_METHOD] = REDIRECT_METHOD_RETURN_TO_SENDER + . |= BLOCK_SHOULD_REDIRECT + /obj/item/melee/transforming/energy/sword/cyborg sword_color = "red" light_color = "#ff0000" diff --git a/code/game/objects/items/melee/misc.dm b/code/game/objects/items/melee/misc.dm index ee24579e9a..9a7d455df6 100644 --- a/code/game/objects/items/melee/misc.dm +++ b/code/game/objects/items/melee/misc.dm @@ -375,6 +375,7 @@ var/wait_desc = get_wait_description() if(wait_desc) to_chat(user, wait_desc) + return DISCARD_LAST_ACTION /obj/item/melee/classic_baton/telescopic name = "telescopic baton" @@ -626,7 +627,7 @@ to_chat(user, "[target] doesn't seem to want to get on [src]!") update_icon() -/obj/item/melee/roastingstick/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/item/melee/roastingstick/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) ..() if (held_sausage) user.put_in_hands(held_sausage) diff --git a/code/game/objects/items/melee/transforming.dm b/code/game/objects/items/melee/transforming.dm index 386a6e9acc..66752c4c9a 100644 --- a/code/game/objects/items/melee/transforming.dm +++ b/code/game/objects/items/melee/transforming.dm @@ -84,4 +84,4 @@ /obj/item/melee/transforming/proc/clumsy_transform_effect(mob/living/user) if(clumsy_check && HAS_TRAIT(user, TRAIT_CLUMSY) && prob(50)) to_chat(user, "You accidentally cut yourself with [src], like a doofus!") - user.take_bodypart_damage(5,5) \ No newline at end of file + user.take_bodypart_damage(5,5) diff --git a/code/game/objects/items/mop.dm b/code/game/objects/items/mop.dm index 3a06c7d7fe..b420bfc002 100644 --- a/code/game/objects/items/mop.dm +++ b/code/game/objects/items/mop.dm @@ -58,7 +58,7 @@ if(T) user.visible_message("[user] cleans \the [T] with [src].", "You clean \the [T] with [src].") clean(T) - user.changeNext_move(CLICK_CD_MELEE) + user.DelayNextAction(CLICK_CD_MELEE) user.do_attack_animation(T, used_item = src) if(istype(L)) L.adjustStaminaLossBuffered(stamusage) @@ -128,4 +128,4 @@ return ..() /obj/item/mop/advanced/cyborg - insertable = FALSE \ No newline at end of file + insertable = FALSE diff --git a/code/game/objects/items/pet_carrier.dm b/code/game/objects/items/pet_carrier.dm index 4576edd2e0..c6b5a7e224 100644 --- a/code/game/objects/items/pet_carrier.dm +++ b/code/game/objects/items/pet_carrier.dm @@ -142,8 +142,6 @@ remove_occupant(user) return - user.changeNext_move(CLICK_CD_BREAKOUT) - user.last_special = world.time + CLICK_CD_BREAKOUT if(user.mob_size <= MOB_SIZE_SMALL) to_chat(user, "You begin to try escaping the [src] and start fumbling for the lock switch... (This will take some time.)") to_chat(loc, "You see [user] attempting to unlock the [src]!") diff --git a/code/game/objects/items/powerfist.dm b/code/game/objects/items/powerfist.dm index 52f4b3462e..2834b3b758 100644 --- a/code/game/objects/items/powerfist.dm +++ b/code/game/objects/items/powerfist.dm @@ -14,12 +14,11 @@ w_class = WEIGHT_CLASS_NORMAL armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 40) resistance_flags = FIRE_PROOF - click_delay = CLICK_CD_MELEE * 1.5 + attack_speed = CLICK_CD_MELEE * 1.5 var/fisto_setting = 1 var/gasperfist = 3 var/obj/item/tank/internals/tank = null //Tank used for the gauntlet's piston-ram. - /obj/item/melee/powerfist/examine(mob/user) . = ..() if(!in_range(user, src)) diff --git a/code/game/objects/items/shooting_range.dm b/code/game/objects/items/shooting_range.dm index 7fd37053b1..ced0ee3160 100644 --- a/code/game/objects/items/shooting_range.dm +++ b/code/game/objects/items/shooting_range.dm @@ -31,10 +31,7 @@ to_chat(user, "You slice off [src]'s uneven chunks of aluminium and scorch marks.") return TRUE -/obj/item/target/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) - . = ..() - if(.) - return +/obj/item/target/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(pinnedLoc) pinnedLoc.removeTarget(user) diff --git a/code/game/objects/items/signs.dm b/code/game/objects/items/signs.dm index cf7373b700..67bc28b2ea 100644 --- a/code/game/objects/items/signs.dm +++ b/code/game/objects/items/signs.dm @@ -40,4 +40,3 @@ user.visible_message("[user] waves around \the \"[label]\" sign.") else user.visible_message("[user] waves around blank sign.") - user.changeNext_move(CLICK_CD_MELEE) \ No newline at end of file diff --git a/code/game/objects/items/stacks/bscrystal.dm b/code/game/objects/items/stacks/bscrystal.dm index c142db6530..3b4be37cee 100644 --- a/code/game/objects/items/stacks/bscrystal.dm +++ b/code/game/objects/items/stacks/bscrystal.dm @@ -74,8 +74,7 @@ /obj/item/stack/sheet/bluespace_crystal/attack_self(mob/user)// to prevent the construction menu from ever happening to_chat(user, "You cannot crush the polycrystal in-hand, try breaking one off.") -//ATTACK HAND IGNORING PARENT RETURN VALUE -/obj/item/stack/sheet/bluespace_crystal/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/item/stack/sheet/bluespace_crystal/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(user.get_inactive_held_item() == src) if(zero_amount()) return diff --git a/code/game/objects/items/stacks/medical.dm b/code/game/objects/items/stacks/medical.dm index b358608ee4..1ceb525b8a 100644 --- a/code/game/objects/items/stacks/medical.dm +++ b/code/game/objects/items/stacks/medical.dm @@ -336,7 +336,7 @@ return . = ..() -/obj/item/stack/medical/mesh/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/item/stack/medical/mesh/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(!is_open & user.get_inactive_held_item() == src) to_chat(user, "You need to open [src] first.") return diff --git a/code/game/objects/items/stacks/sheets/sheet_types.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm index a73545c685..5f6341ea21 100644 --- a/code/game/objects/items/stacks/sheets/sheet_types.dm +++ b/code/game/objects/items/stacks/sheets/sheet_types.dm @@ -184,13 +184,13 @@ GLOBAL_LIST_INIT(plasteel_recipes, list ( \ new /datum/stack_recipe("trash cart", /obj/structure/closet/crate/trashcart, 5, time = 50, one_per_turf = 1, on_floor = 1), \ new /datum/stack_recipe("medical crate", /obj/structure/closet/crate/medical, 5, time = 50, one_per_turf = 1, on_floor = 1), \ new /datum/stack_recipe("freezer crate", /obj/structure/closet/crate/freezer, 8, time = 50, one_per_turf = 1, on_floor = 1), \ - new /datum/stack_recipe("blood bag crate", /obj/structure/closet/crate/freezer/blood, 8, time = 50, one_per_turf = 1, on_floor = 1), \ - new /datum/stack_recipe("surplus limbs crate", /obj/structure/closet/crate/freezer/surplus_limbs, 8, time = 50, one_per_turf = 1, on_floor = 1), \ + new /datum/stack_recipe("blood bag crate", /obj/structure/closet/crate/freezer/blood/fake, 8, time = 50, one_per_turf = 1, on_floor = 1), \ + new /datum/stack_recipe("surplus limbs crate", /obj/structure/closet/crate/freezer/surplus_limbs/fake, 8, time = 50, one_per_turf = 1, on_floor = 1), \ new /datum/stack_recipe("radiation containment crate", /obj/structure/closet/crate/radiation, 8, time = 50, one_per_turf = 1, on_floor = 1), \ new /datum/stack_recipe("hydroponics crate", /obj/structure/closet/crate/hydroponics, 5, time = 50, one_per_turf = 1, on_floor = 1), \ new /datum/stack_recipe("engineering crate", /obj/structure/closet/crate/engineering, 5, time = 50, one_per_turf = 1, on_floor = 1), \ new /datum/stack_recipe("eletrical crate", /obj/structure/closet/crate/engineering/electrical, 5, time = 50, one_per_turf = 1, on_floor = 1), \ - new /datum/stack_recipe("RCD storage crate", /obj/structure/closet/crate/rcd, 5, time = 50, one_per_turf = 1, on_floor = 1), \ + new /datum/stack_recipe("RCD storage crate", /obj/structure/closet/crate/rcd/fake, 5, time = 50, one_per_turf = 1, on_floor = 1), \ new /datum/stack_recipe("science crate", /obj/structure/closet/crate/science, 5, time = 50, one_per_turf = 1, on_floor = 1), \ )), \ new /datum/stack_recipe_list("airlock assemblies", list( \ diff --git a/code/game/objects/items/stacks/stack.dm b/code/game/objects/items/stacks/stack.dm index a80eeacaf6..3e2bb675fa 100644 --- a/code/game/objects/items/stacks/stack.dm +++ b/code/game/objects/items/stacks/stack.dm @@ -398,8 +398,7 @@ merge(AM) . = ..() -//ATTACK HAND IGNORING PARENT RETURN VALUE -/obj/item/stack/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/item/stack/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(user.get_inactive_held_item() == src) if(zero_amount()) return diff --git a/code/game/objects/items/storage/belt.dm b/code/game/objects/items/storage/belt.dm index 83ac727c9e..3c554aa58e 100755 --- a/code/game/objects/items/storage/belt.dm +++ b/code/game/objects/items/storage/belt.dm @@ -83,7 +83,7 @@ new /obj/item/multitool(src) new /obj/item/stack/cable_coil(src,30,pick("red","yellow","orange")) new /obj/item/extinguisher/mini(src) - new /obj/item/analyzer(src) + new /obj/item/analyzer/ranged(src) //much roomier now that we've managed to remove two tools /obj/item/storage/belt/utility/full/PopulateContents() @@ -120,7 +120,7 @@ new /obj/item/wrench/brass(src) new /obj/item/crowbar/brass(src) new /obj/item/weldingtool/experimental/brass(src) - new /obj/item/multitool(src) + new /obj/item/multitool/advanced/brass(src) new /obj/item/stack/cable_coil(src, 30, "yellow") /obj/item/storage/belt/medical diff --git a/code/game/objects/items/storage/book.dm b/code/game/objects/items/storage/book.dm index 5d5f0eaa24..7532aacbfa 100644 --- a/code/game/objects/items/storage/book.dm +++ b/code/game/objects/items/storage/book.dm @@ -104,7 +104,7 @@ GLOBAL_LIST_INIT(bibleitemstates, list("bible", "koran", "scrapbook", "bible", SEND_SIGNAL(H, COMSIG_ADD_MOOD_EVENT, "blessing", /datum/mood_event/blessing) return 1 -/obj/item/storage/book/bible/attack(mob/living/M, mob/living/carbon/human/user, heal_mode = TRUE) +/obj/item/storage/book/bible/attack(mob/living/M, mob/living/user, attackchain_flags = NONE, damage_multiplier = 1, heal_mode = TRUE) if (!user.IsAdvancedToolUser()) to_chat(user, "You don't have the dexterity to do this!") @@ -238,11 +238,10 @@ GLOBAL_LIST_INIT(bibleitemstates, list("bible", "koran", "scrapbook", "bible", var/ownername = H.real_name desc += "The name [ownername] is written in blood inside the cover." -/obj/item/storage/book/bible/syndicate/attack(mob/living/M, mob/living/carbon/human/user, heal_mode = TRUE) - if (user.a_intent == INTENT_HELP) - return ..() - else - return ..(M,user,heal_mode = FALSE) +/obj/item/storage/book/bible/syndicate/attack(mob/living/M, mob/living/user, attackchain_flags = NONE, damage_multiplier = 1, heal_mode = TRUE) + if(user.a_intent != INTENT_HELP) + heal_mode = FALSE //args pass over + return ..() // to ..() /obj/item/storage/book/bible/syndicate/add_blood_DNA(list/blood_dna) return FALSE diff --git a/code/game/objects/items/storage/boxes.dm b/code/game/objects/items/storage/boxes.dm index 02ae867240..975621ead1 100644 --- a/code/game/objects/items/storage/boxes.dm +++ b/code/game/objects/items/storage/boxes.dm @@ -726,9 +726,9 @@ obj/item/storage/box/stingbangs return (BRUTELOSS) /obj/item/storage/box/hug/attack_self(mob/user) - ..() - user.changeNext_move(CLICK_CD_MELEE) - playsound(loc, "rustle", 50, 1, -5) + . = ..() + user.DelayNextAction(CLICK_CD_MELEE) + playsound(src, "rustle", 50, 1, -5) user.visible_message("[user] hugs \the [src].","You hug \the [src].") SEND_SIGNAL(user, COMSIG_ADD_MOOD_EVENT,"hugbox", /datum/mood_event/hugbox) @@ -1423,4 +1423,4 @@ obj/item/storage/box/stingbangs /obj/item/storage/box/strange_seeds_5pack/PopulateContents() for(var/i in 1 to 5) - new /obj/item/seeds/random(src) \ No newline at end of file + new /obj/item/seeds/random(src) diff --git a/code/game/objects/items/storage/dakis.dm b/code/game/objects/items/storage/dakis.dm index 1939593c8e..29f12df4c4 100644 --- a/code/game/objects/items/storage/dakis.dm +++ b/code/game/objects/items/storage/dakis.dm @@ -47,6 +47,6 @@ if(INTENT_HARM) user.visible_message("[user] punches the [name]!") playsound(src, 'sound/effects/shieldbash.ogg', 50, 1) - user.changeNext_move(CLICK_CD_MELEE) + user.DelayNextAction(CLICK_CD_MELEE) //////////////////////////// diff --git a/code/game/objects/items/storage/secure.dm b/code/game/objects/items/storage/secure.dm index 6061feb893..4e6a0b3463 100644 --- a/code/game/objects/items/storage/secure.dm +++ b/code/game/objects/items/storage/secure.dm @@ -205,10 +205,7 @@ new /obj/item/paper(src) new /obj/item/pen(src) -/obj/item/storage/secure/safe/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) - . = ..() - if(.) - return +/obj/item/storage/secure/safe/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) return attack_self(user) /obj/item/storage/secure/safe/HoS diff --git a/code/game/objects/items/stunbaton.dm b/code/game/objects/items/stunbaton.dm index fa0c9ba693..1a84b85a1a 100644 --- a/code/game/objects/items/stunbaton.dm +++ b/code/game/objects/items/stunbaton.dm @@ -14,6 +14,7 @@ w_class = WEIGHT_CLASS_NORMAL attack_verb = list("beaten") armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 50, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 80) + attack_speed = CLICK_CD_MELEE var/stamforce = 35 var/turned_on = FALSE @@ -144,8 +145,9 @@ return ..() /obj/item/melee/baton/alt_pre_attack(atom/A, mob/living/user, params) + if(!user.CheckActionCooldown(CLICK_CD_MELEE)) + return . = common_baton_melee(A, user, TRUE) //return true (attackchain interrupt) if this also returns true. no harm-disarming. - user.changeNext_move(CLICK_CD_MELEE) //return TRUE to interrupt attack chain. /obj/item/melee/baton/proc/common_baton_melee(mob/M, mob/living/user, disarming = FALSE) @@ -156,6 +158,7 @@ if(IS_STAMCRIT(user)) //CIT CHANGE - makes it impossible to baton in stamina softcrit to_chat(user, "You're too exhausted to use [src] properly.") return TRUE + user.DelayNextAction() if(ishuman(M)) var/mob/living/carbon/human/L = M if(check_martial_counter(L, user)) diff --git a/code/game/objects/items/tanks/tanks.dm b/code/game/objects/items/tanks/tanks.dm index 42e25273a2..2de5860794 100644 --- a/code/game/objects/items/tanks/tanks.dm +++ b/code/game/objects/items/tanks/tanks.dm @@ -123,6 +123,7 @@ /obj/item/tank/analyzer_act(mob/living/user, obj/item/I) atmosanalyzer_scan(air_contents, user, src) + return TRUE /obj/item/tank/deconstruct(disassembled = TRUE) if(!disassembled) diff --git a/code/game/objects/items/tanks/watertank.dm b/code/game/objects/items/tanks/watertank.dm index 0a7eefb786..16a91b6358 100644 --- a/code/game/objects/items/tanks/watertank.dm +++ b/code/game/objects/items/tanks/watertank.dm @@ -72,7 +72,7 @@ QDEL_NULL(noz) return ..() -/obj/item/watertank/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/item/watertank/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if (user.get_item_by_slot(user.getBackSlot()) == src) toggle_mister(user) else diff --git a/code/game/objects/items/tools/crowbar.dm b/code/game/objects/items/tools/crowbar.dm index 91e8c49e5a..d39da2f543 100644 --- a/code/game/objects/items/tools/crowbar.dm +++ b/code/game/objects/items/tools/crowbar.dm @@ -90,6 +90,7 @@ /obj/item/crowbar/power/attack_self(mob/user) playsound(get_turf(user), 'sound/items/change_jaws.ogg', 50, 1) var/obj/item/wirecutters/power/cutjaws = new /obj/item/wirecutters/power(drop_location()) + cutjaws.name = name to_chat(user, "You attach the cutting jaws to [src].") qdel(src) user.put_in_active_hand(cutjaws) diff --git a/code/game/objects/items/tools/wirecutters.dm b/code/game/objects/items/tools/wirecutters.dm index ac5a02b9fc..53a578a45d 100644 --- a/code/game/objects/items/tools/wirecutters.dm +++ b/code/game/objects/items/tools/wirecutters.dm @@ -117,6 +117,7 @@ /obj/item/wirecutters/power/attack_self(mob/user) playsound(get_turf(user), 'sound/items/change_jaws.ogg', 50, 1) var/obj/item/crowbar/power/pryjaws = new /obj/item/crowbar/power(drop_location()) + pryjaws.name = name to_chat(user, "You attach the pry jaws to [src].") qdel(src) user.put_in_active_hand(pryjaws) diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm index fe2e0df2eb..58b282be7d 100644 --- a/code/game/objects/items/toys.dm +++ b/code/game/objects/items/toys.dm @@ -574,10 +574,7 @@ else . = ..() -/obj/item/toy/prize/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) - . = ..() - if(.) - return +/obj/item/toy/prize/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(loc == user) attack_self(user) @@ -811,9 +808,8 @@ cards += "Ace of Clubs" cards += "Ace of Diamonds" -//ATTACK HAND IGNORING PARENT RETURN VALUE //ATTACK HAND NOT CALLING PARENT -/obj/item/toy/cards/deck/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/item/toy/cards/deck/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) draw_card(user) /obj/item/toy/cards/deck/proc/draw_card(mob/user) @@ -1234,7 +1230,7 @@ name = "steampunk watch" desc = "A stylish steampunk watch made out of thousands of tiny cogwheels." icon = 'icons/obj/clockwork_objects.dmi' - icon_state = "dread_ipad" + icon_state = "clockwork_slab" slot_flags = ITEM_SLOT_BELT w_class = WEIGHT_CLASS_SMALL var/cooldown = 0 diff --git a/code/game/objects/items/weaponry.dm b/code/game/objects/items/weaponry.dm index f94140db3c..e21c4aaffa 100644 --- a/code/game/objects/items/weaponry.dm +++ b/code/game/objects/items/weaponry.dm @@ -286,6 +286,9 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 parry_efficiency_to_counterattack = 100 parry_efficiency_considered_successful = 65 // VERY generous parry_efficiency_perfect = 120 + parry_efficiency_perfect_override = list( + TEXT_ATTACK_TYPE_PROJECTILE = 30, + ) parry_failed_stagger_duration = 3 SECONDS parry_data = list(PARRY_COUNTERATTACK_MELEE_ATTACK_CHAIN = 2.5) // 7*2.5 = 17.5, 8*2.5 = 20, 9*2.5 = 22.5, 10*2.5 = 25 diff --git a/code/game/objects/obj_defense.dm b/code/game/objects/obj_defense.dm index 1203c5a1df..14017ffb2d 100644 --- a/code/game/objects/obj_defense.dm +++ b/code/game/objects/obj_defense.dm @@ -105,15 +105,19 @@ /obj/proc/attack_generic(mob/user, damage_amount = 0, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, armor_penetration = 0) //used by attack_alien, attack_animal, and attack_slime if(SEND_SIGNAL(src, COMSIG_OBJ_ATTACK_GENERIC, user, damage_amount, damage_type, damage_flag, sound_effect, armor_penetration) & COMPONENT_STOP_GENERIC_ATTACK) return FALSE + if(!user.CheckActionCooldown(CLICK_CD_MELEE)) + return user.do_attack_animation(src) - user.changeNext_move(CLICK_CD_MELEE) - return take_damage(damage_amount, damage_type, damage_flag, sound_effect, get_dir(src, user), armor_penetration) + . = take_damage(damage_amount, damage_type, damage_flag, sound_effect, get_dir(src, user), armor_penetration) + user.DelayNextAction() /obj/attack_alien(mob/living/carbon/alien/humanoid/user) if(attack_generic(user, 60, BRUTE, "melee", 0)) playsound(src.loc, 'sound/weapons/slash.ogg', 100, 1) /obj/attack_animal(mob/living/simple_animal/M) + if(!M.CheckActionCooldown(CLICK_CD_MELEE)) + return if(!M.melee_damage_upper && !M.obj_damage) M.emote("custom", message = "[M.friendly_verb_continuous] [src].") return 0 diff --git a/code/game/objects/structures.dm b/code/game/objects/structures.dm index cce4955210..39f2d276a1 100644 --- a/code/game/objects/structures.dm +++ b/code/game/objects/structures.dm @@ -28,12 +28,10 @@ queue_smooth_neighbors(src) return ..() -/obj/structure/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/structure/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() - if(.) - return if(structureclimber && structureclimber != user) - user.changeNext_move(CLICK_CD_MELEE) + user.DelayNextAction(CLICK_CD_MELEE) user.do_attack_animation(src) structureclimber.DefaultCombatKnockdown(40) structureclimber.visible_message("[structureclimber] has been knocked off [src].", "You're knocked off [src]!", "You see [structureclimber] get knocked off [src].") diff --git a/code/game/objects/structures/aliens.dm b/code/game/objects/structures/aliens.dm index a6cd8df746..ce11daec54 100644 --- a/code/game/objects/structures/aliens.dm +++ b/code/game/objects/structures/aliens.dm @@ -249,7 +249,7 @@ /obj/structure/alien/egg/attack_alien(mob/living/carbon/alien/user) return attack_hand(user) -/obj/structure/alien/egg/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/structure/alien/egg/on_attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return @@ -269,8 +269,7 @@ return else to_chat(user, "It feels slimy.") - user.changeNext_move(CLICK_CD_MELEE) - + user.DelayNextAction(CLICK_CD_MELEE) /obj/structure/alien/egg/proc/Grow() status = GROWN diff --git a/code/game/objects/structures/barsigns.dm b/code/game/objects/structures/barsigns.dm index 7ea678cae4..905888c904 100644 --- a/code/game/objects/structures/barsigns.dm +++ b/code/game/objects/structures/barsigns.dm @@ -52,10 +52,7 @@ /obj/structure/sign/barsign/attack_ai(mob/user) return attack_hand(user) -/obj/structure/sign/barsign/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) - . = ..() - if(.) - return +/obj/structure/sign/barsign/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(!allowed(user)) to_chat(user, "Access denied.") return diff --git a/code/game/objects/structures/bedsheet_bin.dm b/code/game/objects/structures/bedsheet_bin.dm index e45ddf650c..45cac650b8 100644 --- a/code/game/objects/structures/bedsheet_bin.dm +++ b/code/game/objects/structures/bedsheet_bin.dm @@ -311,10 +311,7 @@ LINEN BINS /obj/structure/bedsheetbin/attack_paw(mob/user) return attack_hand(user) -/obj/structure/bedsheetbin/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) - . = ..() - if(.) - return +/obj/structure/bedsheetbin/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(user.incapacitated()) return if(amount >= 1) diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm index 4b9251d8ec..043232e9e3 100644 --- a/code/game/objects/structures/crates_lockers/closets.dm +++ b/code/game/objects/structures/crates_lockers/closets.dm @@ -37,12 +37,13 @@ var/lock_in_use = FALSE //Someone is doing some stuff with the lock here, better not proceed further var/eigen_teleport = FALSE //If the closet leads to Mr Tumnus. var/obj/structure/closet/eigen_target //Where you go to. - + var/should_populate_contents = TRUE /obj/structure/closet/Initialize(mapload) . = ..() update_icon() - PopulateContents() + if(should_populate_contents) + PopulateContents() if(mapload && !opened) // if closed, any item at the crate's loc is put in the contents addtimer(CALLBACK(src, .proc/take_contents), 0) if(secure) @@ -458,10 +459,7 @@ return container_resist(user) -/obj/structure/closet/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) - . = ..() - if(.) - return +/obj/structure/closet/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(user.lying && get_dist(src, user) > 0) return @@ -506,8 +504,6 @@ if(opened) return if(ismovable(loc)) - user.changeNext_move(CLICK_CD_BREAKOUT) - user.last_special = world.time + CLICK_CD_BREAKOUT var/atom/movable/AM = loc AM.relay_container_resist(user, src) return @@ -516,8 +512,6 @@ return //okay, so the closet is either welded or locked... resist!!! - user.changeNext_move(CLICK_CD_BREAKOUT) - user.last_special = world.time + CLICK_CD_BREAKOUT user.visible_message("[src] begins to shake violently!", \ "You lean on the back of [src] and start pushing the door open... (this will take about [DisplayTimeText(breakout_time)].)", \ "You hear banging from [src].") diff --git a/code/game/objects/structures/crates_lockers/closets/genpop.dm b/code/game/objects/structures/crates_lockers/closets/genpop.dm index 04c2f37b0f..7be12a4819 100644 --- a/code/game/objects/structures/crates_lockers/closets/genpop.dm +++ b/code/game/objects/structures/crates_lockers/closets/genpop.dm @@ -91,7 +91,7 @@ locked = TRUE return ..() -/obj/structure/closet/secure_closet/genpop/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/structure/closet/secure_closet/genpop/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(user.lying && get_dist(src, user) > 0) return diff --git a/code/game/objects/structures/crates_lockers/crates.dm b/code/game/objects/structures/crates_lockers/crates.dm index 99bce305f8..ee202f9504 100644 --- a/code/game/objects/structures/crates_lockers/crates.dm +++ b/code/game/objects/structures/crates_lockers/crates.dm @@ -41,10 +41,8 @@ if(manifest) . += "manifest" -/obj/structure/closet/crate/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/structure/closet/crate/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() - if(.) - return if(manifest) tear_manifest(user) @@ -144,6 +142,9 @@ desc = "A freezer containing packs of blood." icon_state = "surgery" +/obj/structure/closet/crate/freezer/blood/fake + should_populate_contents = FALSE + /obj/structure/closet/crate/freezer/blood/PopulateContents() . = ..() new /obj/item/reagent_containers/blood(src) @@ -164,6 +165,9 @@ name = "surplus prosthetic limbs" desc = "A crate containing an assortment of cheap prosthetic limbs." +/obj/structure/closet/crate/freezer/surplus_limbs/fake + should_populate_contents = FALSE + /obj/structure/closet/crate/freezer/surplus_limbs/PopulateContents() . = ..() new /obj/item/bodypart/l_arm/robot/surplus(src) @@ -198,6 +202,9 @@ name = "\improper RCD crate" icon_state = "engi_crate" +/obj/structure/closet/crate/rcd/fake + should_populate_contents = FALSE + /obj/structure/closet/crate/rcd/PopulateContents() ..() for(var/i in 1 to 4) diff --git a/code/game/objects/structures/crates_lockers/crates/large.dm b/code/game/objects/structures/crates_lockers/crates/large.dm index d8c2f7f91c..3cee96e435 100644 --- a/code/game/objects/structures/crates_lockers/crates/large.dm +++ b/code/game/objects/structures/crates_lockers/crates/large.dm @@ -8,7 +8,7 @@ delivery_icon = "deliverybox" integrity_failure = 0 //Makes the crate break when integrity reaches 0, instead of opening and becoming an invisible sprite. -/obj/structure/closet/crate/large/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/structure/closet/crate/large/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) add_fingerprint(user) if(manifest) tear_manifest(user) diff --git a/code/game/objects/structures/displaycase.dm b/code/game/objects/structures/displaycase.dm index 4db889b392..f0384ca96a 100644 --- a/code/game/objects/structures/displaycase.dm +++ b/code/game/objects/structures/displaycase.dm @@ -9,6 +9,8 @@ armor = list("melee" = 30, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 10, "bio" = 0, "rad" = 0, "fire" = 70, "acid" = 100) max_integrity = 200 integrity_failure = 0.25 + attack_hand_speed = CLICK_CD_MELEE + attack_hand_is_action = TRUE var/obj/item/showpiece = null var/alert = TRUE var/open = FALSE @@ -157,11 +159,7 @@ /obj/structure/displaycase/attack_paw(mob/user) return attack_hand(user) -/obj/structure/displaycase/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) - . = ..() - if(.) - return - user.changeNext_move(CLICK_CD_MELEE) +/obj/structure/displaycase/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if (showpiece && (broken || open)) to_chat(user, "You deactivate the hover field built into the case.") log_combat(user, src, "deactivates the hover field of") diff --git a/code/game/objects/structures/divine.dm b/code/game/objects/structures/divine.dm index 5afe97f669..f64397df09 100644 --- a/code/game/objects/structures/divine.dm +++ b/code/game/objects/structures/divine.dm @@ -7,7 +7,7 @@ density = FALSE can_buckle = 1 -/obj/structure/sacrificealtar/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/structure/sacrificealtar/on_attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return @@ -30,7 +30,7 @@ var/time_between_uses = 1800 var/last_process = 0 -/obj/structure/healingfountain/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/structure/healingfountain/on_attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/game/objects/structures/dresser.dm b/code/game/objects/structures/dresser.dm index 9279bf1d73..7fdec9b3d9 100644 --- a/code/game/objects/structures/dresser.dm +++ b/code/game/objects/structures/dresser.dm @@ -19,7 +19,7 @@ new /obj/item/stack/sheet/mineral/wood(drop_location(), 10) qdel(src) -/obj/structure/dresser/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/structure/dresser/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(. || !ishuman(user) || !user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK)) return diff --git a/code/game/objects/structures/extinguisher.dm b/code/game/objects/structures/extinguisher.dm index a279070e69..84926ccfb0 100644 --- a/code/game/objects/structures/extinguisher.dm +++ b/code/game/objects/structures/extinguisher.dm @@ -69,10 +69,7 @@ return ..() -/obj/structure/extinguisher_cabinet/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) - . = ..() - if(.) - return +/obj/structure/extinguisher_cabinet/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(iscyborg(user) || isalien(user)) return if(stored_extinguisher) diff --git a/code/game/objects/structures/false_walls.dm b/code/game/objects/structures/false_walls.dm index eaa6e574cd..b654f4f5c0 100644 --- a/code/game/objects/structures/false_walls.dm +++ b/code/game/objects/structures/false_walls.dm @@ -41,7 +41,7 @@ new /obj/structure/falsewall/brass(loc) qdel(src) -/obj/structure/falsewall/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/structure/falsewall/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(opening) return . = ..() @@ -180,7 +180,7 @@ radiate() return ..() -/obj/structure/falsewall/uranium/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/structure/falsewall/uranium/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) radiate() . = ..() diff --git a/code/game/objects/structures/femur_breaker.dm b/code/game/objects/structures/femur_breaker.dm index 1fa21d119e..2ac56ec4fb 100644 --- a/code/game/objects/structures/femur_breaker.dm +++ b/code/game/objects/structures/femur_breaker.dm @@ -32,7 +32,7 @@ if (LAZYLEN(buckled_mobs)) . += "Someone appears to be strapped in. You can help them unbuckle, or activate the femur breaker." -/obj/structure/femur_breaker/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/structure/femur_breaker/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) add_fingerprint(user) // Currently being used diff --git a/code/game/objects/structures/fence.dm b/code/game/objects/structures/fence.dm index 5803fb1306..f90161f587 100644 --- a/code/game/objects/structures/fence.dm +++ b/code/game/objects/structures/fence.dm @@ -120,7 +120,7 @@ open = TRUE density = TRUE -/obj/structure/fence/door/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/structure/fence/door/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(can_open(user)) toggle(user) diff --git a/code/game/objects/structures/fireaxe.dm b/code/game/objects/structures/fireaxe.dm index de88372b1e..412730910f 100644 --- a/code/game/objects/structures/fireaxe.dm +++ b/code/game/objects/structures/fireaxe.dm @@ -105,10 +105,7 @@ fireaxe = null qdel(src) -/obj/structure/fireaxecabinet/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) - . = ..() - if(.) - return +/obj/structure/fireaxecabinet/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(open || broken) if(fireaxe) user.put_in_hands(fireaxe) diff --git a/code/game/objects/structures/flora.dm b/code/game/objects/structures/flora.dm index 6d72bb58b2..b587e57c3a 100644 --- a/code/game/objects/structures/flora.dm +++ b/code/game/objects/structures/flora.dm @@ -65,7 +65,7 @@ var/gift_type = /obj/item/a_gift/anything var/list/ckeys_that_took = list() -/obj/structure/flora/tree/pine/xmas/presents/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/structure/flora/tree/pine/xmas/presents/on_attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/game/objects/structures/fluff.dm b/code/game/objects/structures/fluff.dm index 1dcda6eb50..bd7ddb36d5 100644 --- a/code/game/objects/structures/fluff.dm +++ b/code/game/objects/structures/fluff.dm @@ -110,7 +110,7 @@ desc = "Space Jesus is my copilot." icon_state = "driverseat" -/obj/structure/fluff/bus/passable/seat/driver/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/structure/fluff/bus/passable/seat/driver/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) playsound(src, 'sound/items/carhorn.ogg', 50, 1) . = ..() diff --git a/code/game/objects/structures/ghost_role_spawners.dm b/code/game/objects/structures/ghost_role_spawners.dm index 03bcdde57c..4d500837d9 100644 --- a/code/game/objects/structures/ghost_role_spawners.dm +++ b/code/game/objects/structures/ghost_role_spawners.dm @@ -186,10 +186,7 @@ else new_spawn.mind.assigned_role = "Free Golem" -/obj/effect/mob_spawn/human/golem/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) - . = ..() - if(.) - return +/obj/effect/mob_spawn/human/golem/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(isgolem(user) && can_transfer) var/transfer_choice = alert("Transfer your soul to [src]? (Warning, your old body will die!)",,"Yes","No") if(transfer_choice != "Yes" || QDELETED(src) || uses <= 0 || !user.canUseTopic(src, BE_CLOSE, NO_DEXTERY, NO_TK)) diff --git a/code/game/objects/structures/grille.dm b/code/game/objects/structures/grille.dm index efd1b486d0..36e4f825da 100644 --- a/code/game/objects/structures/grille.dm +++ b/code/game/objects/structures/grille.dm @@ -10,6 +10,8 @@ layer = BELOW_OBJ_LAYER armor = list("melee" = 50, "bullet" = 70, "laser" = 70, "energy" = 100, "bomb" = 10, "bio" = 100, "rad" = 100, "fire" = 0, "acid" = 0) max_integrity = 50 + attack_hand_is_action = TRUE + attack_hand_speed = 8 integrity_failure = 0.4 var/rods_type = /obj/item/stack/rods var/rods_amount = 2 @@ -99,11 +101,10 @@ ..(user, 1) return TRUE -/obj/structure/grille/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/structure/grille/on_attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return - user.changeNext_move(CLICK_CD_MELEE) user.do_attack_animation(src, ATTACK_EFFECT_KICK) user.visible_message("[user] hits [src].", null, null, COMBAT_MESSAGE_RANGE) log_combat(user, src, "hit") @@ -111,8 +112,9 @@ take_damage(rand(5,10), BRUTE, "melee", 1) /obj/structure/grille/attack_alien(mob/living/user) + if(!user.CheckActionCooldown(CLICK_CD_MELEE)) + return user.do_attack_animation(src) - user.changeNext_move(CLICK_CD_MELEE) user.visible_message("[user] mangles [src].", null, null, COMBAT_MESSAGE_RANGE) if(!shock(user, 70)) take_damage(20, BRUTE, "melee", 1) @@ -134,7 +136,7 @@ . = . || (mover.pass_flags & PASSGRILLE) /obj/structure/grille/attackby(obj/item/W, mob/user, params) - user.changeNext_move(CLICK_CD_MELEE) + user.DelayNextAction(CLICK_CD_MELEE) add_fingerprint(user) if(istype(W, /obj/item/wirecutters)) if(!shock(user, 100)) diff --git a/code/game/objects/structures/guillotine.dm b/code/game/objects/structures/guillotine.dm index acec52a583..4773c07657 100644 --- a/code/game/objects/structures/guillotine.dm +++ b/code/game/objects/structures/guillotine.dm @@ -51,7 +51,7 @@ if (LAZYLEN(buckled_mobs)) . += "Someone appears to be strapped in. You can help them out, or you can harm them by activating the guillotine." -/obj/structure/guillotine/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/structure/guillotine/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) add_fingerprint(user) // Currently being used by something diff --git a/code/game/objects/structures/guncase.dm b/code/game/objects/structures/guncase.dm index 1cab600fb1..e7ff9d4abf 100644 --- a/code/game/objects/structures/guncase.dm +++ b/code/game/objects/structures/guncase.dm @@ -53,10 +53,7 @@ else return ..() -/obj/structure/guncase/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) - . = ..() - if(.) - return +/obj/structure/guncase/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(iscyborg(user) || isalien(user)) return if(contents.len && open) diff --git a/code/game/objects/structures/headpike.dm b/code/game/objects/structures/headpike.dm index 7a67387a8e..6aed11701d 100644 --- a/code/game/objects/structures/headpike.dm +++ b/code/game/objects/structures/headpike.dm @@ -37,10 +37,7 @@ MA.pixel_y = 12 . += H -/obj/structure/headpike/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) - . = ..() - if(.) - return +/obj/structure/headpike/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) to_chat(user, "You take down [src].") if(victim) victim.forceMove(drop_location()) diff --git a/code/game/objects/structures/holosign.dm b/code/game/objects/structures/holosign.dm index 844c2ff8fd..dc5355e9d8 100644 --- a/code/game/objects/structures/holosign.dm +++ b/code/game/objects/structures/holosign.dm @@ -25,12 +25,12 @@ projector = null return ..() -/obj/structure/holosign/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/structure/holosign/on_attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return user.do_attack_animation(src, ATTACK_EFFECT_PUNCH) - user.changeNext_move(CLICK_CD_MELEE) + user.DelayNextAction(CLICK_CD_MELEE) take_damage(5 , BRUTE, "melee", 1) /obj/structure/holosign/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0) @@ -162,7 +162,7 @@ return TRUE //nice or benign diseases! return TRUE -/obj/structure/holosign/barrier/medical/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/structure/holosign/barrier/medical/on_attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) if(CanPass(user) && user.a_intent == INTENT_HELP) force_allaccess = !force_allaccess to_chat(user, "You [force_allaccess ? "deactivate" : "activate"] the biometric scanners.") //warning spans because you can make the station sick! @@ -182,7 +182,7 @@ /obj/structure/holosign/barrier/cyborg/hacked/proc/cooldown() shockcd = FALSE -/obj/structure/holosign/barrier/cyborg/hacked/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/structure/holosign/barrier/cyborg/hacked/on_attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/game/objects/structures/janicart.dm b/code/game/objects/structures/janicart.dm index 72487ddc16..10a9f2afd4 100644 --- a/code/game/objects/structures/janicart.dm +++ b/code/game/objects/structures/janicart.dm @@ -91,10 +91,7 @@ else return ..() -/obj/structure/janitorialcart/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) - . = ..() - if(.) - return +/obj/structure/janitorialcart/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) var/list/items = list() if(mybag) diff --git a/code/game/objects/structures/kitchen_spike.dm b/code/game/objects/structures/kitchen_spike.dm index 5706f79192..a23dd3a21e 100644 --- a/code/game/objects/structures/kitchen_spike.dm +++ b/code/game/objects/structures/kitchen_spike.dm @@ -60,8 +60,7 @@ deconstruct(TRUE) return TRUE -//ATTACK HAND IGNORING PARENT RETURN VALUE -/obj/structure/kitchenspike/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/structure/kitchenspike/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(VIABLE_MOB_CHECK(user.pulling) && user.a_intent == INTENT_GRAB && !has_buckled_mobs()) var/mob/living/L = user.pulling if(HAS_TRAIT(user, TRAIT_PACIFISM) && L.stat != DEAD) diff --git a/code/game/objects/structures/ladders.dm b/code/game/objects/structures/ladders.dm index 6037183cc9..e844461952 100644 --- a/code/game/objects/structures/ladders.dm +++ b/code/game/objects/structures/ladders.dm @@ -122,10 +122,7 @@ return FALSE return TRUE -/obj/structure/ladder/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) - . = ..() - if(.) - return +/obj/structure/ladder/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) use(user) /obj/structure/ladder/attack_paw(mob/user) diff --git a/code/game/objects/structures/life_candle.dm b/code/game/objects/structures/life_candle.dm index 5dc0bcdab5..52986a44d7 100644 --- a/code/game/objects/structures/life_candle.dm +++ b/code/game/objects/structures/life_candle.dm @@ -24,10 +24,7 @@ var/respawn_time = 50 var/respawn_sound = 'sound/magic/staff_animation.ogg' -/obj/structure/life_candle/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) - . = ..() - if(.) - return +/obj/structure/life_candle/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(!user.mind) return if(user.mind in linked_minds) diff --git a/code/game/objects/structures/manned_turret.dm b/code/game/objects/structures/manned_turret.dm index 79489e4ae6..e8fbafa42b 100644 --- a/code/game/objects/structures/manned_turret.dm +++ b/code/game/objects/structures/manned_turret.dm @@ -198,10 +198,6 @@ /obj/item/gun_control/CanItemAutoclick() return TRUE -/obj/item/gun_control/attack_obj(obj/O, mob/living/user) - user.changeNext_move(CLICK_CD_MELEE) - O.attacked_by(src, user) - /obj/item/gun_control/attack(mob/living/M, mob/living/user) M.lastattacker = user.real_name M.lastattackerckey = user.ckey diff --git a/code/game/objects/structures/mineral_doors.dm b/code/game/objects/structures/mineral_doors.dm index cca41b4e11..b2f1de8750 100644 --- a/code/game/objects/structures/mineral_doors.dm +++ b/code/game/objects/structures/mineral_doors.dm @@ -50,10 +50,7 @@ /obj/structure/mineral_door/attack_paw(mob/user) return attack_hand(user) -/obj/structure/mineral_door/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) - . = ..() - if(.) - return +/obj/structure/mineral_door/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) return TryToSwitchState(user) /obj/structure/mineral_door/CanPass(atom/movable/mover, turf/target) diff --git a/code/game/objects/structures/mirror.dm b/code/game/objects/structures/mirror.dm index b1829054ce..237cfdbf0b 100644 --- a/code/game/objects/structures/mirror.dm +++ b/code/game/objects/structures/mirror.dm @@ -15,10 +15,7 @@ if(icon_state == "mirror_broke" && !broken) obj_break(null, mapload) -/obj/structure/mirror/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) - . = ..() - if(.) - return +/obj/structure/mirror/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(broken || !Adjacent(user)) return @@ -118,10 +115,7 @@ choosable_races += S.id ..() -/obj/structure/mirror/magic/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) - . = ..() - if(.) - return +/obj/structure/mirror/magic/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(!ishuman(user)) return diff --git a/code/game/objects/structures/morgue.dm b/code/game/objects/structures/morgue.dm index 40753dde54..82ca59161c 100644 --- a/code/game/objects/structures/morgue.dm +++ b/code/game/objects/structures/morgue.dm @@ -61,10 +61,7 @@ GLOBAL_LIST_EMPTY(bodycontainers) //Let them act as spawnpoints for revenants an /obj/structure/bodycontainer/attack_paw(mob/user) return attack_hand(user) -/obj/structure/bodycontainer/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) - . = ..() - if(.) - return +/obj/structure/bodycontainer/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(locked) to_chat(user, "It's locked.") return @@ -109,8 +106,6 @@ GLOBAL_LIST_EMPTY(bodycontainers) //Let them act as spawnpoints for revenants an if(!locked) open() return - user.changeNext_move(CLICK_CD_BREAKOUT) - user.last_special = world.time + CLICK_CD_BREAKOUT user.visible_message(null, \ "You lean on the back of [src] and start pushing the tray open... (this will take about [DisplayTimeText(breakout_time)].)", \ "You hear a metallic creaking from [src].") @@ -322,10 +317,7 @@ GLOBAL_LIST_EMPTY(crematoriums) /obj/structure/tray/attack_paw(mob/user) return attack_hand(user) -/obj/structure/tray/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) - . = ..() - if(.) - return +/obj/structure/tray/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if (src.connected) connected.close() add_fingerprint(user) diff --git a/code/game/objects/structures/spirit_board.dm b/code/game/objects/structures/spirit_board.dm index 3a415b84a9..1b3093e4e7 100644 --- a/code/game/objects/structures/spirit_board.dm +++ b/code/game/objects/structures/spirit_board.dm @@ -14,10 +14,7 @@ desc = "[initial(desc)] The planchette is sitting at \"[planchette]\"." return ..() -/obj/structure/spirit_board/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) - . = ..() - if(.) - return +/obj/structure/spirit_board/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) spirit_board_pick_letter(user) diff --git a/code/game/objects/structures/statues.dm b/code/game/objects/structures/statues.dm index 1d7ba1d993..f8b54d04b6 100644 --- a/code/game/objects/structures/statues.dm +++ b/code/game/objects/structures/statues.dm @@ -74,7 +74,7 @@ radiate() ..() -/obj/structure/statue/uranium/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/structure/statue/uranium/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) radiate() . = ..() @@ -240,7 +240,7 @@ honk() return ..() -/obj/structure/statue/bananium/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/structure/statue/bananium/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) honk() . = ..() diff --git a/code/game/objects/structures/tables_racks.dm b/code/game/objects/structures/tables_racks.dm index 1b7eb25bb8..a553e63b0f 100644 --- a/code/game/objects/structures/tables_racks.dm +++ b/code/game/objects/structures/tables_racks.dm @@ -23,6 +23,8 @@ climbable = TRUE obj_flags = CAN_BE_HIT|SHOVABLE_ONTO pass_flags = LETPASSTHROW //You can throw objects over this, despite it's density.") + attack_hand_speed = CLICK_CD_MELEE + attack_hand_is_action = TRUE var/frame = /obj/structure/table_frame var/framestack = /obj/item/stack/rods var/buildstack = /obj/item/stack/sheet/metal @@ -60,7 +62,7 @@ /obj/structure/table/attack_paw(mob/user) return attack_hand(user) -/obj/structure/table/attack_hand(mob/living/user) +/obj/structure/table/on_attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) if(Adjacent(user) && user.pulling) if(isliving(user.pulling)) var/mob/living/pushed_mob = user.pulling @@ -210,8 +212,10 @@ return /obj/structure/table/alt_attack_hand(mob/user) + if(!user.CheckActionCooldown(CLICK_CD_MELEE)) + return + user.DelayNextAction() if(user && Adjacent(user) && !user.incapacitated()) - user.changeNext_move(CLICK_CD_MELEE*0.5) if(istype(user) && user.a_intent == INTENT_HARM) user.visible_message("[user] slams [user.p_their()] palms down on [src].", "You slam your palms down on [src].") playsound(src, 'sound/weapons/sonic_jackhammer.ogg', 50, 1) @@ -654,6 +658,8 @@ anchored = TRUE pass_flags = LETPASSTHROW //You can throw objects over this, despite it's density. max_integrity = 20 + attack_hand_speed = CLICK_CD_MELEE + attack_hand_is_action = TRUE /obj/structure/rack/examine(mob/user) . = ..() @@ -695,13 +701,12 @@ /obj/structure/rack/attack_paw(mob/living/user) attack_hand(user) -/obj/structure/rack/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/structure/rack/on_attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return if(CHECK_MULTIPLE_BITFIELDS(user.mobility_flags, MOBILITY_STAND|MOBILITY_MOVE) || user.get_num_legs() < 2) return - user.changeNext_move(CLICK_CD_MELEE) user.do_attack_animation(src, ATTACK_EFFECT_KICK) user.visible_message("[user] kicks [src].", null, null, COMBAT_MESSAGE_RANGE) take_damage(rand(4,8), BRUTE, "melee", 1) diff --git a/code/game/objects/structures/target_stake.dm b/code/game/objects/structures/target_stake.dm index a08d5c95c1..c5f3a089f7 100644 --- a/code/game/objects/structures/target_stake.dm +++ b/code/game/objects/structures/target_stake.dm @@ -48,10 +48,7 @@ handle_density() to_chat(user, "You slide the target into the stake.") -/obj/structure/target_stake/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) - . = ..() - if(.) - return +/obj/structure/target_stake/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(pinned_target) removeTarget(user) diff --git a/code/game/objects/structures/transit_tubes/station.dm b/code/game/objects/structures/transit_tubes/station.dm index 7f597857d9..3a5eb135f4 100644 --- a/code/game/objects/structures/transit_tubes/station.dm +++ b/code/game/objects/structures/transit_tubes/station.dm @@ -58,10 +58,7 @@ qdel(R) -/obj/structure/transit_tube/station/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) - . = ..() - if(.) - return +/obj/structure/transit_tube/station/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(!pod_moving) if(user.pulling && user.a_intent == INTENT_GRAB && isliving(user.pulling)) if(open_status == STATION_TUBE_OPEN) diff --git a/code/game/objects/structures/transit_tubes/transit_tube_pod.dm b/code/game/objects/structures/transit_tubes/transit_tube_pod.dm index 36539ae1e4..cf68341b2c 100644 --- a/code/game/objects/structures/transit_tubes/transit_tube_pod.dm +++ b/code/game/objects/structures/transit_tubes/transit_tube_pod.dm @@ -69,8 +69,6 @@ empty_pod() return if(!moving) - user.changeNext_move(CLICK_CD_BREAKOUT) - user.last_special = world.time + CLICK_CD_BREAKOUT to_chat(user, "You start trying to escape from the pod...") if(do_after(user, 600, target = src)) to_chat(user, "You manage to open the pod.") diff --git a/code/game/objects/structures/watercloset.dm b/code/game/objects/structures/watercloset.dm index 3dacd49fc9..c52249686a 100644 --- a/code/game/objects/structures/watercloset.dm +++ b/code/game/objects/structures/watercloset.dm @@ -13,6 +13,8 @@ var/mob/living/swirlie = null //the mob being given a swirlie var/buildstacktype = /obj/item/stack/sheet/metal //they're metal now, shut up var/buildstackamount = 1 + attack_hand_speed = CLICK_CD_MELEE + attack_hand_is_action = TRUE /obj/structure/toilet/Initialize() . = ..() @@ -26,18 +28,16 @@ AM.forceMove(loc) return ..() -/obj/structure/toilet/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/structure/toilet/on_attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return if(swirlie) - user.changeNext_move(CLICK_CD_MELEE) playsound(src.loc, "swing_hit", 25, 1) swirlie.visible_message("[user] slams the toilet seat onto [swirlie]'s head!", "[user] slams the toilet seat onto your head!", "You hear reverberating porcelain.") swirlie.adjustBruteLoss(5) else if(user.pulling && user.a_intent == INTENT_GRAB && isliving(user.pulling)) - user.changeNext_move(CLICK_CD_MELEE) var/mob/living/GM = user.pulling if(user.grab_state >= GRAB_AGGRESSIVE) if(GM.loc != get_turf(src)) @@ -167,6 +167,8 @@ icon_state = "urinal" density = FALSE anchored = TRUE + attack_hand_speed = CLICK_CD_MELEE + attack_hand_is_action = TRUE var/exposed = 0 // can you currently put an item inside var/obj/item/hiddenitem = null // what's in the urinal @@ -174,17 +176,13 @@ ..() hiddenitem = new /obj/item/reagent_containers/food/urinalcake -/obj/structure/urinal/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) - . = ..() - if(.) - return +/obj/structure/urinal/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(user.pulling && user.a_intent == INTENT_GRAB && isliving(user.pulling)) var/mob/living/GM = user.pulling if(user.grab_state >= GRAB_AGGRESSIVE) if(GM.loc != get_turf(src)) to_chat(user, "[GM.name] needs to be on [src].") return - user.changeNext_move(CLICK_CD_MELEE) user.visible_message("[user] slams [GM] into [src]!", "You slam [GM] into [src]!") GM.adjustBruteLoss(8) else @@ -492,7 +490,7 @@ var/buildstacktype = /obj/item/stack/sheet/metal var/buildstackamount = 1 -/obj/structure/sink/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/structure/sink/on_attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return @@ -707,8 +705,7 @@ icon_state = "puddle" resistance_flags = UNACIDABLE -//ATTACK HAND IGNORING PARENT RETURN VALUE -/obj/structure/sink/puddle/attack_hand(mob/M) +/obj/structure/sink/puddle/on_attack_hand(mob/M) icon_state = "puddle-splash" . = ..() icon_state = "puddle" @@ -784,10 +781,7 @@ return TRUE -/obj/structure/curtain/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) - . = ..() - if(.) - return +/obj/structure/curtain/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) playsound(loc, 'sound/effects/curtain.ogg', 50, 1) toggle() diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm index 38655df39e..6aae4955f1 100644 --- a/code/game/objects/structures/window.dm +++ b/code/game/objects/structures/window.dm @@ -40,6 +40,8 @@ GLOBAL_LIST_EMPTY(electrochromatic_window_lookup) rad_flags = RAD_PROTECT_CONTENTS flags_ricochet = RICOCHET_HARD ricochet_chance_mod = 0.4 + attack_hand_speed = CLICK_CD_MELEE + attack_hand_is_action = TRUE /// Electrochromatic status var/electrochromatic_status = NOT_ELECTROCHROMATIC @@ -157,7 +159,7 @@ GLOBAL_LIST_EMPTY(electrochromatic_window_lookup) return 1 /obj/structure/window/attack_tk(mob/user) - user.changeNext_move(CLICK_CD_MELEE) + user.DelayNextAction(CLICK_CD_MELEE) user.visible_message("Something knocks on [src].") add_fingerprint(user) playsound(src, 'sound/effects/Glassknock.ogg', 50, 1) @@ -167,18 +169,15 @@ GLOBAL_LIST_EMPTY(electrochromatic_window_lookup) return 1 . = ..() -/obj/structure/window/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) - . = ..() - if(.) - return +/obj/structure/window/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(!can_be_reached(user)) return - user.changeNext_move(CLICK_CD_MELEE) user.visible_message("[user] knocks on [src].") add_fingerprint(user) playsound(src, 'sound/effects/Glassknock.ogg', 50, 1) /obj/structure/window/attack_paw(mob/user) + user.DelayNextAction() return attack_hand(user) /obj/structure/window/attack_generic(mob/user, damage_amount = 0, damage_type = BRUTE, damage_flag = 0, sound_effect = 1) //used by attack_alien, attack_animal, and attack_slime @@ -836,13 +835,9 @@ GLOBAL_LIST_EMPTY(electrochromatic_window_lookup) for (var/i in 1 to rand(1,4)) . += new /obj/item/paper/natural(location) -/obj/structure/window/paperframe/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) - . = ..() - if(.) - return +/obj/structure/window/paperframe/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) add_fingerprint(user) if(user.a_intent != INTENT_HARM) - user.changeNext_move(CLICK_CD_MELEE) user.visible_message("[user] knocks on [src].") playsound(src, "pageturn", 50, 1) else diff --git a/code/game/turfs/simulated/floor.dm b/code/game/turfs/simulated/floor.dm index bdca384bd0..758f824727 100644 --- a/code/game/turfs/simulated/floor.dm +++ b/code/game/turfs/simulated/floor.dm @@ -162,7 +162,7 @@ return 0 /turf/open/floor/crowbar_act(mob/living/user, obj/item/I) - return intact ? pry_tile(I, user) : FALSE + return intact ? FORCE_BOOLEAN(pry_tile(I, user)) : FALSE /turf/open/floor/proc/try_replace_tile(obj/item/stack/tile/T, mob/user, params) if(T.turf_type == type) diff --git a/code/game/turfs/simulated/floor/light_floor.dm b/code/game/turfs/simulated/floor/light_floor.dm index 4f7aa9e492..4bca25f96c 100644 --- a/code/game/turfs/simulated/floor/light_floor.dm +++ b/code/game/turfs/simulated/floor/light_floor.dm @@ -52,10 +52,7 @@ set_light(0) return ..() -/turf/open/floor/light/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) - . = ..() - if(.) - return +/turf/open/floor/light/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(!can_modify_colour) return if(!on) diff --git a/code/game/turfs/simulated/floor/mineral_floor.dm b/code/game/turfs/simulated/floor/mineral_floor.dm index 9a227d2594..8e0230a2b0 100644 --- a/code/game/turfs/simulated/floor/mineral_floor.dm +++ b/code/game/turfs/simulated/floor/mineral_floor.dm @@ -149,7 +149,7 @@ if(!.) honk() -/turf/open/floor/mineral/bananium/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/turf/open/floor/mineral/bananium/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) .=..() if(!.) honk() @@ -202,7 +202,7 @@ if(!.) radiate() -/turf/open/floor/mineral/uranium/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/turf/open/floor/mineral/uranium/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) .=..() if(!.) radiate() diff --git a/code/game/turfs/simulated/floor/plating.dm b/code/game/turfs/simulated/floor/plating.dm index f26a4b827a..ac80bddd00 100644 --- a/code/game/turfs/simulated/floor/plating.dm +++ b/code/game/turfs/simulated/floor/plating.dm @@ -124,7 +124,7 @@ ChangeTurf(/turf/open/floor/plating, flags = CHANGETURF_INHERIT_AIR) else playsound(src, 'sound/weapons/tap.ogg', 100, TRUE) //The attack sound is muffled by the foam itself - user.changeNext_move(CLICK_CD_MELEE) + user.DelayNextAction(CLICK_CD_MELEE) user.do_attack_animation(src) if(prob(I.force * 20 - 25)) user.visible_message("[user] smashes through [src]!", \ diff --git a/code/game/turfs/simulated/floor/reinf_floor.dm b/code/game/turfs/simulated/floor/reinf_floor.dm index b050d8fb89..03045674e4 100644 --- a/code/game/turfs/simulated/floor/reinf_floor.dm +++ b/code/game/turfs/simulated/floor/reinf_floor.dm @@ -89,10 +89,7 @@ /turf/open/floor/engine/attack_paw(mob/user) return attack_hand(user) -/turf/open/floor/engine/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) - . = ..() - if(.) - return +/turf/open/floor/engine/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) user.Move_Pulled(src) //air filled floors; used in atmos pressure chambers diff --git a/code/game/turfs/simulated/wall/mineral_walls.dm b/code/game/turfs/simulated/wall/mineral_walls.dm index c8afe628db..4466511acd 100644 --- a/code/game/turfs/simulated/wall/mineral_walls.dm +++ b/code/game/turfs/simulated/wall/mineral_walls.dm @@ -72,7 +72,7 @@ return return -/turf/closed/wall/mineral/uranium/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/turf/closed/wall/mineral/uranium/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) radiate() . = ..() diff --git a/code/game/turfs/simulated/wall/reinf_walls.dm b/code/game/turfs/simulated/wall/reinf_walls.dm index a1d2c1757c..6b41f41763 100644 --- a/code/game/turfs/simulated/wall/reinf_walls.dm +++ b/code/game/turfs/simulated/wall/reinf_walls.dm @@ -36,7 +36,8 @@ new /obj/item/stack/sheet/metal(src, 2) /turf/closed/wall/r_wall/attack_animal(mob/living/simple_animal/M) - M.changeNext_move(CLICK_CD_MELEE) + if(!M.CheckActionCooldown()) + return M.do_attack_animation(src) if(!M.environment_smash) return @@ -46,6 +47,7 @@ else playsound(src, 'sound/effects/bang.ogg', 50, 1) to_chat(M, "This wall is far too strong for you to destroy.") + M.DelayNextAction() /turf/closed/wall/r_wall/try_destroy(obj/item/I, mob/user, turf/T) if(istype(I, /obj/item/pickaxe/drill/jackhammer)) diff --git a/code/game/turfs/simulated/walls.dm b/code/game/turfs/simulated/walls.dm index df63cf93e6..37248f814c 100644 --- a/code/game/turfs/simulated/walls.dm +++ b/code/game/turfs/simulated/walls.dm @@ -9,6 +9,8 @@ thermal_conductivity = WALL_HEAT_TRANSFER_COEFFICIENT heat_capacity = 312500 //a little over 5 cm thick , 312500 for 1 m by 2.5 m by 0.25 m plasteel wall + attack_hand_speed = 8 + attack_hand_is_action = TRUE baseturfs = /turf/open/floor/plating @@ -113,12 +115,12 @@ return FALSE /turf/closed/wall/attack_paw(mob/living/user) - user.changeNext_move(CLICK_CD_MELEE) return attack_hand(user) - /turf/closed/wall/attack_animal(mob/living/simple_animal/M) - M.changeNext_move(CLICK_CD_MELEE) + if(!M.CheckActionCooldown(CLICK_CD_MELEE)) + return + M.DelayNextAction() M.do_attack_animation(src) if((M.environment_smash & ENVIRONMENT_SMASH_WALLS) || (M.environment_smash & ENVIRONMENT_SMASH_RWALLS)) playsound(src, 'sound/effects/meteorimpact.ogg', 100, 1) @@ -137,17 +139,14 @@ to_chat(user, text("You punch the wall.")) return TRUE -/turf/closed/wall/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) - . = ..() - if(.) - return - user.changeNext_move(CLICK_CD_MELEE) +/turf/closed/wall/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) to_chat(user, "You push the wall but nothing happens!") playsound(src, 'sound/weapons/genhit.ogg', 25, 1) add_fingerprint(user) /turf/closed/wall/attackby(obj/item/W, mob/user, params) - user.changeNext_move(CLICK_CD_MELEE) + if(!user.CheckActionCooldown(CLICK_CD_MELEE)) + return if (!user.IsAdvancedToolUser()) to_chat(user, "You don't have the dexterity to do this!") return @@ -156,6 +155,7 @@ if(!isturf(user.loc)) return //can't do this stuff whilst inside objects and such + user.DelayNextAction() add_fingerprint(user) var/turf/T = user.loc //get user's location for delay checks diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index 02c12a9744..55d945535d 100755 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -122,10 +122,7 @@ requires_activation = FALSE ..() -/turf/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) - . = ..() - if(.) - return +/turf/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) user.Move_Pulled(src) /turf/proc/multiz_turf_del(turf/T, dir) diff --git a/code/modules/NTNet/relays.dm b/code/modules/NTNet/relays.dm index 2101a72960..c64e2332cc 100644 --- a/code/modules/NTNet/relays.dm +++ b/code/modules/NTNet/relays.dm @@ -118,4 +118,4 @@ D.target = null D.error = "Connection to quantum relay severed" - return ..() \ No newline at end of file + return ..() diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index a2e2b3c122..8cfae3820a 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -40,6 +40,11 @@ if(M.client) body += "
    \[First Seen: [M.client.player_join_date]\]\[Byond account registered on: [M.client.account_join_date]\]" + body += "

    CentCom Galactic Ban DB: " + if(CONFIG_GET(string/centcom_ban_db)) + body += "Search" + else + body += "Disabled" body += "

    Show related accounts by: " body += "\[ CID | " body += "IP \]" diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index 1e3d1e93e3..41c3fe5105 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -2834,6 +2834,60 @@ usr << browse(dat.Join("
    "), "window=related_[C];size=420x300") + else if(href_list["centcomlookup"]) + if(!check_rights(R_ADMIN)) + return + + if(!CONFIG_GET(string/centcom_ban_db)) + to_chat(usr, "Centcom Galactic Ban DB is disabled!") + return + + var/ckey = href_list["centcomlookup"] + + // Make the request + var/datum/http_request/request = new() + request.prepare(RUSTG_HTTP_METHOD_GET, "[CONFIG_GET(string/centcom_ban_db)]/[ckey]", "", "") + request.begin_async() + UNTIL(request.is_complete() || !usr) + if (!usr) + return + var/datum/http_response/response = request.into_response() + + var/list/bans + + var/list/dat = list("") + + if(response.errored) + dat += "
    Failed to connect to CentCom." + else if(response.status_code != 200) + dat += "
    Failed to connect to CentCom. Status code: [response.status_code]" + else + if(response.body == "[]") + dat += "
    0 bans detected for [ckey]
    " + else + bans = json_decode(response["body"]) + dat += "
    [bans.len] ban\s detected for [ckey]
    " + for(var/list/ban in bans) + dat += "Server: [sanitize(ban["sourceName"])]
    " + dat += "RP Level: [sanitize(ban["sourceRoleplayLevel"])]
    " + dat += "Type: [sanitize(ban["type"])]
    " + dat += "Banned By: [sanitize(ban["bannedBy"])]
    " + dat += "Reason: [sanitize(ban["reason"])]
    " + dat += "Datetime: [sanitize(ban["bannedOn"])]
    " + var/expiration = ban["expires"] + dat += "Expires: [expiration ? "[sanitize(expiration)]" : "Permanent"]
    " + if(ban["type"] == "job") + dat += "Jobs: " + var/list/jobs = ban["jobs"] + dat += sanitize(jobs.Join(", ")) + dat += "
    " + dat += "
    " + + dat += "
    " + var/datum/browser/popup = new(usr, "centcomlookup-[ckey]", "
    Central Command Galactic Ban Database
    ", 700, 600) + popup.set_content(dat.Join()) + popup.open(0) + else if(href_list["modantagrep"]) if(!check_rights(R_ADMIN)) return diff --git a/code/modules/admin/verbs/diagnostics.dm b/code/modules/admin/verbs/diagnostics.dm index b3bea2201c..6f8e9e703f 100644 --- a/code/modules/admin/verbs/diagnostics.dm +++ b/code/modules/admin/verbs/diagnostics.dm @@ -22,37 +22,6 @@ show_air_status_to(target, usr) SSblackbox.record_feedback("tally", "admin_verb", 1, "Show Air Status") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! -/client/proc/fix_next_move() - set category = "Debug" - set name = "Unfreeze Everyone" - var/largest_move_time = 0 - var/largest_click_time = 0 - var/mob/largest_move_mob = null - var/mob/largest_click_mob = null - for(var/mob/M in world) - if(!M.client) - continue - if(M.next_move >= largest_move_time) - largest_move_mob = M - if(M.next_move > world.time) - largest_move_time = M.next_move - world.time - else - largest_move_time = 1 - if(M.next_click >= largest_click_time) - largest_click_mob = M - if(M.next_click > world.time) - largest_click_time = M.next_click - world.time - else - largest_click_time = 0 - log_admin("DEBUG: [key_name(M)] next_move = [M.next_move] lastDblClick = [M.next_click] world.time = [world.time]") - M.next_move = 1 - M.next_click = 0 - message_admins("[ADMIN_LOOKUPFLW(largest_move_mob)] had the largest move delay with [largest_move_time] frames / [DisplayTimeText(largest_move_time)]!") - message_admins("[ADMIN_LOOKUPFLW(largest_click_mob)] had the largest click delay with [largest_click_time] frames / [DisplayTimeText(largest_click_time)]!") - message_admins("world.time = [world.time]") - SSblackbox.record_feedback("tally", "admin_verb", 1, "Unfreeze Everyone") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - return - /client/proc/radio_report() set category = "Debug" set name = "Radio report" diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm index d0dc3c789e..c559135bd1 100644 --- a/code/modules/admin/verbs/randomverbs.dm +++ b/code/modules/admin/verbs/randomverbs.dm @@ -1280,12 +1280,12 @@ GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits ADMIN_PUNISHMENT_SUPPLYPOD, ADMIN_PUNISHMENT_MAZING, ADMIN_PUNISHMENT_ROD, + ADMIN_PUNISHMENT_SHOES, ADMIN_PUNISHMENT_PICKLE, ADMIN_PUNISHMENT_FRY, - ADMIN_PUNISHMENT_CRACK, - ADMIN_PUNISHMENT_BLEED, - ADMIN_PUNISHMENT_SCARIFY) - + ADMIN_PUNISHMENT_CRACK, + ADMIN_PUNISHMENT_BLEED, + ADMIN_PUNISHMENT_SCARIFY) var/punishment = input("Choose a punishment", "DIVINE SMITING") as null|anything in punishment_list @@ -1395,6 +1395,17 @@ GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits if(ADMIN_PUNISHMENT_FRY) target.fry() + if(ADMIN_PUNISHMENT_SHOES) + if(!iscarbon(target)) + to_chat(usr,"This must be used on a carbon mob.") + return + var/mob/living/carbon/C = target + var/obj/item/clothing/shoes/sick_kicks = C.shoes + if(!sick_kicks?.can_be_tied) + to_chat(usr,"[C] does not have knottable shoes!") + return + sick_kicks.adjust_laces(SHOES_KNOTTED) + punish_log(target, punishment) /client/proc/punish_log(var/whom, var/punishment) diff --git a/code/modules/antagonists/abductor/abductor.dm b/code/modules/antagonists/abductor/abductor.dm index b4fc5b5948..7eb7ec2af2 100644 --- a/code/modules/antagonists/abductor/abductor.dm +++ b/code/modules/antagonists/abductor/abductor.dm @@ -60,8 +60,10 @@ /datum/antagonist/abductor/greet() to_chat(owner.current, "You are the [owner.special_role]!") - to_chat(owner.current, "With the help of your teammate, kidnap and experiment on station crew members!") - to_chat(owner.current, "Try not to disturb the habitat, it could lead to dead specimens.") + to_chat(owner.current, "You are an operative for your home planet's government. Your mission is to detain, experiment, and observe.") + to_chat(owner.current, "Work together with your teammate to bring live subjects from the space station nearby onto your ship for experimentation.") + to_chat(owner.current, "For the sake of the mission, do not damage the integrity of the station, do not kill anyone unless in self defense, always capture specimens first if you can, and do not steal equipment or belongings from abducted specimens.") + to_chat(owner.current, "Your task is to observe and take notes of the effects of your experiments.") to_chat(owner.current, "[greet_text]") owner.announce_objectives() diff --git a/code/modules/antagonists/abductor/machinery/console.dm b/code/modules/antagonists/abductor/machinery/console.dm index 9c9715ee43..6a981b36dc 100644 --- a/code/modules/antagonists/abductor/machinery/console.dm +++ b/code/modules/antagonists/abductor/machinery/console.dm @@ -24,10 +24,7 @@ var/obj/machinery/computer/camera_advanced/abductor/camera var/list/datum/icon_snapshot/disguises = list() -/obj/machinery/abductor/console/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) - . = ..() - if(.) - return +/obj/machinery/abductor/console/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(!HAS_TRAIT(user, TRAIT_ABDUCTOR_TRAINING) && !HAS_TRAIT(user.mind, TRAIT_ABDUCTOR_TRAINING)) to_chat(user, "You start mashing alien buttons at random!") if(do_after(user,100, target = src)) diff --git a/code/modules/antagonists/abductor/machinery/dispenser.dm b/code/modules/antagonists/abductor/machinery/dispenser.dm index ef423b6379..90dcf6626f 100644 --- a/code/modules/antagonists/abductor/machinery/dispenser.dm +++ b/code/modules/antagonists/abductor/machinery/dispenser.dm @@ -22,10 +22,7 @@ gland_colors[i] = random_color() amounts[i] = rand(1,5) -/obj/machinery/abductor/gland_dispenser/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) - . = ..() - if(.) - return +/obj/machinery/abductor/gland_dispenser/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(!isabductor(user)) return user.set_machine(src) diff --git a/code/modules/antagonists/abductor/machinery/experiment.dm b/code/modules/antagonists/abductor/machinery/experiment.dm index b94912b635..bc58cf45f0 100644 --- a/code/modules/antagonists/abductor/machinery/experiment.dm +++ b/code/modules/antagonists/abductor/machinery/experiment.dm @@ -21,10 +21,7 @@ return close_machine(target) -/obj/machinery/abductor/experiment/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) - . = ..() - if(.) - return +/obj/machinery/abductor/experiment/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) experimentUI(user) @@ -47,8 +44,6 @@ to_chat(user, "[src]'s door won't budge!") /obj/machinery/abductor/experiment/container_resist(mob/living/user) - user.changeNext_move(CLICK_CD_BREAKOUT) - user.last_special = world.time + CLICK_CD_BREAKOUT user.visible_message("You see [user] kicking against the door of [src]!", \ "You lean on the back of [src] and start pushing the door open... (this will take about [DisplayTimeText(breakout_time)].)", \ "You hear a metallic creaking from [src].") diff --git a/code/modules/antagonists/blob/blob/theblob.dm b/code/modules/antagonists/blob/blob/theblob.dm index 6a73dc579b..ed85726a4a 100644 --- a/code/modules/antagonists/blob/blob/theblob.dm +++ b/code/modules/antagonists/blob/blob/theblob.dm @@ -225,7 +225,7 @@ /obj/structure/blob/attackby(obj/item/I, mob/user, params) if(istype(I, /obj/item/analyzer)) - user.changeNext_move(CLICK_CD_MELEE) + user.DelayNextAction(CLICK_CD_MELEE) to_chat(user, "The analyzer beeps once, then reports:
    ") SEND_SOUND(user, sound('sound/machines/ping.ogg')) if(overmind) diff --git a/code/modules/antagonists/bloodsucker/bloodsucker_life.dm b/code/modules/antagonists/bloodsucker/bloodsucker_life.dm index 208b1be87b..a81f702a75 100644 --- a/code/modules/antagonists/bloodsucker/bloodsucker_life.dm +++ b/code/modules/antagonists/bloodsucker/bloodsucker_life.dm @@ -10,26 +10,24 @@ // // Show as dead when... -/datum/antagonist/bloodsucker/proc/LifeTick()// Should probably run from life.dm, same as handle_changeling, but will be an utter pain to move - set waitfor = FALSE // Don't make on_gain() wait for this function to finish. This lets this code run on the side. - var/notice_healing - while(owner && !AmFinalDeath()) - if(owner.current.stat == CONSCIOUS && !poweron_feed && !HAS_TRAIT(owner.current, TRAIT_FAKEDEATH)) // Deduct Blood - AddBloodVolume(passive_blood_drain) // -.1 currently - if(HandleHealing(1)) // Heal - if(!notice_healing && owner.current.blood_volume > 0) - to_chat(owner, "The power of your blood begins knitting your wounds...") - notice_healing = TRUE - else if(notice_healing == TRUE) - notice_healing = FALSE // Apply Low Blood Effects - HandleStarving() // Death - HandleDeath() // Standard Update - update_hud()// Daytime Sleep in Coffin - if(SSticker.mode.is_daylight() && !HAS_TRAIT_FROM(owner.current, TRAIT_FAKEDEATH, "bloodsucker")) - if(istype(owner.current.loc, /obj/structure/closet/crate/coffin)) - Torpor_Begin() - // Wait before next pass - sleep(10) +/datum/antagonist/bloodsucker/proc/LifeTick() //Runs from BiologicalLife, handles all the bloodsucker constant proccesses + if(!owner || AmFinalDeath()) + return + if(owner.current.stat == CONSCIOUS && !poweron_feed && !HAS_TRAIT(owner.current, TRAIT_FAKEDEATH)) // Deduct Blood + AddBloodVolume(passive_blood_drain) // -.1 currently + if(HandleHealing(1)) // Heal + if(!notice_healing && owner.current.blood_volume > 0) + to_chat(owner, "The power of your blood begins knitting your wounds...") + notice_healing = TRUE + else if(notice_healing) + notice_healing = FALSE // Apply Low Blood Effects + HandleStarving() // Death + HandleDeath() // Standard Update + update_hud()// Daytime Sleep in Coffin + if(SSticker.mode.is_daylight() && !HAS_TRAIT_FROM(owner.current, TRAIT_FAKEDEATH, "bloodsucker")) + if(istype(owner.current.loc, /obj/structure/closet/crate/coffin)) + Torpor_Begin() + // Wait before next pass FreeAllVassals() // Free my Vassals! (if I haven't yet) ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/code/modules/antagonists/bloodsucker/datum_bloodsucker.dm b/code/modules/antagonists/bloodsucker/datum_bloodsucker.dm index d732742e51..1fcffff810 100644 --- a/code/modules/antagonists/bloodsucker/datum_bloodsucker.dm +++ b/code/modules/antagonists/bloodsucker/datum_bloodsucker.dm @@ -37,6 +37,7 @@ var/had_toxlover var/level_bloodcost var/passive_blood_drain = -0.1 //The amount of blood we loose each bloodsucker life() tick + var/notice_healing //Var to see if you are healing for preventing spam of the chat message inform the user of such var/FinalDeath //Have we reached final death? Used to prevent spam. // LISTS var/static/list/defaultTraits = list (TRAIT_STABLEHEART, TRAIT_NOBREATH, TRAIT_SLEEPIMMUNE, TRAIT_NOCRITDAMAGE, TRAIT_RESISTCOLD, TRAIT_RADIMMUNE, TRAIT_NIGHT_VISION, \ @@ -51,7 +52,6 @@ AssignStarterPowersAndStats()// Give Powers & Stats forge_bloodsucker_objectives()// Objectives & Team update_bloodsucker_icons_added(owner.current, "bloodsucker") // Add Antag HUD - LifeTick() // Run Life Function . = ..() diff --git a/code/modules/antagonists/bloodsucker/objects/bloodsucker_crypt.dm b/code/modules/antagonists/bloodsucker/objects/bloodsucker_crypt.dm index 9301d0c239..9af2553644 100644 --- a/code/modules/antagonists/bloodsucker/objects/bloodsucker_crypt.dm +++ b/code/modules/antagonists/bloodsucker/objects/bloodsucker_crypt.dm @@ -217,7 +217,7 @@ return FALSE return ..() -/obj/structure/bloodsucker/vassalrack/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/structure/bloodsucker/vassalrack/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) //. = ..() // Taken from sacrificial altar in divine.dm //if(.) // return @@ -469,7 +469,7 @@ . += {"This is a magical candle which drains at the sanity of the fools who havent yet accepted your master, as long as it is active.\n You can turn it on and off by clicking on it while you are next to it"} */ -/obj/structure/bloodsucker/candelabrum/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/structure/bloodsucker/candelabrum/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) var/datum/antagonist/vassal/T = user.mind.has_antag_datum(ANTAG_DATUM_VASSAL) if(AmBloodsucker(user) || istype(T)) toggle() diff --git a/code/modules/antagonists/bloodsucker/powers/mesmerize.dm b/code/modules/antagonists/bloodsucker/powers/mesmerize.dm index fccef4fb0c..efdd312c6e 100644 --- a/code/modules/antagonists/bloodsucker/powers/mesmerize.dm +++ b/code/modules/antagonists/bloodsucker/powers/mesmerize.dm @@ -128,11 +128,9 @@ target.face_atom(L) target.Stun(power_time) to_chat(L, "[target] is fixed in place by your hypnotic gaze.") - target.next_move = world.time + power_time // <--- Use direct change instead. We want an unmodified delay to their next move // target.changeNext_move(power_time) // check click.dm - target.mob_transforming = TRUE // <--- Fuck it. We tried using next_move, but they could STILL resist. We're just doing a hard freeze. + target.DelayNextAction(power_time) spawn(power_time) if(istype(target) && success) - target.mob_transforming = FALSE if(istype(L) && target.stat == CONSCIOUS && (target in L.fov_view(10))) // They Woke Up! (Notice if within view) to_chat(L, "[target] has snapped out of their trance.") diff --git a/code/modules/antagonists/bloodsucker/powers/trespass.dm b/code/modules/antagonists/bloodsucker/powers/trespass.dm index cad3eeb88b..56b72a562e 100644 --- a/code/modules/antagonists/bloodsucker/powers/trespass.dm +++ b/code/modules/antagonists/bloodsucker/powers/trespass.dm @@ -81,9 +81,7 @@ var/mist_delay = max(5, 20 - level_current * 2.5) // Level up and do this faster. // Freeze Me - user.next_move = world.time + mist_delay user.Stun(mist_delay, ignore_canstun = TRUE) - user.mob_transforming = TRUE user.density = FALSE var/invis_was = user.invisibility user.invisibility = INVISIBILITY_MAXIMUM @@ -96,7 +94,6 @@ // Move & Freeze if(isturf(target_turf)) do_teleport(owner, target_turf, no_effects=TRUE, channel = TELEPORT_CHANNEL_QUANTUM) // in teleport.dm? - user.next_move = world.time + mist_delay / 2 user.Stun(mist_delay / 2, ignore_canstun = TRUE) // Wait... @@ -104,9 +101,7 @@ // Un-Hide & Freeze user.dir = get_dir(my_turf, target_turf) - user.next_move = world.time + mist_delay / 2 user.Stun(mist_delay / 2, ignore_canstun = TRUE) - user.mob_transforming = FALSE user.density = 1 user.invisibility = invis_was diff --git a/code/modules/antagonists/changeling/powers/transform.dm b/code/modules/antagonists/changeling/powers/transform.dm index c0979b6936..8e3a36740b 100644 --- a/code/modules/antagonists/changeling/powers/transform.dm +++ b/code/modules/antagonists/changeling/powers/transform.dm @@ -17,8 +17,7 @@ ADD_TRAIT(src, TRAIT_NODROP, CHANGELING_TRAIT) -//ATTACK HAND IGNORING PARENT RETURN VALUE -/obj/item/clothing/glasses/changeling/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/item/clothing/glasses/changeling/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(loc == user && user.mind && user.mind.has_antag_datum(/datum/antagonist/changeling)) to_chat(user, "You reabsorb [src] into your body.") qdel(src) @@ -33,8 +32,7 @@ ADD_TRAIT(src, TRAIT_NODROP, CHANGELING_TRAIT) -//ATTACK HAND IGNORING PARENT RETURN VALUE -/obj/item/clothing/under/changeling/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/item/clothing/under/changeling/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(loc == user && user.mind && user.mind.has_antag_datum(/datum/antagonist/changeling)) to_chat(user, "You reabsorb [src] into your body.") qdel(src) @@ -50,8 +48,7 @@ ADD_TRAIT(src, TRAIT_NODROP, CHANGELING_TRAIT) -//ATTACK HAND IGNORING PARENT RETURN VALUE -/obj/item/clothing/suit/changeling/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/item/clothing/suit/changeling/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(loc == user && user.mind && user.mind.has_antag_datum(/datum/antagonist/changeling)) to_chat(user, "You reabsorb [src] into your body.") qdel(src) @@ -65,8 +62,7 @@ . = ..() ADD_TRAIT(src, TRAIT_NODROP, CHANGELING_TRAIT) -//ATTACK HAND IGNORING PARENT RETURN VALUE -/obj/item/clothing/head/changeling/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/item/clothing/head/changeling/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(loc == user && user.mind && user.mind.has_antag_datum(/datum/antagonist/changeling)) to_chat(user, "You reabsorb [src] into your body.") qdel(src) @@ -81,8 +77,7 @@ ADD_TRAIT(src, TRAIT_NODROP, CHANGELING_TRAIT) -//ATTACK HAND IGNORING PARENT RETURN VALUE -/obj/item/clothing/shoes/changeling/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/item/clothing/shoes/changeling/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(loc == user && user.mind && user.mind.has_antag_datum(/datum/antagonist/changeling)) to_chat(user, "You reabsorb [src] into your body.") qdel(src) @@ -97,8 +92,7 @@ ADD_TRAIT(src, TRAIT_NODROP, CHANGELING_TRAIT) -//ATTACK HAND IGNORING PARENT RETURN VALUE -/obj/item/clothing/gloves/changeling/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/item/clothing/gloves/changeling/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(loc == user && user.mind && user.mind.has_antag_datum(/datum/antagonist/changeling)) to_chat(user, "You reabsorb [src] into your body.") qdel(src) @@ -113,8 +107,7 @@ ADD_TRAIT(src, TRAIT_NODROP, CHANGELING_TRAIT) -//ATTACK HAND IGNORING PARENT RETURN VALUE -/obj/item/clothing/mask/changeling/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/item/clothing/mask/changeling/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(loc == user && user.mind && user.mind.has_antag_datum(/datum/antagonist/changeling)) to_chat(user, "You reabsorb [src] into your body.") qdel(src) @@ -131,8 +124,7 @@ ADD_TRAIT(src, TRAIT_NODROP, CHANGELING_TRAIT) -//ATTACK HAND IGNORING PARENT RETURN VALUE -/obj/item/changeling/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/item/changeling/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(loc == user && user.mind && user.mind.has_antag_datum(/datum/antagonist/changeling)) to_chat(user, "You reabsorb [src] into your body.") qdel(src) diff --git a/code/modules/antagonists/clockcult/clock_effects/city_of_cogs_rift.dm b/code/modules/antagonists/clockcult/clock_effects/city_of_cogs_rift.dm index 21d0035ef1..3ea4668df8 100644 --- a/code/modules/antagonists/clockcult/clock_effects/city_of_cogs_rift.dm +++ b/code/modules/antagonists/clockcult/clock_effects/city_of_cogs_rift.dm @@ -36,8 +36,7 @@ return . = ..() -//ATTACK HAND IGNORING PARENT RETURN VALUE -/obj/effect/clockwork/city_of_cogs_rift/attack_hand(atom/movable/AM) +/obj/effect/clockwork/city_of_cogs_rift/on_attack_hand(atom/movable/AM) beckon(AM) /obj/effect/clockwork/city_of_cogs_rift/Bumped(atom/movable/AM) diff --git a/code/modules/antagonists/clockcult/clock_effects/clock_sigils.dm b/code/modules/antagonists/clockcult/clock_effects/clock_sigils.dm index 90c4bdf8de..e579023a7a 100644 --- a/code/modules/antagonists/clockcult/clock_effects/clock_sigils.dm +++ b/code/modules/antagonists/clockcult/clock_effects/clock_sigils.dm @@ -27,8 +27,7 @@ /obj/effect/clockwork/sigil/attack_tk(mob/user) return //you can't tk stomp sigils, but you can hit them with something -//ATTACK HAND IGNORING PARENT RETURN VALUE -/obj/effect/clockwork/sigil/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/effect/clockwork/sigil/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(iscarbon(user) && !user.stat) if(is_servant_of_ratvar(user) && user.a_intent != INTENT_HARM) return ..() @@ -217,6 +216,20 @@ else if(get_clockwork_power()) to_chat(L, "You feel a slight, static shock.") +/obj/effect/clockwork/sigil/transmission/process() + var/power_drained = 0 + var/power_mod = 0.005 + for(var/t in spiral_range_turfs(SIGIL_ACCESS_RANGE, src)) + var/turf/T = t + for(var/M in T) + var/atom/movable/A = M + power_drained += A.power_drain(TRUE) + + CHECK_TICK + + adjust_clockwork_power(power_drained * power_mod * 15) + new /obj/effect/temp_visual/ratvar/sigil/transmission(loc, 1 + (power_drained * 0.0035)) + /obj/effect/clockwork/sigil/transmission/proc/charge_cyborg(mob/living/silicon/robot/cyborg) if(!cyborg_checks(cyborg)) return diff --git a/code/modules/antagonists/clockcult/clock_effects/spatial_gateway.dm b/code/modules/antagonists/clockcult/clock_effects/spatial_gateway.dm index 9106015c0a..00c52e4a59 100644 --- a/code/modules/antagonists/clockcult/clock_effects/spatial_gateway.dm +++ b/code/modules/antagonists/clockcult/clock_effects/spatial_gateway.dm @@ -14,6 +14,8 @@ var/uses = 1 //How many objects or mobs can go through the portal var/obj/effect/clockwork/spatial_gateway/linked_gateway //The gateway linked to this one var/timerid + var/is_stable = FALSE + var/busy = FALSE //If someone is already working on closing the gateway, only needed for stable gateways but in the parent to not need typecasting /obj/effect/clockwork/spatial_gateway/Initialize() . = ..() @@ -31,11 +33,16 @@ clockwork_desc = "A gateway in reality. It can both send and receive objects." else clockwork_desc = "A gateway in reality. It can only [sender ? "send" : "receive"] objects." - timerid = QDEL_IN(src, lifetime) + if(is_stable) + return + timerid = QDEL_IN(src, lifetime) //We only need this if the gateway is not stable //set up a gateway with another gateway /obj/effect/clockwork/spatial_gateway/proc/setup_gateway(obj/effect/clockwork/spatial_gateway/gatewayB, set_duration, set_uses, two_way) - if(!gatewayB || !set_duration || !uses) + if(!gatewayB) + return FALSE + + if((!set_duration || !uses) && !is_stable) return FALSE linked_gateway = gatewayB gatewayB.linked_gateway = src @@ -55,7 +62,7 @@ /obj/effect/clockwork/spatial_gateway/examine(mob/user) . = ..() if(is_servant_of_ratvar(user) || isobserver(user)) - . += "It has [uses] use\s remaining." + . += " [is_stable ? "It is stabilised and can be used as much as is neccessary." : "It has [uses] use\s remaining."]" //ATTACK GHOST IGNORING PARENT RETURN VALUE /obj/effect/clockwork/spatial_gateway/attack_ghost(mob/user) @@ -63,8 +70,7 @@ user.forceMove(get_turf(linked_gateway)) ..() -//ATTACK HAND IGNORING PARENT RETURN VALUE -/obj/effect/clockwork/spatial_gateway/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/effect/clockwork/spatial_gateway/on_attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) if(!uses) return FALSE if(user.pulling && user.a_intent == INTENT_GRAB && isliving(user.pulling)) @@ -122,9 +128,9 @@ /obj/effect/clockwork/spatial_gateway/Bumped(atom/movable/AM) ..() if(!QDELETED(AM)) - pass_through_gateway(AM, FALSE) + pass_through_gateway(AM) -/obj/effect/clockwork/spatial_gateway/proc/pass_through_gateway(atom/movable/A, no_cost) +/obj/effect/clockwork/spatial_gateway/proc/pass_through_gateway(atom/movable/A, no_cost = FALSE) if(!linked_gateway) qdel(src) return FALSE @@ -198,6 +204,10 @@ return procure_gateway(invoker, time_duration, gateway_uses, two_way) var/istargetobelisk = istype(target, /obj/structure/destructible/clockwork/powered/clockwork_obelisk) var/issrcobelisk = istype(src, /obj/structure/destructible/clockwork/powered/clockwork_obelisk) + if(!issrcobelisk && target.z != invoker.z && (is_reebe(invoker.z) || is_reebe(target.z)) && !GLOB.ratvar_awakens) //You need obilisks to get from and to reebe. Costs alot of power, unless you use stable gateways. + to_chat(invoker, "The distance between reebe and the mortal realm is far too vast to bridge with a gateway your slab can create, my child. \ + Use an obilisk instead!") + return procure_gateway(invoker, time_duration, gateway_uses, two_way) if(issrcobelisk) if(!anchored) to_chat(invoker, "[src] is no longer secured!") @@ -218,12 +228,63 @@ gateway_uses = round(gateway_uses * (2 * efficiency), 1) time_duration = round(time_duration * (2 * efficiency), 1) CO.active = TRUE //you'd be active in a second but you should update immediately - invoker.visible_message("The air in front of [invoker] ripples before suddenly tearing open!", \ - "With a word, you rip open a [two_way ? "two-way":"one-way"] rift to [input_target_key]. It will last for [DisplayTimeText(time_duration)] and has [gateway_uses] use[gateway_uses > 1 ? "s" : ""].") - var/obj/effect/clockwork/spatial_gateway/S1 = new(issrcobelisk ? get_turf(src) : get_step(get_turf(invoker), invoker.dir)) - var/obj/effect/clockwork/spatial_gateway/S2 = new(istargetobelisk ? get_turf(target) : get_step(get_turf(target), target.dir)) + if(issrcobelisk && istargetobelisk && src.z != target.z && (is_reebe(src.z) || is_reebe(target.z))) + invoker.visible_message("The air in front of [invoker] ripples before suddenly tearing open!", \ + "With a word, you rip open a stable two-way rift between reebe and the mortal realm.") + var/obj/effect/clockwork/spatial_gateway/stable/stable_S1 = new(get_turf(src)) + var/obj/effect/clockwork/spatial_gateway/stable/stable_S2 = new(get_turf(target)) + stable_S1.setup_gateway(stable_S2) + stable_S2.visible_message("The air in front of [target] ripples before suddenly tearing open!") + else + invoker.visible_message("The air in front of [invoker] ripples before suddenly tearing open!", \ + "With a word, you rip open a [two_way ? "two-way":"one-way"] rift to [input_target_key]. It will last for [DisplayTimeText(time_duration)] and has [gateway_uses] use[gateway_uses > 1 ? "s" : ""].") + var/obj/effect/clockwork/spatial_gateway/S1 = new(issrcobelisk ? get_turf(src) : get_step(get_turf(invoker), invoker.dir)) + var/obj/effect/clockwork/spatial_gateway/S2 = new(istargetobelisk ? get_turf(target) : get_step(get_turf(target), target.dir)) - //Set up the portals now that they've spawned - S1.setup_gateway(S2, time_duration, gateway_uses, two_way) - S2.visible_message("The air in front of [target] ripples before suddenly tearing open!") + //Set up the portals now that they've spawned + S1.setup_gateway(S2, time_duration, gateway_uses, two_way) + S2.visible_message("The air in front of [target] ripples before suddenly tearing open!") return TRUE + +//Stable Gateway: Used to travel to and from reebe without any further powercost. Needs a clockwork obilisk to keep active, but stays active as long as it is not deactivated via an null rod or a slab, or the obilisk is destroyed +/obj/effect/clockwork/spatial_gateway/stable + name = "stable gateway" + is_stable = TRUE + +/obj/effect/clockwork/spatial_gateway/stable/ex_act(severity) + if(severity == 1) + start_shutdown() //Yes, you can chain devastation-level explosions to delay a gateway shutdown, if you somehow manage to do it without breaking the obelisk. Is it worth it? Probably not. + return TRUE + return FALSE + +/obj/effect/clockwork/spatial_gateway/stable/setup_gateway(obj/effect/clockwork/spatial_gateway/stable/gatewayB) //Reduced setup call due to some things being irrelevant for stable gateways + return ..(gatewayB, 1, 1, TRUE) //Uses and time irrelevant due to is_stable + +/obj/effect/clockwork/spatial_gateway/stable/attackby(obj/item/I, mob/living/user, params) + if(!istype(I, /obj/item/clockwork/slab) || !is_servant_of_ratvar(user) || busy) + return ..() + busy = TRUE + linked_gateway.busy = TRUE + user.visible_message("The rift begins to ripple as [user] points [user.p_their()] slab at it!", " You begin to shutdown the stabilised gateway with your slab.") + linked_gateway.visible_message("") + var/datum/beam/B = user.Beam(src, icon_state = "nzcrentrs_power", maxdistance = 50, time = 80) //Not too fancy, but this'll do.. for now. + if(do_after(user, 80, target = src)) //Eight seconds to initiate the closing, then another two before is closes. + to_chat(user, "You successfully set the gateway to shutdown in another two seconds.") + start_shutdown() + qdel(B) + busy = FALSE + linked_gateway.busy = FALSE + return TRUE + +/obj/effect/clockwork/spatial_gateway/stable/proc/start_shutdown() + deltimer(timerid) + deltimer(linked_gateway.timerid) + timerid = QDEL_IN(src, 20) + linked_gateway.timerid = QDEL_IN(linked_gateway, 20) + animate(src, alpha = 0, transform = matrix()*2, time = 20, flags = ANIMATION_END_NOW) + animate(linked_gateway, alpha = 0, transform = matrix()*2, time = 20, flags = ANIMATION_END_NOW) + src.visible_message("[src] begins to destabilise!") + linked_gateway.visible_message("[linked_gateway] begins to destabilise!") + +/obj/effect/clockwork/spatial_gateway/stable/pass_through_gateway(atom/movable/A, no_cost = TRUE) + return ..() \ No newline at end of file diff --git a/code/modules/antagonists/clockcult/clock_items/clock_weapons/_call_weapon.dm b/code/modules/antagonists/clockcult/clock_items/clock_weapons/_call_weapon.dm index 40aca961fc..a6f2ee6d90 100644 --- a/code/modules/antagonists/clockcult/clock_items/clock_weapons/_call_weapon.dm +++ b/code/modules/antagonists/clockcult/clock_items/clock_weapons/_call_weapon.dm @@ -29,7 +29,7 @@ owner.visible_message("[owner]'s [weapon.name] flickers and disappears!") to_chat(owner, "You dismiss [weapon].") QDEL_NULL(weapon) - weapon_reset(RATVARIAN_SPEAR_COOLDOWN * 0.5) + weapon_reset(RATVARIAN_WEAPON_COOLDOWN * 0.5) return else weapon.visible_message("[weapon] suddenly flickers and disappears!") diff --git a/code/modules/antagonists/clockcult/clock_items/clock_weapons/ratvarian_spear.dm b/code/modules/antagonists/clockcult/clock_items/clock_weapons/ratvarian_spear.dm index 234f0445e0..527745b81a 100644 --- a/code/modules/antagonists/clockcult/clock_items/clock_weapons/ratvarian_spear.dm +++ b/code/modules/antagonists/clockcult/clock_items/clock_weapons/ratvarian_spear.dm @@ -78,5 +78,5 @@ if(T) //make sure we're not in null or something T.visible_message("[src] [pick("cracks in two and fades away", "snaps in two and dematerializes")]!") new /obj/effect/temp_visual/ratvar/spearbreak(T) - action.weapon_reset(RATVARIAN_SPEAR_COOLDOWN) + action.weapon_reset(RATVARIAN_WEAPON_COOLDOWN) diff --git a/code/modules/antagonists/clockcult/clock_items/clockwork_armor.dm b/code/modules/antagonists/clockcult/clock_items/clockwork_armor.dm index a4f8bf8062..d08caa39d7 100644 --- a/code/modules/antagonists/clockcult/clock_items/clockwork_armor.dm +++ b/code/modules/antagonists/clockcult/clock_items/clockwork_armor.dm @@ -8,7 +8,7 @@ resistance_flags = FIRE_PROOF | ACID_PROOF flags_inv = HIDEEARS|HIDEHAIR|HIDEFACE|HIDESNOUT mutantrace_variation = STYLE_MUZZLE - armor = list("melee" = 50, "bullet" = 70, "laser" = -25, "energy" = 0, "bomb" = 60, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100) + armor = list("melee" = 50, "bullet" = 70, "laser" = 0, "energy" = 0, "bomb" = 60, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100, "magic" = 60, "wound" = 65) /obj/item/clothing/head/helmet/clockwork/Initialize() . = ..() @@ -21,17 +21,17 @@ /obj/item/clothing/head/helmet/clockwork/ratvar_act() if(GLOB.ratvar_awakens) - armor = getArmor(melee = 100, bullet = 100, laser = 100, energy = 100, bomb = 100, bio = 100, rad = 100, fire = 100, acid = 100) + armor = getArmor(melee = 100, bullet = 100, laser = 100, energy = 100, bomb = 100, bio = 100, rad = 100, fire = 100, acid = 100, magic = 100, wound = 100) clothing_flags |= STOPSPRESSUREDAMAGE max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT min_cold_protection_temperature = SPACE_HELM_MIN_TEMP_PROTECT else if(GLOB.ratvar_approaches) - armor = getArmor(melee = 70, bullet = 80, laser = -15, energy = 25, bomb = 70, bio = 0, rad = 0, fire = 100, acid = 100) + armor = getArmor(melee = 70, bullet = 80, laser = 10, energy = 25, bomb = 70, bio = 0, rad = 0, fire = 100, acid = 100,, magic = 70, wound = 75) clothing_flags |= STOPSPRESSUREDAMAGE max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT min_cold_protection_temperature = SPACE_HELM_MIN_TEMP_PROTECT else - armor = getArmor(melee = 60, bullet = 70, laser = -25, energy = 0, bomb = 60, bio = 0, rad = 0, fire = 100, acid = 100) + armor = getArmor(melee = 60, bullet = 70, laser = 0, energy = 0, bomb = 60, bio = 0, rad = 0, fire = 100, acid = 100, magic = 60, wound = 65) clothing_flags &= ~STOPSPRESSUREDAMAGE max_heat_protection_temperature = initial(max_heat_protection_temperature) min_cold_protection_temperature = initial(min_cold_protection_temperature) @@ -68,7 +68,7 @@ cold_protection = CHEST|GROIN|LEGS heat_protection = CHEST|GROIN|LEGS resistance_flags = FIRE_PROOF | ACID_PROOF - armor = list("melee" = 60, "bullet" = 70, "laser" = -25, "energy" = 0, "bomb" = 60, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100) + armor = list("melee" = 60, "bullet" = 70, "laser" = 0, "energy" = 0, "bomb" = 60, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100, "magic" = 60, "wound" = 65) allowed = list(/obj/item/clockwork, /obj/item/clothing/glasses/wraith_spectacles, /obj/item/clothing/glasses/judicial_visor, /obj/item/mmi/posibrain/soul_vessel, /obj/item/reagent_containers/food/drinks/bottle/holyoil) mutantrace_variation = STYLE_DIGITIGRADE|STYLE_SNEK_TAURIC @@ -83,17 +83,17 @@ /obj/item/clothing/suit/armor/clockwork/ratvar_act() if(GLOB.ratvar_awakens) - armor = getArmor(melee = 100, bullet = 100, laser = 100, energy = 100, bomb = 100, bio = 100, rad = 100, fire = 100, acid = 100) + armor = getArmor(melee = 100, bullet = 100, laser = 100, energy = 100, bomb = 100, bio = 100, rad = 100, fire = 100, acid = 100, magic = 100, wound = 100) clothing_flags |= STOPSPRESSUREDAMAGE max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT min_cold_protection_temperature = SPACE_HELM_MIN_TEMP_PROTECT else if(GLOB.ratvar_approaches) - armor = getArmor(melee = 70, bullet = 80, laser = -15, energy = 25, bomb = 70, bio = 0, rad = 0, fire = 100, acid = 100) + armor = getArmor(melee = 70, bullet = 80, laser = 10, energy = 25, bomb = 70, bio = 0, rad = 0, fire = 100, acid = 100, magic = 70, wound = 75) clothing_flags |= STOPSPRESSUREDAMAGE max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT min_cold_protection_temperature = SPACE_HELM_MIN_TEMP_PROTECT else - armor = getArmor(melee = 60, bullet = 70, laser = -25, energy = 0, bomb = 60, bio = 0, rad = 0, fire = 100, acid = 100) + armor = getArmor(melee = 60, bullet = 70, laser = 0, energy = 0, bomb = 60, bio = 0, rad = 0, fire = 100, acid = 100, magic = 60, wound = 65) clothing_flags &= ~STOPSPRESSUREDAMAGE max_heat_protection_temperature = initial(max_heat_protection_temperature) min_cold_protection_temperature = initial(min_cold_protection_temperature) @@ -135,7 +135,7 @@ siemens_coefficient = 0 permeability_coefficient = 0.05 resistance_flags = FIRE_PROOF | ACID_PROOF - armor = list("melee" = 80, "bullet" = 70, "laser" = -25, "energy" = 0, "bomb" = 60, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100) + armor = list("melee" = 80, "bullet" = 70, "laser" = 0, "energy" = 0, "bomb" = 60, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100, "magic" = 70, "wound" = 85) /obj/item/clothing/gloves/clockwork/Initialize() . = ..() @@ -153,7 +153,7 @@ max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT min_cold_protection_temperature = SPACE_HELM_MIN_TEMP_PROTECT else - armor = getArmor(melee = 80, bullet = 70, laser = -25, energy = 0, bomb = 60, bio = 0, rad = 0, fire = 100, acid = 100) + armor = getArmor(melee = 80, bullet = 70, laser = 0, energy = 0, bomb = 60, bio = 0, rad = 0, fire = 100, acid = 100, magic = 70, wound = 85) clothing_flags &= ~STOPSPRESSUREDAMAGE max_heat_protection_temperature = initial(max_heat_protection_temperature) min_cold_protection_temperature = initial(min_cold_protection_temperature) diff --git a/code/modules/antagonists/clockcult/clock_items/clockwork_slab.dm b/code/modules/antagonists/clockcult/clock_items/clockwork_slab.dm index d0d3bafe06..04a8e92bb7 100644 --- a/code/modules/antagonists/clockcult/clock_items/clockwork_slab.dm +++ b/code/modules/antagonists/clockcult/clock_items/clockwork_slab.dm @@ -4,7 +4,7 @@ clockwork_desc = "A link between you and the Celestial Derelict. It contains information, recites scripture, and is your most vital tool as a Servant.\ It can be used to link traps and triggers by attacking them with the slab. Keep in mind that traps linked with one another will activate in tandem!" - icon_state = "dread_ipad" + icon_state = "clockwork_slab" lefthand_file = 'icons/mob/inhands/antag/clockwork_lefthand.dmi' righthand_file = 'icons/mob/inhands/antag/clockwork_righthand.dmi' var/inhand_overlay //If applicable, this overlay will be applied to the slab's inhand @@ -21,7 +21,7 @@ var/recollecting = TRUE //if we're looking at fancy recollection. tutorial enabled by default var/recollection_category = "Default" - var/list/quickbound = list(/datum/clockwork_scripture/abscond, \ + var/list/quickbound = list(/datum/clockwork_scripture/spatial_gateway, \ /datum/clockwork_scripture/ranged_ability/kindle, /datum/clockwork_scripture/ranged_ability/hateful_manacles) //quickbound scripture, accessed by index var/maximum_quickbound = 5 //how many quickbound scriptures we can have @@ -57,8 +57,7 @@ to_chat(user, "[src] falls dark. It appears you weren't worthy.") return ..() -//ATTACK HAND IGNORING PARENT RETURN VALUE -/obj/item/clockwork/slab/debug/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/item/clockwork/slab/debug/on_attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) if(!is_servant_of_ratvar(user)) add_servant_of_ratvar(user) return ..() @@ -70,29 +69,32 @@ maximum_quickbound = 6 //we usually have one or two unique scriptures, so if ratvar is up let us bind one more actions_types = list() -/obj/item/clockwork/slab/cyborg/engineer //three scriptures, plus a fabricator - quickbound = list(/datum/clockwork_scripture/abscond, /datum/clockwork_scripture/create_object/replicant, /datum/clockwork_scripture/create_object/sigil_of_transmission, /datum/clockwork_scripture/create_object/stargazer) +/obj/item/clockwork/slab/cyborg/engineer //six scriptures, plus a fabricator. Might revert this if its too OP, I just thought that engineering borgs should get the all the structures + quickbound = list(/datum/clockwork_scripture/spatial_gateway, /datum/clockwork_scripture/create_object/replicant, /datum/clockwork_scripture/create_object/sigil_of_transmission, /datum/clockwork_scripture/create_object/stargazer, \ + /datum/clockwork_scripture/create_object/ocular_warden, /datum/clockwork_scripture/create_object/clockwork_obelisk, /datum/clockwork_scripture/create_object/mania_motor) -/obj/item/clockwork/slab/cyborg/medical //five scriptures, plus a spear - quickbound = list(/datum/clockwork_scripture/abscond, /datum/clockwork_scripture/ranged_ability/linked_vanguard, /datum/clockwork_scripture/ranged_ability/sentinels_compromise, \ - /datum/clockwork_scripture/create_object/vitality_matrix) +/obj/item/clockwork/slab/cyborg/medical //six scriptures, plus a spear + quickbound = list(/datum/clockwork_scripture/spatial_gateway, /datum/clockwork_scripture/ranged_ability/linked_vanguard, /datum/clockwork_scripture/ranged_ability/sentinels_compromise, \ + /datum/clockwork_scripture/create_object/vitality_matrix, /datum/clockwork_scripture/channeled/mending_mantra) -/obj/item/clockwork/slab/cyborg/security //twoscriptures, plus a spear - quickbound = list(/datum/clockwork_scripture/abscond, /datum/clockwork_scripture/ranged_ability/hateful_manacles, /datum/clockwork_scripture/ranged_ability/judicial_marker) - -/obj/item/clockwork/slab/cyborg/peacekeeper //two scriptures, plus a spear - quickbound = list(/datum/clockwork_scripture/abscond, /datum/clockwork_scripture/ranged_ability/hateful_manacles, /datum/clockwork_scripture/ranged_ability/judicial_marker) +/obj/item/clockwork/slab/cyborg/security //four scriptures, plus a spear + quickbound = list(/datum/clockwork_scripture/spatial_gateway, /datum/clockwork_scripture/channeled/volt_blaster, /datum/clockwork_scripture/ranged_ability/hateful_manacles, \ + /datum/clockwork_scripture/ranged_ability/judicial_marker, /datum/clockwork_scripture/channeled/belligerent) +/obj/item/clockwork/slab/cyborg/peacekeeper //four scriptures, plus a spear + quickbound = list(/datum/clockwork_scripture/spatial_gateway, /datum/clockwork_scripture/channeled/volt_blaster, /datum/clockwork_scripture/ranged_ability/hateful_manacles, \ + /datum/clockwork_scripture/ranged_ability/judicial_marker, /datum/clockwork_scripture/channeled/belligerent) +/*//this module was commented out so why wasn't this? /obj/item/clockwork/slab/cyborg/janitor //six scriptures, plus a fabricator - quickbound = list(/datum/clockwork_scripture/abscond, /datum/clockwork_scripture/create_object/replicant, /datum/clockwork_scripture/create_object/sigil_of_transgression, \ + quickbound = list(/datum/clockwork_scripture/spatial_gateway, /datum/clockwork_scripture/create_object/replicant, /datum/clockwork_scripture/create_object/sigil_of_transgression, \ /datum/clockwork_scripture/create_object/stargazer, /datum/clockwork_scripture/create_object/ocular_warden, /datum/clockwork_scripture/create_object/mania_motor) - +*/ /obj/item/clockwork/slab/cyborg/service //six scriptures, plus xray vision - quickbound = list(/datum/clockwork_scripture/abscond, /datum/clockwork_scripture/create_object/replicant,/datum/clockwork_scripture/create_object/stargazer, \ + quickbound = list(/datum/clockwork_scripture/spatial_gateway, /datum/clockwork_scripture/create_object/replicant,/datum/clockwork_scripture/create_object/stargazer, \ /datum/clockwork_scripture/spatial_gateway, /datum/clockwork_scripture/create_object/clockwork_obelisk) -/obj/item/clockwork/slab/cyborg/miner //two scriptures, plus a spear and xray vision - quickbound = list(/datum/clockwork_scripture/abscond, /datum/clockwork_scripture/ranged_ability/linked_vanguard, /datum/clockwork_scripture/spatial_gateway) +/obj/item/clockwork/slab/cyborg/miner //three scriptures, plus a spear and xray vision + quickbound = list(/datum/clockwork_scripture/spatial_gateway, /datum/clockwork_scripture/ranged_ability/linked_vanguard, /datum/clockwork_scripture/channeled/belligerent, /datum/clockwork_scripture/channeled/volt_blaster) /obj/item/clockwork/slab/cyborg/access_display(mob/living/user) if(!GLOB.ratvar_awakens) @@ -243,7 +245,7 @@ var/datum/clockwork_scripture/S = GLOB.all_scripture[s] if(S.tier == SCRIPTURE_PERIPHERAL) //yes, tiers are the tabs. continue - + var/list/data = list() data["name"] = S.name data["descname"] = S.descname @@ -254,13 +256,13 @@ data["quickbind"] = S.quickbind //this is if it cant quickbind data["fontcolor"] = get_component_color_bright(S.primary_component) data["important"] = S.important //italic! - + var/found = quickbound.Find(S.type) if(found) data["bound"] = found //number (pos) on where is it on the list if(S.invokers_required > 1) data["invokers"] = "Invokers: [S.invokers_required]" - + .["rec_binds"] = list() for(var/i in 1 to maximum_quickbound) if(GLOB.ratvar_awakens) @@ -270,10 +272,10 @@ else var/datum/clockwork_scripture/quickbind_slot = quickbound[i] .["rec_binds"] += list(list( - "name" = initial(quickbind_slot.name), + "name" = initial(quickbind_slot.name), "color" = get_component_color_bright(initial(quickbind_slot.primary_component)) )) - + .["scripture"][S.tier] += list(data) /obj/item/clockwork/slab/ui_static_data(mob/user) @@ -291,6 +293,10 @@ "requirement" = "Unlock these optional scriptures by converting another servant or if [DisplayPower(APPLICATION_UNLOCK_THRESHOLD)] of power is reached..", "ready" = SSticker.scripture_states[SCRIPTURE_APPLICATION] ) + .["tier_infos"][SCRIPTURE_JUDGEMENT] = list( + "requirement" = "Unlock powerful equipment and structures by converting five servants or if [DisplayPower(JUDGEMENT_UNLOCK_THRESHOLD)] of power is reached..", + "ready" = SSticker.scripture_states[SCRIPTURE_JUDGEMENT] + ) // .["selected"] = selected_scripture generate_all_scripture() @@ -363,4 +369,4 @@ Q.button_icon_state = quickbind_slot.name Q.UpdateButtonIcon() if(isliving(loc)) - Q.Grant(loc) + Q.Grant(loc) \ No newline at end of file diff --git a/code/modules/antagonists/clockcult/clock_items/construct_chassis.dm b/code/modules/antagonists/clockcult/clock_items/construct_chassis.dm index 7578d41b15..19c29762bf 100644 --- a/code/modules/antagonists/clockcult/clock_items/construct_chassis.dm +++ b/code/modules/antagonists/clockcult/clock_items/construct_chassis.dm @@ -31,8 +31,7 @@ . = ..() clockwork_desc = initial(clockwork_desc) -//ATTACK HAND IGNORING PARENT RETURN VALUE -/obj/item/clockwork/construct_chassis/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/item/clockwork/construct_chassis/on_attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) if(w_class >= WEIGHT_CLASS_HUGE) to_chat(user, "[src] is too cumbersome to carry! Drag it around instead!") return diff --git a/code/modules/antagonists/clockcult/clock_items/integration_cog.dm b/code/modules/antagonists/clockcult/clock_items/integration_cog.dm index 0ce70336fe..ab8e30c8bb 100644 --- a/code/modules/antagonists/clockcult/clock_items/integration_cog.dm +++ b/code/modules/antagonists/clockcult/clock_items/integration_cog.dm @@ -30,6 +30,7 @@ var/obj/item/stock_parts/cell/cell = apc.cell if(cell && (cell.charge / cell.maxcharge > COG_MAX_SIPHON_THRESHOLD)) cell.use(1) + apc.cog_drained++ adjust_clockwork_power(2) //Power is shared, so only do it once; this runs very quickly so it's about 10 W/second else adjust_clockwork_power(1) //Continue generating power when the cell has run dry; 5 W/second diff --git a/code/modules/antagonists/clockcult/clock_mobs/_eminence.dm b/code/modules/antagonists/clockcult/clock_mobs/_eminence.dm index faa5e025ca..2f6a018a4c 100644 --- a/code/modules/antagonists/clockcult/clock_mobs/_eminence.dm +++ b/code/modules/antagonists/clockcult/clock_mobs/_eminence.dm @@ -114,24 +114,27 @@ superheat_wall(A) return if(modifiers["middle"] || modifiers["ctrl"]) - issue_command(A) + INVOKE_ASYNC(src, .proc/issue_command, A) return if(GLOB.ark_of_the_clockwork_justiciar == A) var/obj/structure/destructible/clockwork/massive/celestial_gateway/G = GLOB.ark_of_the_clockwork_justiciar - if(G.recalling) - return - if(!G.recalls_remaining) - to_chat(src, "The Ark can no longer recall!") - return - if(alert(src, "Initiate mass recall?", "Mass Recall", "Yes", "No") != "Yes" || QDELETED(src) || QDELETED(G) || !G.obj_integrity) - return - G.initiate_mass_recall() //wHOOPS LOOKS LIKE A HULK GOT THROUGH + INVOKE_ASYNC(src, .proc/attempt_recall, G) else if(istype(A, /obj/structure/destructible/clockwork/trap/trigger)) var/obj/structure/destructible/clockwork/trap/trigger/T = A T.visible_message("[T] clunks as it's activated remotely.") to_chat(src, "You activate [T].") T.activate() +/mob/camera/eminence/proc/attempt_recall(obj/structure/destructible/clockwork/massive/celestial_gateway/G) + if(G.recalling) + return + if(!G.recalls_remaining) + to_chat(src, "The Ark can no longer recall!") + return + if(alert(src, "Initiate mass recall?", "Mass Recall", "Yes", "No") != "Yes" || QDELETED(src) || QDELETED(G) || !G.obj_integrity) + return + G.initiate_mass_recall() //wHOOPS LOOKS LIKE A HULK GOT THROUGH + /mob/camera/eminence/ratvar_act() name = "\improper Radiance" real_name = "\improper Radiance" diff --git a/code/modules/antagonists/clockcult/clock_mobs/clockwork_marauder.dm b/code/modules/antagonists/clockcult/clock_mobs/clockwork_marauder.dm index 3bc237fc56..79b919b1e9 100644 --- a/code/modules/antagonists/clockcult/clock_mobs/clockwork_marauder.dm +++ b/code/modules/antagonists/clockcult/clock_mobs/clockwork_marauder.dm @@ -124,3 +124,437 @@ #undef MARAUDER_SLOWDOWN_PERCENTAGE #undef MARAUDER_SHIELD_REGEN_TIME + +//Clockwork guardian: Slow but with high damage, resides inside of a servant. Created via the Memory Allocation scripture. +/mob/living/simple_animal/hostile/clockwork/marauder/guardian + name = "clockwork guardian" + desc = "A stalwart apparition of a soldier, blazing with crimson flames. It's armed with a gladius and shield and stands ready by its master." + icon_state = "clockwork_marauder" + health = 300 + maxHealth = 300 + speed = 1 + obj_damage = 40 + melee_damage_lower = 12 + melee_damage_upper = 12 + attack_verb_continuous = "slashes" + attack_verb_simple = "slash" + attack_sound = 'sound/weapons/bladeslice.ogg' + weather_immunities = list("lava") + movement_type = FLYING + AIStatus = AI_OFF //this has to be manually set so that the guardian doesn't start bashing the host, how annoying -_- + loot = list(/obj/item/clockwork/component/geis_capacitor/fallen_armor) + max_shield_health = 0 + shield_health = 0 + var/true_name = "Meme Master 69" //Required to call forth the guardian + var/global/list/possible_true_names = list("Servant", "Warden", "Serf", "Page", "Usher", "Knave", "Vassal", "Escort") + var/mob/living/host //The mob that the guardian is living inside of + var/recovering = FALSE //If the guardian is recovering from recalling + var/blockchance = 17 //chance to block attacks entirely + var/counterchance = 30 //chance to counterattack after blocking + var/static/list/damage_heal_order = list(OXY, BURN, BRUTE, TOX) //we heal our host's damage in this order + light_range = 2 + light_power = 1.1 + playstyle_string = "You are a clockwork guardian, a living extension of Sevtug's will. As a guardian, you are somewhat slow, but may block attacks, \ + and have a chance to also counter blocked melee attacks for extra damage, in addition to being immune to extreme temperatures and pressures. \ + Your primary goal is to serve the creature that you are now a part of, as well as The Clockwork Justiciar, Ratvar. You can use The Hierophant Network to communicate silently with your master and their allies, \ + but can only exit if your master calls your true name or if they are exceptionally damaged. \ + \n\n\ + Stay near your host to protect and heal them; being too far from your host will rapidly cause you massive damage. Recall to your host if you are too weak and believe you cannot continue \ + fighting safely. As a final note, you should probably avoid harming any fellow servants of Ratvar." + +/mob/living/simple_animal/hostile/clockwork/marauder/guardian/Initialize() + . = ..() + true_name = pick(possible_true_names) + +/mob/living/simple_animal/hostile/clockwork/marauder/guardian/BiologicalLife(seconds, times_fired) + ..() + if(is_in_host()) + if(!is_servant_of_ratvar(host)) + emerge_from_host(FALSE, TRUE) + unbind_from_host() + return + if(!GLOB.ratvar_awakens && host.stat == DEAD) + death() + return + if(GLOB.ratvar_awakens) + adjustHealth(-50) + else + adjustHealth(-10) + if(!recovering) + heal_host() //also heal our host if inside of them and we aren't recovering + else if(health == maxHealth) + to_chat(src, "Your strength has returned. You can once again come forward!") + to_chat(host, "Your guardian is now strong enough to come forward again!") + recovering = FALSE + else + if(GLOB.ratvar_awakens) //If Ratvar is alive, guardians don't need a host and are downright impossible to kill + adjustHealth(-5) + heal_host() + else if(host) + if(!is_servant_of_ratvar(host)) + unbind_from_host() + return + if(host.stat == DEAD) + adjustHealth(50) + to_chat(src, "Your host is dead!") + return + if(z && host.z && z == host.z) + switch(get_dist(get_turf(src), get_turf(host))) + if(2) + adjustHealth(-1) + if(3) + //EQUILIBRIUM + if(4) + adjustHealth(1) + if(5) + adjustHealth(3) + if(6) + adjustHealth(6) + if(7) + adjustHealth(9) + if(8 to INFINITY) + adjustHealth(15) + to_chat(src, "You're too far from your host and rapidly taking damage!") + else //right next to or on top of host + adjustHealth(-2) + heal_host() //gradually heal host if nearby and host is very weak + else //well then, you're not even in the same zlevel + adjustHealth(15) + to_chat(src, "You're too far from your host and rapidly taking damage!") + +/mob/living/simple_animal/hostile/clockwork/marauder/guardian/death(gibbed) + emerge_from_host(FALSE, TRUE) + unbind_from_host() + visible_message("[src]'s equipment clatters lifelessly to the ground as the red flames within dissipate.", \ + "Your equipment falls away. You feel a moment of confusion before your fragile form is annihilated.") + . = ..() + +/mob/living/simple_animal/hostile/clockwork/marauder/guardian/Stat() + ..() + if(statpanel("Status")) + stat(null, "Current True Name: [true_name]") + stat(null, "Host: [host ? host : "NONE"]") + if(host) + var/resulthealth = round((host.health / host.maxHealth) * 100, 0.5) + if(iscarbon(host)) + resulthealth = round((abs(HEALTH_THRESHOLD_DEAD - host.health) / abs(HEALTH_THRESHOLD_DEAD - host.maxHealth)) * 100) + stat(null, "Host Health: [resulthealth]%") + if(GLOB.ratvar_awakens) + stat(null, "You are [recovering ? "un" : ""]able to deploy!") + else + if(resulthealth > GUARDIAN_EMERGE_THRESHOLD) + stat(null, "You are [recovering ? "unable to deploy" : "able to deploy on hearing your True Name"]!") + else + stat(null, "You are [recovering ? "unable to deploy" : "able to deploy to protect your host"]!") + stat(null, "You do [melee_damage_upper] damage on melee attacks.") + +/mob/living/simple_animal/hostile/clockwork/marauder/guardian/Process_Spacemove(movement_dir = 0) + return 1 + +/mob/living/simple_animal/hostile/clockwork/marauder/guardian/proc/bind_to_host(mob/living/new_host) + if(!new_host) + return FALSE + host = new_host + var/datum/action/innate/summon_guardian/SG = new() + SG.linked_guardian = src + SG.Grant(host) + var/datum/action/innate/linked_minds/LM = new() + LM.linked_guardian = src + LM.Grant(host) + return TRUE + +/mob/living/simple_animal/hostile/clockwork/marauder/guardian/proc/unbind_from_host() + if(host) + for(var/datum/action/innate/summon_guardian/SG in host.actions) + qdel(SG) + for(var/datum/action/innate/linked_minds/LM in host.actions) + qdel(LM) + host = null + return TRUE + return FALSE + +//DAMAGE and FATIGUE +/mob/living/simple_animal/hostile/clockwork/marauder/guardian/proc/heal_host() + if(!host) + return + var/resulthealth = round((host.health / host.maxHealth) * 100, 0.5) + if(iscarbon(host)) + resulthealth = round((abs(HEALTH_THRESHOLD_DEAD - host.health) / abs(HEALTH_THRESHOLD_DEAD - host.maxHealth)) * 100) + if(GLOB.ratvar_awakens || resulthealth <= GUARDIAN_EMERGE_THRESHOLD) + new /obj/effect/temp_visual/heal(host.loc, "#AF0AAF") + host.heal_ordered_damage(4, damage_heal_order) + +/mob/living/simple_animal/hostile/clockwork/marauder/guardian/adjustHealth(amount, updating_health = TRUE, forced = FALSE) + if(amount > 0) + for(var/mob/living/L in view(2, src)) + if(L.is_holding_item_of_type(/obj/item/nullrod)) + to_chat(src, "The presence of a brandished holy artifact weakens your armor!") + amount *= 4 //if a wielded null rod is nearby, it takes four times the health damage + break + . = ..() + if(src && updating_health) + update_health_hud() + update_stats() + +/mob/living/simple_animal/hostile/clockwork/marauder/guardian/update_health_hud() + if(hud_used && hud_used.healths) + if(istype(hud_used, /datum/hud/marauder)) + var/datum/hud/marauder/G = hud_used + var/resulthealth + if(host) + if(iscarbon(host)) + resulthealth = "[round((abs(HEALTH_THRESHOLD_DEAD - host.health) / abs(HEALTH_THRESHOLD_DEAD - host.maxHealth)) * 100)]%" + else + resulthealth = "[round((host.health / host.maxHealth) * 100, 0.5)]%" + else + resulthealth = "NONE" + G.hosthealth.maptext = "
    HOST
    [resulthealth]
    " + hud_used.healths.maptext = "
    [round((health / maxHealth) * 100, 0.5)]%" + +/mob/living/simple_animal/hostile/clockwork/marauder/guardian/proc/update_stats() + if(GLOB.ratvar_awakens) + speed = 0 + melee_damage_lower = 20 + melee_damage_upper = 20 + attack_verb_continuous = "devastates" + else + var/healthpercent = (health/maxHealth) * 100 + switch(healthpercent) + if(100 to 70) //Bonuses to speed and damage at high health + speed = 0 + melee_damage_lower = 16 + melee_damage_upper = 16 + attack_verb_continuous = "viciously slashes" + if(70 to 40) + speed = initial(speed) + melee_damage_lower = initial(melee_damage_lower) + melee_damage_upper = initial(melee_damage_upper) + attack_verb_continuous = initial(attack_verb_continuous) + if(40 to 30) //Damage decrease, but not speed + speed = initial(speed) + melee_damage_lower = 10 + melee_damage_upper = 10 + attack_verb_continuous = "lightly slashes" + if(30 to 20) //Speed decrease + speed = 2 + melee_damage_lower = 8 + melee_damage_upper = 8 + attack_verb_continuous = "lightly slashes" + if(20 to 10) //Massive speed decrease and weak melee attacks + speed = 3 + melee_damage_lower = 6 + melee_damage_upper = 6 + attack_verb_continuous = "weakly slashes" + if(10 to 0) //We are super weak and going to die + speed = 4 + melee_damage_lower = 4 + melee_damage_upper = 4 + attack_verb_continuous = "taps" + +//ATTACKING, BLOCKING, and COUNTERING + +/mob/living/simple_animal/hostile/clockwork/marauder/guardian/AttackingTarget() + if(is_in_host()) + return FALSE + return ..() + +/mob/living/simple_animal/hostile/clockwork/marauder/guardian/bullet_act(obj/item/projectile/Proj) + if(blockOrCounter(null, Proj)) + return + return ..() + +/mob/living/simple_animal/hostile/clockwork/marauder/guardian/hitby(atom/movable/AM, skipcatch, hitpush, blocked, atom/movable/AM, datum/thrownthing/throwingdatum) + if(blockOrCounter(null, AM)) + return + return ..() + +/mob/living/simple_animal/hostile/clockwork/marauder/guardian/attack_animal(mob/living/simple_animal/M) + if(istype(M, /mob/living/simple_animal/hostile/clockwork/marauder/guardian) || !blockOrCounter(M, M)) //we don't want infinite blockcounter loops if fighting another guardian + return ..() + +/mob/living/simple_animal/hostile/clockwork/marauder/guardian/attack_paw(mob/living/carbon/monkey/M) + if(!blockOrCounter(M, M)) + return ..() + +/mob/living/simple_animal/hostile/clockwork/marauder/guardian/attack_alien(mob/living/carbon/alien/humanoid/M) + if(!blockOrCounter(M, M)) + return ..() + +/mob/living/simple_animal/hostile/clockwork/marauder/guardian/attack_slime(mob/living/simple_animal/slime/M) + if(!blockOrCounter(M, M)) + return ..() + +/mob/living/simple_animal/hostile/clockwork/marauder/guardian/attack_hand(mob/living/carbon/human/M) + if(!blockOrCounter(M, M)) + return ..() + +/mob/living/simple_animal/hostile/clockwork/marauder/guardian/attackby(obj/item/I, mob/user, params) + if(istype(I, /obj/item/nullrod) || !blockOrCounter(user, I)) + return ..() + +/mob/living/simple_animal/hostile/clockwork/marauder/guardian/proc/blockOrCounter(mob/target, atom/textobject) + if(GLOB.ratvar_awakens) //if ratvar has woken, we block nearly everything at a very high chance + blockchance = 90 + counterchance = 90 + if(prob(blockchance)) + . = TRUE + if(target) + target.do_attack_animation(src) + target.DelayNextAction(CLICK_CD_MELEE) + blockchance = initial(blockchance) + playsound(src, 'sound/magic/clockwork/fellowship_armory.ogg', 30, 1, 0, 1) //clang + visible_message("[src] blocks [target && isitem(textobject) ? "[target]'s [textobject.name]":"\the [textobject]"]!", \ + "You block [target && isitem(textobject) ? "[target]'s [textobject.name]":"\the [textobject]"]!") + if(target && Adjacent(target)) + if(prob(counterchance)) + counterchance = initial(counterchance) + var/previousattack_verb_continuous = attack_verb_continuous + attack_verb_continuous = "counters" + UnarmedAttack(target) + attack_verb_continuous = previousattack_verb_continuous + else + counterchance = min(counterchance + initial(counterchance), 100) + else + blockchance = min(blockchance + initial(blockchance), 100) + if(GLOB.ratvar_awakens) + blockchance = 90 + counterchance = 90 + +//COMMUNICATION and EMERGENCE +/* +/mob/living/simple_animal/hostile/clockwork/marauder/guardian/handle_inherent_channels(message, message_mode) + if(host && (is_in_host() || message_mode == MODE_BINARY)) + guardian_comms(message) + return TRUE + return ..() +*/ +/mob/living/simple_animal/hostile/clockwork/marauder/guardian/proc/guardian_comms(message) + var/name_part = "[src] ([true_name])" + message = "\"[message]\"" //Processed output + to_chat(src, "[name_part]: [message]") + to_chat(host, "[name_part]: [message]") + for(var/M in GLOB.mob_list) + if(isobserver(M)) + var/link = FOLLOW_LINK(M, src) + to_chat(M, "[link] [name_part] (to [findtextEx(host.name, host.real_name) ? "[host.name]" : "[host.real_name] (as [host.name])"]): [message] ") + return TRUE + +/mob/living/simple_animal/hostile/clockwork/marauder/guardian/proc/return_to_host() + if(is_in_host()) + return FALSE + if(!host) + to_chat(src, "You don't have a host!") + return FALSE + var/resulthealth = round((host.health / host.maxHealth) * 100, 0.5) + if(iscarbon(host)) + resulthealth = round((abs(HEALTH_THRESHOLD_DEAD - host.health) / abs(HEALTH_THRESHOLD_DEAD - host.maxHealth)) * 100) + host.visible_message("[host]'s skin flashes crimson!", "You feel [true_name]'s consciousness settle in your mind.") + visible_message("[src] suddenly disappears!", "You return to [host].") + forceMove(host) + if(resulthealth > GUARDIAN_EMERGE_THRESHOLD && health != maxHealth) + recovering = TRUE + to_chat(src, "You have weakened and will need to recover before manifesting again!") + to_chat(host, "[true_name] has weakened and will need to recover before manifesting again!") + return TRUE + +/mob/living/simple_animal/hostile/clockwork/marauder/guardian/proc/try_emerge() + if(!host) + to_chat(src, "You don't have a host!") + return FALSE + if(!GLOB.ratvar_awakens) + var/resulthealth = round((host.health / host.maxHealth) * 100, 0.5) + if(iscarbon(host)) + resulthealth = round((abs(HEALTH_THRESHOLD_DEAD - host.health) / abs(HEALTH_THRESHOLD_DEAD - host.maxHealth)) * 100) + if(host.stat != DEAD && resulthealth > GUARDIAN_EMERGE_THRESHOLD) //if above 20 health, fails + to_chat(src, "Your host must be at [GUARDIAN_EMERGE_THRESHOLD]% or less health to emerge like this!") + return FALSE + return emerge_from_host(FALSE) + +/mob/living/simple_animal/hostile/clockwork/marauder/guardian/proc/emerge_from_host(hostchosen, force) //Notice that this is a proc rather than a verb - guardians can NOT exit at will, but they CAN return + if(!is_in_host()) + return FALSE + if(!force && recovering) + if(hostchosen) + to_chat(host, "[true_name] is too weak to come forth!") + else + to_chat(host, "[true_name] tries to emerge to protect you, but it's too weak!") + to_chat(src, "You try to come forth, but you're too weak!") + return FALSE + if(!force) + if(hostchosen) //guardian approved + to_chat(host, "Your words echo with power as [true_name] emerges from your body!") + else + to_chat(host, "[true_name] emerges from your body to protect you!") + forceMove(host.loc) + visible_message("[host]'s skin glows red as [name] emerges from their body!", "You exit the safety of [host]'s body!") + return TRUE + +/mob/living/simple_animal/hostile/clockwork/marauder/guardian/get_alt_name() + return " ([text2ratvar(true_name)])" + +/mob/living/simple_animal/hostile/clockwork/marauder/guardian/proc/is_in_host() //Checks if the guardian is inside of their host + return host && loc == host + +//HOST ACTIONS + +//Summon guardian action: Calls forth or recalls your guardian +/datum/action/innate/summon_guardian + name = "Force Guardian to Emerge/Recall" + desc = "Allows you to force your clockwork guardian to emerge or recall as required." + button_icon_state = "clockwork_marauder" + background_icon_state = "bg_clock" + check_flags = AB_CHECK_CONSCIOUS + buttontooltipstyle = "clockcult" + var/mob/living/simple_animal/hostile/clockwork/marauder/guardian/linked_guardian + var/list/defend_phrases = list("Defend me", "Come forth", "Assist me", "Protect me", "Give aid", "Help me") + var/list/return_phrases = list("Return", "Return to me", "Your job is done", "You have served", "Come back", "Retreat") + +/datum/action/innate/summon_guardian/IsAvailable() + if(!linked_guardian) + return FALSE + if(isliving(owner)) + var/mob/living/L = owner + if(!L.can_speak_vocal() || L.stat) + return FALSE + return ..() + +/datum/action/innate/summon_guardian/Activate() + if(linked_guardian.is_in_host()) + clockwork_say(owner, text2ratvar("[pick(defend_phrases)], [linked_guardian.true_name]!")) + linked_guardian.emerge_from_host(TRUE) + else + clockwork_say(owner, text2ratvar("[pick(return_phrases)], [linked_guardian.true_name]!")) + linked_guardian.return_to_host() + return TRUE + +//Linked Minds action: talks to your guardian +/datum/action/innate/linked_minds + name = "Linked Minds" + desc = "Allows you to silently communicate with your guardian." + button_icon_state = "linked_minds" + background_icon_state = "bg_clock" + check_flags = AB_CHECK_CONSCIOUS + buttontooltipstyle = "clockcult" + var/mob/living/simple_animal/hostile/clockwork/marauder/guardian/linked_guardian + +/datum/action/innate/linked_minds/IsAvailable() + if(!linked_guardian) + return FALSE + return ..() + +/datum/action/innate/linked_minds/Activate() + var/message = stripped_input(owner, "Enter a message to tell your guardian.", "Telepathy") + if(!owner || !message) + return FALSE + if(!linked_guardian) + to_chat(owner, "Your guardian seems to have been destroyed!") + return FALSE + var/name_part = "Servant [findtextEx(owner.name, owner.real_name) ? "[owner.name]" : "[owner.real_name] (as [owner.name])"]" + message = "\"[message]\"" //Processed output + to_chat(owner, "[name_part]: [message]") + to_chat(linked_guardian, "[name_part]: [message]") + for(var/M in GLOB.mob_list) + if(isobserver(M)) + var/link = FOLLOW_LINK(M, src) + to_chat(M, "[link] [name_part] (to [linked_guardian] ([linked_guardian.true_name])): [message]") + return TRUE diff --git a/code/modules/antagonists/clockcult/clock_scripture.dm b/code/modules/antagonists/clockcult/clock_scripture.dm index 1ebefe4d05..a85245e9d0 100644 --- a/code/modules/antagonists/clockcult/clock_scripture.dm +++ b/code/modules/antagonists/clockcult/clock_scripture.dm @@ -3,8 +3,9 @@ Tiers and Requirements Pieces of scripture require certain follower counts, contruction value, and active caches in order to recite. Drivers: Unlocked by default -Scripts: 5 servants and a cache -Applications: 8 servants, 3 caches, and 100 CV +Scripts: 35k power or one convert +Applications: 50k or three converts +Judgement 5 converts */ /datum/clockwork_scripture @@ -129,11 +130,11 @@ Applications: 8 servants, 3 caches, and 100 CV SEND_SOUND(invoker, sound('sound/magic/clockwork/invoke_general.ogg')) return TRUE -/datum/clockwork_scripture/proc/check_offstation_penalty() +/datum/clockwork_scripture/proc/check_offstation_penalty()//don't cast spells away from the station var/turf/T = get_turf(invoker) if(!T || (!is_centcom_level(T.z) && !is_station_level(T.z) && !is_mining_level(T.z) && !is_reebe(T.z))) - channel_time *= 2 - power_cost *= 2 + channel_time *= 3 + power_cost *= 3 return TRUE /datum/clockwork_scripture/proc/check_special_requirements() //Special requirements for scriptures, checked multiple times during invocation diff --git a/code/modules/antagonists/clockcult/clock_scriptures/scripture_applications.dm b/code/modules/antagonists/clockcult/clock_scriptures/scripture_applications.dm index ffe9ecfa80..cbf3bdaa38 100644 --- a/code/modules/antagonists/clockcult/clock_scriptures/scripture_applications.dm +++ b/code/modules/antagonists/clockcult/clock_scriptures/scripture_applications.dm @@ -1,5 +1,5 @@ ////////////////// -// APPLICATIONS // +// APPLICATIONS // For various structures and base building, as well as advanced power generation. ////////////////// @@ -23,6 +23,37 @@ quickbind = TRUE quickbind_desc = "Creates a Sigil of Transmission, which can drain and will store power for clockwork structures." +//Prolonging Prism: Creates a prism that will delay the shuttle at a power cost +/datum/clockwork_scripture/create_object/prolonging_prism + descname = "Powered Structure, Delay Emergency Shuttles" + name = "Prolonging Prism" + desc = "Creates a mechanized prism which will delay the arrival of an emergency shuttle by 2 minutes at a massive power cost." + invocations = list("May this prism...", "...grant us time to enact his will!") + channel_time = 80 + power_cost = 300 + object_path = /obj/structure/destructible/clockwork/powered/prolonging_prism + creator_message = "You form a prolonging prism, which will delay the arrival of an emergency shuttle at a massive power cost." + observer_message = "An onyx prism forms in midair and sprouts tendrils to support itself!" + invokers_required = 2 + multiple_invokers_used = TRUE + usage_tip = "The power cost to delay a shuttle increases based on the number of times activated." + tier = SCRIPTURE_APPLICATION + one_per_tile = TRUE + primary_component = VANGUARD_COGWHEEL + sort_priority = 4 + important = TRUE + quickbind = TRUE + quickbind_desc = "Creates a Prolonging Prism, which will delay the arrival of an emergency shuttle by 2 minutes at a massive power cost." + +/datum/clockwork_scripture/create_object/prolonging_prism/check_special_requirements() + if(SSshuttle.emergency.mode == SHUTTLE_DOCKED || SSshuttle.emergency.mode == SHUTTLE_IGNITING || SSshuttle.emergency.mode == SHUTTLE_STRANDED || SSshuttle.emergency.mode == SHUTTLE_ESCAPE) + to_chat(invoker, "\"It is too late to construct one of these, champion.\"") + return FALSE + var/turf/T = get_turf(invoker) + if(!T || !is_station_level(T.z)) + to_chat(invoker, "\"You must be on the station to construct one of these, champion.\"") + return FALSE + return ..() //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 @@ -44,6 +75,7 @@ sort_priority = 2 quickbind = TRUE quickbind_desc = "Creates a Mania Motor, which causes minor damage and negative mental effects in non-Servants." + requires_full_power = TRUE //Clockwork Obelisk: Creates a powerful obelisk that can be used to broadcast messages or open a gateway to any servant or clockwork obelisk at a power cost. @@ -67,6 +99,64 @@ quickbind = TRUE quickbind_desc = "Creates a Clockwork Obelisk, which can send messages or open Spatial Gateways with power." +//Memory Allocation: Finds a willing ghost and makes them into a clockwork guardian for the invoker. +/datum/clockwork_scripture/memory_allocation + descname = "Personal Guardian, A Peice Of Your Mind." + name = "Memory Allocation" + desc = "Allocates part of your consciousness to a Clockwork Guardian, a variant of Marauder that lives within you, able to be \ + called forth by Speaking its True Name or if you become exceptionally low on health.
    \ + If it remains close to you, you will gradually regain health up to a low amount, but it will die if it goes too far from you." + invocations = list("Fright's will...", "...call forth...") + channel_time = 100 + power_cost = 8000 + usage_tip = "guardians are useful as personal bodyguards and frontline warriors." + tier = SCRIPTURE_APPLICATION + primary_component = GEIS_CAPACITOR + sort_priority = 5 + +/datum/clockwork_scripture/memory_allocation/check_special_requirements() + for(var/mob/living/simple_animal/hostile/clockwork/marauder/guardian/M in GLOB.all_clockwork_mobs) + if(M.host == invoker) + to_chat(invoker, "You can only house one guardian at a time!") + return FALSE + return TRUE + +/datum/clockwork_scripture/memory_allocation/scripture_effects() + return create_guardian() + +/datum/clockwork_scripture/memory_allocation/proc/create_guardian() + invoker.visible_message("A purple tendril appears from [invoker]'s [slab.name] and impales itself in [invoker.p_their()] forehead!", \ + "A tendril flies from [slab] into your forehead. You begin waiting while it painfully rearranges your thought pattern...") + //invoker.notransform = TRUE //Vulnerable during the process + slab.busy = "Thought Modification in progress" + if(!do_after(invoker, 50, target = invoker)) + invoker.visible_message("The tendril, covered in blood, retracts from [invoker]'s head and back into the [slab.name]!", \ + "Total agony overcomes you as the tendril is forced out early!") + invoker.Knockdown(100) + invoker.apply_damage(50, BRUTE, "head")//Sevtug leaves a gaping hole in your face if interrupted. + slab.busy = null + return FALSE + clockwork_say(invoker, text2ratvar("...the mind made...")) + //invoker.notransform = FALSE + slab.busy = "Guardian Selection in progress" + if(!check_special_requirements()) + return FALSE + to_chat(invoker, "The tendril shivers slightly as it selects a guardian...") + var/list/marauder_candidates = pollGhostCandidates("Do you want to play as the clockwork guardian of [invoker.real_name]?", ROLE_SERVANT_OF_RATVAR, null, FALSE, 50, POLL_IGNORE_HOLOPARASITE) + if(!check_special_requirements()) + return FALSE + if(!marauder_candidates.len) + invoker.visible_message("The tendril retracts from [invoker]'s head, sealing the entry wound as it does so!", \ + "The tendril was unsuccessful! Perhaps you should try again another time.") + return FALSE + clockwork_say(invoker, text2ratvar("...sword and shield!")) + var/mob/dead/observer/theghost = pick(marauder_candidates) + var/mob/living/simple_animal/hostile/clockwork/marauder/guardian/M = new(invoker) + M.key = theghost.key + M.bind_to_host(invoker) + invoker.visible_message("The tendril retracts from [invoker]'s head, sealing the entry wound as it does so!", \ + "[M.true_name], a clockwork guardian, has taken up residence in your mind. Communicate with it via the \"Linked Minds\" action button.") + return TRUE //Clockwork Marauder: Creates a construct shell for a clockwork marauder, a well-rounded frontline fighter. /datum/clockwork_scripture/create_object/construct/clockwork_marauder @@ -81,7 +171,7 @@ tier = SCRIPTURE_APPLICATION one_per_tile = TRUE primary_component = BELLIGERENT_EYE - sort_priority = 4 + sort_priority = 6 quickbind = TRUE quickbind_desc = "Creates a clockwork marauder, used for frontline combat." object_path = /obj/item/clockwork/construct_chassis/clockwork_marauder @@ -117,14 +207,13 @@ /datum/clockwork_scripture/create_object/summon_arbiter descname = "Powerful Assault Mech" name = "Summon Neovgre, the Anima Bulwark" - desc = "Calls forth the mighty Anima Bulwark, a weapon of unmatched power,\ - mech with superior defensive and offensive capabilities. It will \ + desc = "Calls forth the mighty Anima Bulwark, a mech with superior defensive and offensive capabilities. It will \ steadily regenerate HP and triple its regeneration speed while standing \ on a clockwork tile. It will automatically draw power from nearby sigils of \ transmission should the need arise. Its Arbiter laser cannon can decimate foes \ from a range and is capable of smashing through any barrier presented to it. \ - Be warned, choosing to pilot Neovgre is a lifetime commitment, once you are \ - in you cannot leave and when it is destroyed it will explode catastrophically with you inside." + Be warned however, choosing to pilot Neovgre is a lifetime commitment, once you are \ + in you cannot leave and when it is destroyed it will explode catastrophically, with you inside." invocations = list("By the strength of the alloy...!!", "...call forth the Arbiter!!") channel_time = 200 // This is a strong fucking weapon, 20 seconds channel time is getting off light I tell ya. power_cost = 75000 //75 KW @@ -134,7 +223,7 @@ object_path = /obj/mecha/combat/neovgre tier = SCRIPTURE_APPLICATION primary_component = BELLIGERENT_EYE - sort_priority = 2 + sort_priority = 7 creator_message = "Neovgre, the Anima Bulwark towers over you... your enemies reckoning has come." /datum/clockwork_scripture/create_object/summon_arbiter/check_special_requirements() diff --git a/code/modules/antagonists/clockcult/clock_scriptures/scripture_cyborg.dm b/code/modules/antagonists/clockcult/clock_scriptures/scripture_cyborg.dm index 819dfac72e..3dacecf6b4 100644 --- a/code/modules/antagonists/clockcult/clock_scriptures/scripture_cyborg.dm +++ b/code/modules/antagonists/clockcult/clock_scriptures/scripture_cyborg.dm @@ -1,5 +1,5 @@ ///////////////// -// CYBORG ONLY // +// CYBORG ONLY // Cyborgs only, fleshed ones. ///////////////// //Linked Vanguard: grants Vanguard to the invoker and a target diff --git a/code/modules/antagonists/clockcult/clock_scriptures/scripture_drivers.dm b/code/modules/antagonists/clockcult/clock_scriptures/scripture_drivers.dm index 6349ecb581..c4b1913832 100644 --- a/code/modules/antagonists/clockcult/clock_scriptures/scripture_drivers.dm +++ b/code/modules/antagonists/clockcult/clock_scriptures/scripture_drivers.dm @@ -1,5 +1,5 @@ ///////////// -// DRIVERS // +// DRIVERS // Starter spells ///////////// //Stargazer: Creates a stargazer, a cheap power generator that utilizes starlight. @@ -97,7 +97,7 @@ desc = "Charges your slab with divine energy, allowing you to overwhelm a target with Ratvar's light." invocations = list("Divinity, show them your light!") whispered = TRUE - channel_time = 20 // I think making kindle channel a third of the time less is a good make up for the fact that it silences people for such a little amount of time. + channel_time = 10 // I think making kindle channel a third of the time less is a good make up for the fact that it silences people for such a little amount of time. power_cost = 125 usage_tip = "The light can be used from up to two tiles away. Damage taken will GREATLY REDUCE the stun's duration." tier = SCRIPTURE_DRIVER @@ -113,7 +113,6 @@ quickbind = TRUE quickbind_desc = "Stuns and mutes a target from a short range." - //Hateful Manacles: Applies restraints from melee over several seconds. The restraints function like handcuffs and break on removal. /datum/clockwork_scripture/ranged_ability/hateful_manacles descname = "Handcuffs" @@ -192,43 +191,39 @@ Click your slab to cancel.
    " +/*//commenting this out until its reworked to actually do random teleports //Abscond: Used to return to Reebe. /datum/clockwork_scripture/abscond - descname = "Return to Reebe" + descname = "Safety warp, teleports you somewhere random. moderately high power cost to use." name = "Abscond" - desc = "Yanks you through space, returning you to home base." + desc = "Yanks you through space, putting you in hopefully a safe location." invocations = list("As we bid farewell, and return to the stars...", "...we shall find our way home.") whispered = TRUE - channel_time = 50 - power_cost = 5 - special_power_text = "POWERCOST to bring pulled creature" - special_power_cost = ABSCOND_ABDUCTION_COST + channel_time = 3.5 + power_cost = 10000 usage_tip = "This can't be used while on Reebe, for obvious reasons." tier = SCRIPTURE_DRIVER primary_component = GEIS_CAPACITOR sort_priority = 9 important = TRUE quickbind = TRUE - quickbind_desc = "Returns you to Reebe." + quickbind_desc = "Teleports you somewhere random, or to an active Ark if one exists. Use in emergencies." var/client_color requires_full_power = TRUE /datum/clockwork_scripture/abscond/check_special_requirements() if(is_reebe(invoker.z)) - to_chat(invoker, "You're already at Reebe.") + to_chat(invoker, "You're at Reebe, attempting to warp in the void could cause you to share your masters fate of banishment!.") return if(!isturf(invoker.loc)) - to_chat(invoker, "You must be visible to return!") + to_chat(invoker, "You must be visible to warp!") return return TRUE /datum/clockwork_scripture/abscond/recital() - client_color = invoker.client.color - animate(invoker.client, color = "#AF0AAF", time = 50) . = ..() /datum/clockwork_scripture/abscond/scripture_effects() - var/mob/living/pulled_mob = (invoker.pulling && isliving(invoker.pulling) && get_clockwork_power(ABSCOND_ABDUCTION_COST)) ? invoker.pulling : null var/turf/T if(GLOB.ark_of_the_clockwork_justiciar) T = get_step(GLOB.ark_of_the_clockwork_justiciar, SOUTH) @@ -237,21 +232,12 @@ if(!do_teleport(invoker, T, channel = TELEPORT_CHANNEL_CULT, forced = TRUE)) return invoker.visible_message("[invoker] flickers and phases out of existence!", \ - "You feel a dizzying sense of vertigo as you're yanked back to Reebe!") + "You feel a dizzying sense of vertigo as you're yanked through the fabric of reality!") T.visible_message("[invoker] flickers and phases into existence!") playsound(invoker, 'sound/magic/magic_missile.ogg', 50, TRUE) playsound(T, 'sound/magic/magic_missile.ogg', 50, TRUE) do_sparks(5, TRUE, invoker) - do_sparks(5, TRUE, T) - if(pulled_mob && do_teleport(pulled_mob, T, channel = TELEPORT_CHANNEL_CULT, forced = TRUE)) - adjust_clockwork_power(-special_power_cost) - invoker.start_pulling(pulled_mob) //forcemove resets pulls, so we need to re-pull - if(invoker.client) - animate(invoker.client, color = client_color, time = 25) - -/datum/clockwork_scripture/abscond/scripture_fail() - if(invoker && invoker.client) - animate(invoker.client, color = client_color, time = 10) + do_sparks(5, TRUE, T)*/ //Replicant: Creates a new clockwork slab. @@ -265,7 +251,7 @@ whispered = TRUE object_path = /obj/item/clockwork/slab creator_message = "You copy a piece of replicant alloy and command it into a new slab." - usage_tip = "This is inefficient as a way to produce components, as the slab produced must be held by someone with no other slabs to produce components." + usage_tip = "This is inefficient as a way to produce power, as the slab produced must be held by someone with no other slabs to produce any." tier = SCRIPTURE_DRIVER space_allowed = TRUE primary_component = GEIS_CAPACITOR @@ -293,3 +279,50 @@ sort_priority = 11 quickbind = TRUE quickbind_desc = "Creates a pair of Wraith Spectacles, which grant true sight but cause gradual vision loss." + +//Spatial Gateway: Allows the invoker to teleport themselves and any nearby allies to a conscious servant or clockwork obelisk. +/datum/clockwork_scripture/spatial_gateway + descname = "Teleport Gate" + name = "Spatial Gateway" + desc = "Tears open a miniaturized gateway in spacetime to any conscious servant that can transport objects or creatures to its destination. \ + Each servant assisting in the invocation adds one additional use and four additional seconds to the gateway's uses and duration." + invocations = list("Spatial Gateway...", "...activate!") + channel_time = 30 + power_cost = 400 + whispered = TRUE + multiple_invokers_used = TRUE + multiple_invokers_optional = TRUE + usage_tip = "This gateway is strictly one-way and will only allow things through the invoker's portal." + tier = SCRIPTURE_DRIVER + primary_component = GEIS_CAPACITOR + sort_priority = 9 + quickbind = TRUE + quickbind_desc = "Allows you to create a one-way Spatial Gateway to a living Servant or Clockwork Obelisk." + +/datum/clockwork_scripture/spatial_gateway/check_special_requirements() + if(!isturf(invoker.loc)) + to_chat(invoker, "You must not be inside an object to use this scripture!") + return FALSE + var/other_servants = 0 + for(var/mob/living/L in GLOB.alive_mob_list) + if(is_servant_of_ratvar(L) && !L.stat && L != invoker) + other_servants++ + for(var/obj/structure/destructible/clockwork/powered/clockwork_obelisk/O in GLOB.all_clockwork_objects) + if(O.anchored) + other_servants++ + if(!other_servants) + to_chat(invoker, "There are no other conscious servants or anchored clockwork obelisks!") + return FALSE + return TRUE + +/datum/clockwork_scripture/spatial_gateway/scripture_effects() + var/portal_uses = 0 + var/duration = 0 + for(var/mob/living/L in range(1, invoker)) + if(!L.stat && is_servant_of_ratvar(L)) + portal_uses++ + duration += 40 //4 seconds + if(GLOB.ratvar_awakens) + portal_uses = max(portal_uses, 100) //Very powerful if Ratvar has been summoned + duration = max(duration, 100) + return slab.procure_gateway(invoker, duration, portal_uses) \ No newline at end of file diff --git a/code/modules/antagonists/clockcult/clock_scriptures/scripture_judgement.dm b/code/modules/antagonists/clockcult/clock_scriptures/scripture_judgement.dm new file mode 100644 index 0000000000..5075840e76 --- /dev/null +++ b/code/modules/antagonists/clockcult/clock_scriptures/scripture_judgement.dm @@ -0,0 +1,44 @@ +/////////////// +// JUDGEMENT // For the big game changing things. TODO: Summonable generals, just need mob sprites for them. +/////////////// + +//Ark of the Clockwork Justiciar: Creates a Gateway to the Celestial Derelict, summoning ratvar. +/datum/clockwork_scripture/create_object/ark_of_the_clockwork_justiciar + descname = "Structure, Win Condition" + name = "Ark of the Clockwork Justiciar" + desc = "Tears apart a rift in spacetime to Reebe, the Celestial Derelict, using a massive amount of power.\n\ + This gateway will, after some time, call forth Ratvar from his exile and massively empower all scriptures and tools." + invocations = list("ARMORER! FRIGHT! AMPERAGE! VANGUARD! WE CALL UPON YOU!!", \ + "THE TIME HAS COME FOR OUR MASTER TO BREAK THE CHAINS OF EXILE!!", \ + "LEND US YOUR AID! ENGINE COMES!!") + channel_time = 150 + power_cost = 70000 //70 KW. It's literally the thing wrenching the god out of another dimension why wouldn't it be costly. + invokers_required = 6 + multiple_invokers_used = TRUE + object_path = /obj/structure/destructible/clockwork/massive/celestial_gateway + creator_message = "The Ark swirls into existance before you with the help of the Generals. After all this time, he shall, finally, be free" + usage_tip = "The gateway is completely vulnerable to attack during its five-minute duration. It will periodically give indication of its general position to everyone on the station \ + as well as being loud enough to be heard throughout the entire sector. Defend it with your life!" + tier = SCRIPTURE_APPLICATION + sort_priority = 8 + requires_full_power = TRUE + +/datum/clockwork_scripture/create_object/ark_of_the_clockwork_justiciar/check_special_requirements() + if(!slab.no_cost) + if(GLOB.ratvar_awakens) + to_chat(invoker, "\"I am already here, there is no point in that.\"") + return FALSE + for(var/obj/structure/destructible/clockwork/massive/celestial_gateway/G in GLOB.all_clockwork_objects) + var/area/gate_area = get_area(G) + to_chat(invoker, "There is already an Ark at [gate_area.map_name]!") + return FALSE + var/area/A = get_area(invoker) + var/turf/T = get_turf(invoker) + if(!T || !is_station_level(T.z) || istype(A, /area/shuttle) || !A.blob_allowed) + to_chat(invoker, "You must be on the station to activate the Ark!") + return FALSE + if(GLOB.clockwork_gateway_activated) + to_chat(invoker, "Ratvar's recent banishment renders him too weak to be wrung forth from Reebe!") + return FALSE + return ..() + diff --git a/code/modules/antagonists/clockcult/clock_scriptures/scripture_scripts.dm b/code/modules/antagonists/clockcult/clock_scriptures/scripture_scripts.dm index d22a2f69b7..d96765d536 100644 --- a/code/modules/antagonists/clockcult/clock_scriptures/scripture_scripts.dm +++ b/code/modules/antagonists/clockcult/clock_scriptures/scripture_scripts.dm @@ -1,5 +1,5 @@ ///////////// -// SCRIPTS // +// SCRIPTS // Various miscellanious spells for offense/defense/construction. ///////////// @@ -217,53 +217,6 @@ weapon_type = /obj/item/clockwork/weapon/ratvarian_spear -//Spatial Gateway: Allows the invoker to teleport themselves and any nearby allies to a conscious servant or clockwork obelisk. -/datum/clockwork_scripture/spatial_gateway - descname = "Teleport Gate" - name = "Spatial Gateway" - desc = "Tears open a miniaturized gateway in spacetime to any conscious servant that can transport objects or creatures to its destination. \ - Each servant assisting in the invocation adds one additional use and four additional seconds to the gateway's uses and duration." - invocations = list("Spatial Gateway...", "...activate!") - channel_time = 80 - power_cost = 400 - multiple_invokers_used = TRUE - multiple_invokers_optional = TRUE - usage_tip = "This gateway is strictly one-way and will only allow things through the invoker's portal." - tier = SCRIPTURE_SCRIPT - primary_component = GEIS_CAPACITOR - sort_priority = 9 - quickbind = TRUE - quickbind_desc = "Allows you to create a one-way Spatial Gateway to a living Servant or Clockwork Obelisk." - -/datum/clockwork_scripture/spatial_gateway/check_special_requirements() - if(!isturf(invoker.loc)) - to_chat(invoker, "You must not be inside an object to use this scripture!") - return FALSE - var/other_servants = 0 - for(var/mob/living/L in GLOB.alive_mob_list) - if(is_servant_of_ratvar(L) && !L.stat && L != invoker) - other_servants++ - for(var/obj/structure/destructible/clockwork/powered/clockwork_obelisk/O in GLOB.all_clockwork_objects) - if(O.anchored) - other_servants++ - if(!other_servants) - to_chat(invoker, "There are no other conscious servants or anchored clockwork obelisks!") - return FALSE - return TRUE - -/datum/clockwork_scripture/spatial_gateway/scripture_effects() - var/portal_uses = 0 - var/duration = 0 - for(var/mob/living/L in range(1, invoker)) - if(!L.stat && is_servant_of_ratvar(L)) - portal_uses++ - duration += 40 //4 seconds - if(GLOB.ratvar_awakens) - portal_uses = max(portal_uses, 100) //Very powerful if Ratvar has been summoned - duration = max(duration, 100) - return slab.procure_gateway(invoker, duration, portal_uses) - - //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" @@ -487,3 +440,26 @@ invoker.light_range = 0 invoker.update_light() return ..() + +//Belligerent: Channeled for up to fifteen times over thirty seconds. Forces non-servants that can hear the chant to walk, doing minor damage. Nar-Sian cultists are burned. +/datum/clockwork_scripture/channeled/belligerent + descname = "Channeled, Area Slowdown" + name = "Belligerent" + desc = "Forces all nearby non-servants to walk rather than run, doing minor damage. Chanted every two seconds for up to thirty seconds." + chant_invocations = list("Punish their blindness!", "Take time, make slow!", "Kneel before The Justiciar!", "Halt their charges!", "Cease the tides!") + chant_amount = 15 + chant_interval = 20 + channel_time = 20 + power_cost = 300 + usage_tip = "Useful for crowd control in a populated area and disrupting mass movement." + tier = SCRIPTURE_DRIVER + primary_component = BELLIGERENT_EYE + sort_priority = 1 + quickbind = TRUE + quickbind_desc = "Forces nearby non-Servants to walk, doing minor damage with each chant.
    Maximum 15 chants." + +/datum/clockwork_scripture/channeled/belligerent/chant_effects(chant_number) + for(var/mob/living/carbon/C in hearers(7, invoker)) + C.apply_status_effect(STATUS_EFFECT_BELLIGERENT) + new /obj/effect/temp_visual/ratvar/belligerent(get_turf(invoker)) + return TRUE diff --git a/code/modules/antagonists/clockcult/clock_structures/ark_of_the_clockwork_justicar.dm b/code/modules/antagonists/clockcult/clock_structures/ark_of_the_clockwork_justicar.dm index 297856f531..7478d45b08 100644 --- a/code/modules/antagonists/clockcult/clock_structures/ark_of_the_clockwork_justicar.dm +++ b/code/modules/antagonists/clockcult/clock_structures/ark_of_the_clockwork_justicar.dm @@ -1,5 +1,3 @@ -#define ARK_GRACE_PERIOD 300 //In seconds, how long the crew has before the Ark truly "begins" - /proc/clockwork_ark_active() //A helper proc so the Ark doesn't have to be typecast every time it's checked; returns null if there is no Ark and its active var otherwise var/obj/structure/destructible/clockwork/massive/celestial_gateway/G = GLOB.ark_of_the_clockwork_justiciar if(!G) @@ -11,7 +9,7 @@ name = "\improper Ark of the Clockwork Justicar" desc = "A massive, hulking amalgamation of parts. It seems to be maintaining a very unstable bluespace anomaly." clockwork_desc = "Nezbere's magnum opus: a hulking clockwork machine capable of combining bluespace and steam power to summon Ratvar. Once activated, \ - its instability will cause one-way bluespace rifts to open across the station to the City of Cogs, so be prepared to defend it at all costs." + its instability will alert the entire area, so be prepared to defend it at all costs." max_integrity = 500 mouse_opacity = MOUSE_OPACITY_OPAQUE icon = 'icons/effects/clockwork_effects.dmi' @@ -22,9 +20,8 @@ immune_to_servant_attacks = TRUE var/active = FALSE var/progress_in_seconds = 0 //Once this reaches GATEWAY_RATVAR_ARRIVAL, it's game over - var/grace_period = ARK_GRACE_PERIOD //This exists to allow the crew to gear up and prepare for the invasion - var/initial_activation_delay = -1 //How many seconds the Ark will have initially taken to activate - var/seconds_until_activation = -1 //How many seconds until the Ark activates; if it should never activate, set this to -1 + var/initial_activation_delay = 5 //How many seconds the Ark will have initially taken to activate + var/seconds_until_activation = 5 //How many seconds until the Ark activates; if it should never activate, set this to -1 var/purpose_fulfilled = FALSE var/first_sound_played = FALSE var/second_sound_played = FALSE @@ -38,10 +35,21 @@ /obj/structure/destructible/clockwork/massive/celestial_gateway/Initialize() . = ..() + INVOKE_ASYNC(src, .proc/spawn_animation) glow = new(get_turf(src)) if(!GLOB.ark_of_the_clockwork_justiciar) GLOB.ark_of_the_clockwork_justiciar = src - START_PROCESSING(SSprocessing, src) + +/obj/structure/destructible/clockwork/massive/celestial_gateway/on_attack_hand(mob/user, act_intent, unarmed_attack_flags) + if(!active && is_servant_of_ratvar(user) && user.canUseTopic(src, !issilicon(user), NO_DEXTERY)) + if(alert(user, "Are you sure you want to activate the ark? Once enabled, there will be no turning back.", "Enabling the ark", "Activate!", "Cancel") == "Activate!") + if(active) + return + log_game("[key_name(user)] has activated an Ark of the Clockwork Justicar at [COORD(src)].") + START_PROCESSING(SSprocessing, src) + SSshuttle.registerHostileEnvironment(src) + else + to_chat(user, "You decide against activating the ark.. for now.") /obj/structure/destructible/clockwork/massive/celestial_gateway/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, attack_dir) . = ..() @@ -49,7 +57,7 @@ flick("clockwork_gateway_damaged", glow) playsound(src, 'sound/machines/clockcult/ark_damage.ogg', 75, FALSE) if(last_scream < world.time) - audible_message("An unearthly screaming sound resonates throughout Reebe!") + audible_message("An unearthly screaming sound resonates throughout the area!") for(var/V in GLOB.player_list) var/mob/M = V var/turf/T = get_turf(M) @@ -60,31 +68,19 @@ /obj/structure/destructible/clockwork/massive/celestial_gateway/proc/final_countdown(ark_time) //WE'RE LEAVING TOGETHEEEEEEEEER if(!ark_time) - ark_time = 30 //minutes - initial_activation_delay = ark_time * 60 - seconds_until_activation = ark_time * 60 //60 seconds in a minute * number of minutes + ark_time = 5 //5 minutes for(var/obj/item/clockwork/construct_chassis/cogscarab/C in GLOB.all_clockwork_objects) C.infinite_resources = FALSE GLOB.servants_active = TRUE SSshuttle.registerHostileEnvironment(src) -/obj/structure/destructible/clockwork/massive/celestial_gateway/proc/cry_havoc() - visible_message("[src] shudders and roars to life, its parts beginning to whirr and screech!") - hierophant_message("The Ark is activating! You will be transported there soon!") - for(var/mob/M in GLOB.player_list) - var/turf/T = get_turf(M) - if(is_servant_of_ratvar(M) || isobserver(M) || (T && T.z == z)) - M.playsound_local(M, 'sound/magic/clockwork/ark_activation_sequence.ogg', 30, FALSE, pressure_affected = FALSE) - addtimer(CALLBACK(src, .proc/let_slip_the_dogs), 300) - /obj/structure/destructible/clockwork/massive/celestial_gateway/proc/let_slip_the_dogs() - spawn_animation() first_sound_played = TRUE active = TRUE + visible_message("[src] shudders and roars to life, its parts beginning to whirr and screech!") priority_announce("Massive [Gibberish("bluespace", 100)] anomaly detected on all frequencies. All crew are directed to \ @!$, [text2ratvar("PURGE ALL UNTRUTHS")] <&. the anomalies and destroy their source to prevent further damage to corporate property. This is \ - not a drill.[grace_period ? " Estimated time of appearance: [grace_period] seconds. Use this time to prepare for an attack on [station_name()]." : ""]", \ - "Central Command Higher Dimensional Affairs", 'sound/magic/clockwork/ark_activation.ogg') + not a drill.", "Central Command Higher Dimensional Affairs", 'sound/magic/clockwork/ark_activation_sequence.ogg') set_security_level("delta") for(var/V in SSticker.mode.servants_of_ratvar) var/datum/mind/M = V @@ -92,15 +88,6 @@ continue if(ishuman(M.current)) M.current.add_overlay(mutable_appearance('icons/effects/genetics.dmi', "servitude", -MUTATIONS_LAYER)) - for(var/V in GLOB.brass_recipes) - var/datum/stack_recipe/R = V - if(!R) - continue - if(R.title == "wall gear") - R.time *= 2 //Building walls becomes slower when the Ark activates - mass_recall() - recalls_remaining++ //So it doesn't use up a charge - var/turf/T = get_turf(src) var/list/open_turfs = list() for(var/turf/open/OT in orange(1, T)) @@ -110,14 +97,35 @@ for(var/mob/living/L in T) L.forceMove(pick(open_turfs)) -/obj/structure/destructible/clockwork/massive/celestial_gateway/proc/open_portal(turf/T) - new/obj/effect/clockwork/city_of_cogs_rift(T) - /obj/structure/destructible/clockwork/massive/celestial_gateway/proc/spawn_animation() - hierophant_message("The Ark has activated! [grace_period ? "You have [round(grace_period / 60)] minutes until the crew invades! " : ""]Defend it at all costs!", FALSE, src) - sound_to_playing_players(volume = 10, channel = CHANNEL_JUSTICAR_ARK, S = sound('sound/effects/clockcult_gateway_charging.ogg', TRUE)) - seconds_until_activation = 0 - SSshuttle.registerHostileEnvironment(src) + var/turf/T = get_turf(src) + new/obj/effect/clockwork/general_marker/inathneq(T) + hierophant_message("\"[text2ratvar("Engine, come forth and show your servants your mercy")]!\"") + playsound(T, 'sound/magic/clockwork/invoke_general.ogg', 30, 0) + sleep(10) + new/obj/effect/clockwork/general_marker/sevtug(T) + hierophant_message("\"[text2ratvar("Engine, come forth and show this station your decorating skills")]!\"") + playsound(T, 'sound/magic/clockwork/invoke_general.ogg', 45, 0) + sleep(10) + new/obj/effect/clockwork/general_marker/nezbere(T) + hierophant_message("\"[text2ratvar("Engine, come forth and shine your light across this realm")]!!\"") + playsound(T, 'sound/magic/clockwork/invoke_general.ogg', 60, 0) + sleep(10) + new/obj/effect/clockwork/general_marker/nzcrentr(T) + hierophant_message("\"[text2ratvar("Engine, come forth")].\"") + playsound(T, 'sound/magic/clockwork/invoke_general.ogg', 75, 0) + sleep(10) + playsound(T, 'sound/magic/clockwork/invoke_general.ogg', 100, 0) + var/list/open_turfs = list() + for(var/turf/open/OT in orange(1, T)) + if(!is_blocked_turf(OT, TRUE)) + open_turfs |= OT + if(open_turfs.len) + for(var/mob/living/L in T) + L.forceMove(pick(open_turfs)) + glow = new(get_turf(src)) + var/area/gate_area = get_area(src) + hierophant_message("An Ark of the Clockwork Justicar has been created in [gate_area.map_name]!", FALSE, src) /obj/structure/destructible/clockwork/massive/celestial_gateway/proc/initiate_mass_recall() recalling = TRUE @@ -141,35 +149,22 @@ transform = matrix() * 2 animate(src, transform = matrix() * 0.5, time = 30, flags = ANIMATION_END_NOW) -/obj/structure/destructible/clockwork/massive/celestial_gateway/Destroy() +obj/structure/destructible/clockwork/massive/celestial_gateway/Destroy() STOP_PROCESSING(SSprocessing, src) + if(!purpose_fulfilled) + var/area/gate_area = get_area(src) + hierophant_message("An Ark of the Clockwork Justicar has fallen at [gate_area.map_name]!") + send_to_playing_players(sound(null, 0, channel = CHANNEL_JUSTICAR_ARK)) + var/was_stranded = SSshuttle.emergency.mode == SHUTTLE_STRANDED SSshuttle.clearHostileEnvironment(src) - if(!purpose_fulfilled && istype(SSticker.mode, /datum/game_mode/clockwork_cult)) - hierophant_message("The Ark has fallen!") - sound_to_playing_players(null, channel = CHANNEL_JUSTICAR_ARK) - SSticker.force_ending = TRUE //rip + if(!was_stranded && !purpose_fulfilled) + priority_announce("Massive energy anomaly no longer on short-range scanners, bluespace distortions still detected.","Central Command Higher Dimensional Affairs") if(glow) qdel(glow) glow = null if(countdown) qdel(countdown) countdown = null - for(var/mob/L in GLOB.player_list) - var/turf/T = get_turf(L) - if(T && T.z == z) - var/atom/movable/target = L - if(isobj(L.loc)) - target = L.loc - target.forceMove(get_turf(pick(GLOB.generic_event_spawns))) - L.overlay_fullscreen("flash", /obj/screen/fullscreen/flash/static) - L.clear_fullscreen("flash", 30) - if(isliving(L)) - var/mob/living/LI = L - LI.Stun(50) - for(var/obj/effect/clockwork/city_of_cogs_rift/R in GLOB.all_clockwork_objects) - qdel(R) - if(GLOB.ark_of_the_clockwork_justiciar == src) - GLOB.ark_of_the_clockwork_justiciar = null . = ..() /obj/structure/destructible/clockwork/massive/celestial_gateway/deconstruct(disassembled = TRUE) @@ -203,8 +198,6 @@ /obj/structure/destructible/clockwork/massive/celestial_gateway/proc/get_arrival_time(var/deciseconds = TRUE) if(seconds_until_activation) . = seconds_until_activation - else if(grace_period) - . = grace_period else if(GATEWAY_RATVAR_ARRIVAL - progress_in_seconds > 0) . = round(max((GATEWAY_RATVAR_ARRIVAL - progress_in_seconds) / (GATEWAY_SUMMON_RATE), 0), 1) if(deciseconds) @@ -213,8 +206,6 @@ /obj/structure/destructible/clockwork/massive/celestial_gateway/proc/get_arrival_text(s_on_time) if(seconds_until_activation) return "[get_arrival_time()][s_on_time ? "S" : ""]" - if(grace_period) - return "[get_arrival_time()][s_on_time ? "S" : ""]" . = "IMMINENT" if(!obj_integrity) . = "DETONATING" @@ -229,17 +220,14 @@ if(!active) . += "Time until the Ark's activation: [DisplayTimeText(get_arrival_time())]" else - if(grace_period) - . += "Crew grace period time remaining: [DisplayTimeText(get_arrival_time())]" - else - . += "Time until Ratvar's arrival: [DisplayTimeText(get_arrival_time())]" - switch(progress_in_seconds) - if(-INFINITY to GATEWAY_REEBE_FOUND) - . += "The Ark is feeding power into the bluespace field." - if(GATEWAY_REEBE_FOUND to GATEWAY_RATVAR_COMING) - . += "The field is ripping open a copy of itself in Ratvar's prison." - if(GATEWAY_RATVAR_COMING to INFINITY) - . += "With the bluespace field established, Ratvar is preparing to come through!" + . += "Time until Ratvar's arrival: [DisplayTimeText(get_arrival_time())]" + switch(progress_in_seconds) + if(-INFINITY to GATEWAY_REEBE_FOUND) + . += "The Ark is feeding power into the bluespace field." + if(GATEWAY_REEBE_FOUND to GATEWAY_RATVAR_COMING) + . += "The field is ripping open a copy of itself in Ratvar's prison." + if(GATEWAY_RATVAR_COMING to INFINITY) + . += "With the bluespace field established, Ratvar is preparing to come through!" else if(!active) . += "Whatever it is, it doesn't seem to be active." @@ -253,20 +241,14 @@ . += "The anomaly is stable! Something is coming through!" /obj/structure/destructible/clockwork/massive/celestial_gateway/process() - if(seconds_until_activation == -1) //we never do anything - return adjust_clockwork_power(2.5) //Provides weak power generation on its own if(seconds_until_activation) if(!countdown) countdown = new(src) countdown.start() seconds_until_activation-- - if(!GLOB.script_scripture_unlocked && initial_activation_delay * 0.5 > seconds_until_activation) - GLOB.script_scripture_unlocked = TRUE - hierophant_message("The Ark is halfway prepared. Script scripture is now available!") if(!seconds_until_activation) - cry_havoc() - seconds_until_activation = -1 //we'll set this after cry_havoc() + let_slip_the_dogs() return if(!first_sound_played || prob(7)) for(var/mob/M in GLOB.player_list) @@ -285,6 +267,9 @@ if(!step_away(O, src, 2) || get_dist(O, src) < 2) O.take_damage(50, BURN, "bomb") O.update_icon() + + conversion_pulse() //Converts the nearby area into clockcult-style + for(var/V in GLOB.player_list) var/mob/M = V var/turf/T = get_turf(M) @@ -292,29 +277,24 @@ M.forceMove(get_step(src, SOUTH)) M.overlay_fullscreen("flash", /obj/screen/fullscreen/flash) M.clear_fullscreen("flash", 5) - if(grace_period) - grace_period-- - return progress_in_seconds += GATEWAY_SUMMON_RATE switch(progress_in_seconds) if(-INFINITY to GATEWAY_REEBE_FOUND) if(!second_sound_played) - for(var/V in GLOB.generic_event_spawns) - addtimer(CALLBACK(src, .proc/open_portal, get_turf(V)), rand(100, 600)) sound_to_playing_players('sound/magic/clockwork/invoke_general.ogg', 30, FALSE) - sound_to_playing_players(volume = 20, channel = CHANNEL_JUSTICAR_ARK, S = sound('sound/effects/clockcult_gateway_charging.ogg', TRUE)) + sound_to_playing_players(volume = 10, channel = CHANNEL_JUSTICAR_ARK, S = sound('sound/effects/clockcult_gateway_charging.ogg', TRUE)) second_sound_played = TRUE make_glow() glow.icon_state = "clockwork_gateway_charging" if(GATEWAY_REEBE_FOUND to GATEWAY_RATVAR_COMING) if(!third_sound_played) - sound_to_playing_players(volume = 25, channel = CHANNEL_JUSTICAR_ARK, S = sound('sound/effects/clockcult_gateway_active.ogg', TRUE)) + sound_to_playing_players(volume = 30, channel = CHANNEL_JUSTICAR_ARK, S = sound('sound/effects/clockcult_gateway_active.ogg', TRUE)) third_sound_played = TRUE make_glow() glow.icon_state = "clockwork_gateway_active" if(GATEWAY_RATVAR_COMING to GATEWAY_RATVAR_ARRIVAL) if(!fourth_sound_played) - sound_to_playing_players(volume = 30, channel = CHANNEL_JUSTICAR_ARK, S = sound('sound/effects/clockcult_gateway_closing.ogg', TRUE)) + sound_to_playing_players(volume = 70, channel = CHANNEL_JUSTICAR_ARK, S = sound('sound/effects/clockcult_gateway_closing.ogg', TRUE)) fourth_sound_played = TRUE make_glow() glow.icon_state = "clockwork_gateway_closing" @@ -334,7 +314,6 @@ GLOB.clockwork_gateway_activated = TRUE var/turf/T = SSmapping.get_station_center() new /obj/structure/destructible/clockwork/massive/ratvar(T) - SSticker.force_ending = TRUE var/x0 = T.x var/y0 = T.y for(var/I in spiral_range_turfs(255, T, tick_checked = TRUE)) @@ -349,6 +328,17 @@ T.ratvar_act(dist) CHECK_TICK +//Converts nearby turfs into their clockwork equivalent, with ever-increasing range the closer the ark is to summoning Ratvar +/obj/structure/destructible/clockwork/massive/celestial_gateway/proc/conversion_pulse() + var/convert_dist = 1 + (round(FLOOR(progress_in_seconds, 15) * 0.067)) + for(var/t in RANGE_TURFS(convert_dist, loc)) + var/turf/T = t + if(!T) + continue + var/dist = cheap_hypotenuse(T.x, T.y, x, y) + if(dist < convert_dist) + T.ratvar_act(FALSE, TRUE, 3) + //ATTACK GHOST IGNORING PARENT RETURN VALUE /obj/structure/destructible/clockwork/massive/celestial_gateway/attack_ghost(mob/user) if(!IsAdminGhost(user)) @@ -361,9 +351,9 @@ if(alert(user, "You're REALLY SURE? This cannot be undone.", name, "Yes - Activate the Ark", "No") == "Yes - Activate the Ark") message_admins("Admin [key_name_admin(user)] started the Ark's countdown!") log_admin("Admin [key_name(user)] started the Ark's countdown on a non-clockcult mode!") - to_chat(user, "The gamemode is now being treated as clockwork cult, and the Ark is counting down from 30 \ + to_chat(user, "The gamemode is now being treated as clockwork cult, and the Ark is counting down from 5 \ minutes. You will need to create servant players yourself.") - final_countdown(35) + final_countdown(5) diff --git a/code/modules/antagonists/clockcult/clock_structures/clockwork_obelisk.dm b/code/modules/antagonists/clockcult/clock_structures/clockwork_obelisk.dm index 8c529d43a6..2b4b797b4d 100644 --- a/code/modules/antagonists/clockcult/clock_structures/clockwork_obelisk.dm +++ b/code/modules/antagonists/clockcult/clock_structures/clockwork_obelisk.dm @@ -41,14 +41,19 @@ affected += try_use_power(MIN_CLOCKCULT_POWER*4) return affected -/obj/structure/destructible/clockwork/powered/clockwork_obelisk/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/structure/destructible/clockwork/powered/clockwork_obelisk/Destroy() + for(var/obj/effect/clockwork/spatial_gateway/SG in loc) + SG.ex_act(EXPLODE_DEVASTATE) + return ..() + +/obj/structure/destructible/clockwork/powered/clockwork_obelisk/on_attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return if(!is_servant_of_ratvar(user) || !can_access_clockwork_power(src, hierophant_cost) || !anchored) to_chat(user, "You place your hand on [src], but it doesn't react.") return - var/choice = alert(user,"You place your hand on [src]...",,"Hierophant Broadcast","Spatial Gateway","Cancel") + var/choice = alert(user,"You place your hand on [src]...",,"Hierophant Broadcast","Spatial Gateway","Cancel") //Will create a stable gateway instead if between two obelisks one of which is onstation and the other on reebe switch(choice) if("Hierophant Broadcast") if(active) @@ -96,7 +101,7 @@ if(!anchored) return var/obj/effect/clockwork/spatial_gateway/SG = locate(/obj/effect/clockwork/spatial_gateway) in loc - if(SG && SG.timerid) //it's a valid gateway, we're active + if(SG && (SG.timerid || SG.is_stable)) //it's a valid gateway, we're active icon_state = active_icon density = FALSE active = TRUE diff --git a/code/modules/antagonists/clockcult/clock_structures/eminence_spire.dm b/code/modules/antagonists/clockcult/clock_structures/eminence_spire.dm index 2c84a5b332..5302153b9c 100644 --- a/code/modules/antagonists/clockcult/clock_structures/eminence_spire.dm +++ b/code/modules/antagonists/clockcult/clock_structures/eminence_spire.dm @@ -11,7 +11,7 @@ var/selection_timer //Timer ID; this is canceled if the vote is canceled var/kingmaking -/obj/structure/destructible/clockwork/eminence_spire/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/structure/destructible/clockwork/eminence_spire/on_attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return @@ -27,9 +27,6 @@ if(C.clock_team.eminence) to_chat(user, "There's already an Eminence!") return - if(!GLOB.servants_active) - to_chat(user, "The Ark isn't active!") - return if(eminence_nominee) //This could be one large proc, but is split into three for ease of reading if(eminence_nominee == user) cancelation(user) diff --git a/code/modules/antagonists/clockcult/clock_structures/heralds_beacon.dm b/code/modules/antagonists/clockcult/clock_structures/heralds_beacon.dm index 385b9a5431..f8a3afbf91 100644 --- a/code/modules/antagonists/clockcult/clock_structures/heralds_beacon.dm +++ b/code/modules/antagonists/clockcult/clock_structures/heralds_beacon.dm @@ -1,3 +1,5 @@ + + //Used to "declare war" against the station. The servants' equipment will be permanently supercharged, and the Ark given extra time to prepare. //This will send an announcement to the station, meaning that they will be warned very early in advance about the impending attack. /obj/structure/destructible/clockwork/heralds_beacon @@ -58,7 +60,7 @@ . += "There are [time_remaining] second[time_remaining != 1 ? "s" : ""] remaining to vote." . += "There are [voters.len]/[votes_needed] votes to activate the beacon!" -/obj/structure/destructible/clockwork/heralds_beacon/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/structure/destructible/clockwork/heralds_beacon/on_attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return @@ -108,5 +110,4 @@ to_chat(H, "The beacon's power warps your body into a clockwork form! You are now immune to many hazards, and your body is more robust against damage!") H.set_species(/datum/species/golem/clockwork/no_scrap) var/obj/structure/destructible/clockwork/massive/celestial_gateway/G = GLOB.ark_of_the_clockwork_justiciar - G.grace_period = FALSE //no grace period if we've declared war G.recalls_remaining++ diff --git a/code/modules/antagonists/clockcult/clock_structures/mania_motor.dm b/code/modules/antagonists/clockcult/clock_structures/mania_motor.dm index 24d0651444..40cadb53a2 100644 --- a/code/modules/antagonists/clockcult/clock_structures/mania_motor.dm +++ b/code/modules/antagonists/clockcult/clock_structures/mania_motor.dm @@ -30,7 +30,7 @@ toggle() return TRUE -/obj/structure/destructible/clockwork/powered/mania_motor/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/structure/destructible/clockwork/powered/mania_motor/on_attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/modules/antagonists/clockcult/clock_structures/prolonging_prism.dm b/code/modules/antagonists/clockcult/clock_structures/prolonging_prism.dm new file mode 100644 index 0000000000..73488d736a --- /dev/null +++ b/code/modules/antagonists/clockcult/clock_structures/prolonging_prism.dm @@ -0,0 +1,134 @@ +//Prolonging Prism: A prism that consumes power to delay the shuttle +/obj/structure/destructible/clockwork/powered/prolonging_prism + name = "prolonging prism" + desc = "A dark onyx prism, held in midair by spiraling tendrils of stone." + clockwork_desc = "A powerful prism that will delay the arrival of an emergency shuttle." + icon_state = "prolonging_prism_inactive" + active_icon = "prolonging_prism" + inactive_icon = "prolonging_prism_inactive" + unanchored_icon = "prolonging_prism_unwrenched" + construction_value = 20 + max_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/static/power_refund = 250 + var/static/delay_cost = 2000 //Updated power values for new-newclock. Easier to activate and sustain, you are quite literally pointing the entire station towards you as opposed to blood-delay after all. + var/static/delay_cost_increase = 1000 + var/static/delay_remaining = 0 + +/obj/structure/destructible/clockwork/powered/prolonging_prism/examine(mob/user) + . = ..() + if(is_servant_of_ratvar(user) || isobserver(user)) + if(SSshuttle.emergency.mode == SHUTTLE_DOCKED || SSshuttle.emergency.mode == SHUTTLE_IGNITING || SSshuttle.emergency.mode == SHUTTLE_STRANDED || SSshuttle.emergency.mode == SHUTTLE_ESCAPE) + . += "An emergency shuttle has arrived and this prism is no longer useful; attempt to activate it to gain a partial refund of components used." + else + var/efficiency = get_efficiency_mod(TRUE) + . += "It requires at least [DisplayPower(get_delay_cost())] of power to attempt to delay the arrival of an emergency shuttle by [2 * efficiency] minutes." + . += "This cost increases by [DisplayPower(delay_cost_increase)] for every previous activation." + +/obj/structure/destructible/clockwork/powered/prolonging_prism/forced_disable(bad_effects) + if(active) + if(bad_effects) + try_use_power(MIN_CLOCKCULT_POWER*4) + visible_message("[src] emits an airy chuckling sound and falls dark!") + toggle() + return TRUE + +/obj/structure/destructible/clockwork/powered/prolonging_prism/on_attack_hand(mob/living/user) + if(user.canUseTopic(src, !issilicon(user), NO_DEXTERY) && is_servant_of_ratvar(user)) + if(SSshuttle.emergency.mode == SHUTTLE_DOCKED || SSshuttle.emergency.mode == SHUTTLE_IGNITING || SSshuttle.emergency.mode == SHUTTLE_STRANDED || SSshuttle.emergency.mode == SHUTTLE_ESCAPE) + to_chat(user, "You break [src] apart, refunding some of the power used.") + adjust_clockwork_power(power_refund) + take_damage(max_integrity) + return 0 + if(active) + return 0 + var/turf/T = get_turf(src) + if(!T || !is_station_level(T.z)) + to_chat(user, "[src] must be on the station to function!") + return 0 + if(SSshuttle.emergency.mode != SHUTTLE_CALL) + to_chat(user, "No emergency shuttles are attempting to arrive at the station!") + return 0 + if(!try_use_power(get_delay_cost())) + to_chat(user, "[src] needs more power to function!") + return 0 + delay_cost += delay_cost_increase + delay_remaining += PRISM_DELAY_DURATION + toggle(0, user) + +/obj/structure/destructible/clockwork/powered/prolonging_prism/process() + var/turf/own_turf = get_turf(src) + if(SSshuttle.emergency.mode != SHUTTLE_CALL || delay_remaining <= 0 || !own_turf || !is_station_level(own_turf.z)) + forced_disable(FALSE) + return + . = ..() + var/delay_amount = 40 + delay_remaining -= delay_amount + var/efficiency = get_efficiency_mod() + SSshuttle.emergency.setTimer(SSshuttle.emergency.timeLeft(1) + (delay_amount * efficiency)) + var/highest_y + var/highest_x + var/lowest_y + var/lowest_x + var/list/prism_turfs = list() + for(var/t in SSshuttle.emergency.ripple_area(SSshuttle.getDock("emergency_home"))) + prism_turfs[t] = TRUE + var/turf/T = t + if(!highest_y || T.y > highest_y) + highest_y = T.y + if(!highest_x || T.x > highest_x) + highest_x = T.x + if(!lowest_y || T.y < lowest_y) + lowest_y = T.y + if(!lowest_x || T.x < lowest_x) + lowest_x = T.x + var/mean_y = LERP(lowest_y, highest_y, 0.5) + var/mean_x = LERP(lowest_x, highest_x, 0.5) + if(prob(50)) + mean_y = CEILING(mean_y, 1) + else + mean_y = FLOOR(mean_y, 1) //Yes, I know round(mean_y) does the same, just left as FLOOR for consistancy sake + if(prob(50)) + mean_x = CEILING(mean_x, 1) + else + mean_x = FLOOR(mean_x, 1) + var/turf/semi_random_center_turf = locate(mean_x, mean_y, z) + for(var/t in getline(src, semi_random_center_turf)) + prism_turfs[t] = TRUE + var/placement_style = prob(50) + for(var/t in prism_turfs) + var/turf/T = t + if(placement_style) + if(ISODD(T.x + T.y)) + seven_random_hexes(T, efficiency) + else if(prob(50 * efficiency)) + new /obj/effect/temp_visual/ratvar/prolonging_prism(T) + else + if(ISEVEN(T.x + T.y)) + seven_random_hexes(T, efficiency) + else if(prob(50 * efficiency)) + new /obj/effect/temp_visual/ratvar/prolonging_prism(T) + CHECK_TICK //we may be going over a hell of a lot of turfs + +/obj/structure/destructible/clockwork/powered/prolonging_prism/proc/get_delay_cost() + return FLOOR(delay_cost, MIN_CLOCKCULT_POWER) + +/obj/structure/destructible/clockwork/powered/prolonging_prism/proc/seven_random_hexes(turf/T, efficiency) + var/static/list/hex_states = list("prismhex1", "prismhex2", "prismhex3", "prismhex4", "prismhex5", "prismhex6", "prismhex7") + var/mutable_appearance/hex_combo + for(var/n in hex_states) //BUILD ME A HEXAGON + if(prob(50 * efficiency)) + if(!hex_combo) + hex_combo = mutable_appearance('icons/effects/64x64.dmi', n, RIPPLE_LAYER) + else + hex_combo.add_overlay(mutable_appearance('icons/effects/64x64.dmi', n, RIPPLE_LAYER)) + if(hex_combo) //YOU BUILT A HEXAGON + hex_combo.pixel_x = -16 + hex_combo.pixel_y = -16 + hex_combo.mouse_opacity = MOUSE_OPACITY_TRANSPARENT + hex_combo.plane = GAME_PLANE + new /obj/effect/temp_visual/ratvar/prolonging_prism(T, hex_combo) diff --git a/code/modules/antagonists/clockcult/clock_structures/ratvar_the_clockwork_justicar.dm b/code/modules/antagonists/clockcult/clock_structures/ratvar_the_clockwork_justicar.dm index c17885315f..73ae89a19b 100644 --- a/code/modules/antagonists/clockcult/clock_structures/ratvar_the_clockwork_justicar.dm +++ b/code/modules/antagonists/clockcult/clock_structures/ratvar_the_clockwork_justicar.dm @@ -101,8 +101,8 @@ return clashing = TRUE GLOB.cult_narsie.clashing = TRUE - to_chat(world, "\"YOU.\"") - to_chat(world, "\"Ratvar?!\"") + to_chat(world, "\"[pick("YOU.", "BLOOD GOD!!", "FACE ME, COWARD!")]\"") + to_chat(world, "\"[pick("Ratvar?! How?!", "YOU. BANISHED ONCE. KILLED NOW.", "SCRAP HEAP!!")]\"") clash_of_the_titans(GLOB.cult_narsie) // >:( return TRUE @@ -137,15 +137,16 @@ base_victory_chance *= 2 //The clash has a higher chance of resolving each time both gods attack one another switch(winner) if("Ratvar") - send_to_playing_players("\"[pick("DIE.", "ROT.")]\"\n\ + send_to_playing_players("\"[pick("DIE.", "ROT FOR CENTURIES, AS I HAVE!.","PERISH, HEATHEN.", "DIE, MONSTER, YOU DON'T BELONG IN THIS WORLD.")]\"\n\ \"[pick("Nooooo...", "Not die. To y-", "Die. Ratv-", "Sas tyen re-")]\"") //Nar'Sie get out sound_to_playing_players('sound/magic/clockwork/anima_fragment_attack.ogg') - sound_to_playing_players('sound/magic/demon_dies.ogg', 50) + sound_to_playing_players('sound/magic/abomscream.ogg', 50) clashing = FALSE qdel(narsie) if("Nar'Sie") - send_to_playing_players("\"[pick("Ha.", "Ra'sha fonn dest.", "You fool. To come here.")]\"") //Broken English - sound_to_playing_players('sound/magic/demon_attack1.ogg') - sound_to_playing_players('sound/magic/clockwork/anima_fragment_death.ogg', 62) + send_to_playing_players("\"[pick("Ha.", "Ra'sha fonn dest.", "You fool. To come here.")]\"\n\ + \"[pick("NO, YOUR SHADOWS SHALL NO-", "ZNL GUR FGERNZF BS GVZR PNEEL ZL RKVFG-", "MY LIGHT CANNO-")]\"") + sound_to_playing_players('sound/magic/demon_attack1.ogg', 50) + sound_to_playing_players('sound/machines/clockcult/ratvar_scream.ogg', 80) narsie.clashing = FALSE qdel(src) diff --git a/code/modules/antagonists/clockcult/clock_structures/trap_triggers/lever.dm b/code/modules/antagonists/clockcult/clock_structures/trap_triggers/lever.dm index d4a02cc3e1..55347685f4 100644 --- a/code/modules/antagonists/clockcult/clock_structures/trap_triggers/lever.dm +++ b/code/modules/antagonists/clockcult/clock_structures/trap_triggers/lever.dm @@ -6,7 +6,7 @@ max_integrity = 75 icon_state = "lever" -/obj/structure/destructible/clockwork/trap/trigger/lever/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/structure/destructible/clockwork/trap/trigger/lever/on_attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/modules/antagonists/clockcult/clock_structures/trap_triggers/repeater.dm b/code/modules/antagonists/clockcult/clock_structures/trap_triggers/repeater.dm index e7d4e18c43..7a528786e2 100644 --- a/code/modules/antagonists/clockcult/clock_structures/trap_triggers/repeater.dm +++ b/code/modules/antagonists/clockcult/clock_structures/trap_triggers/repeater.dm @@ -6,7 +6,7 @@ max_integrity = 15 //Fragile! icon_state = "repeater" -/obj/structure/destructible/clockwork/trap/trigger/repeater/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/structure/destructible/clockwork/trap/trigger/repeater/on_attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/modules/antagonists/cult/cult_items.dm b/code/modules/antagonists/cult/cult_items.dm index 4e9d40d91c..f305d5b678 100644 --- a/code/modules/antagonists/cult/cult_items.dm +++ b/code/modules/antagonists/cult/cult_items.dm @@ -258,7 +258,7 @@ /datum/action/innate/cult/spin2win/Activate() cooldown = world.time + sword.spin_cooldown - holder.changeNext_move(50) + holder.DelayNextAction(50) holder.apply_status_effect(/datum/status_effect/sword_spin) sword.spinning = TRUE sword.block_chance = 100 diff --git a/code/modules/antagonists/cult/cult_structures.dm b/code/modules/antagonists/cult/cult_structures.dm index 6f340b9271..5803941f36 100644 --- a/code/modules/antagonists/cult/cult_structures.dm +++ b/code/modules/antagonists/cult/cult_structures.dm @@ -44,15 +44,16 @@ /obj/structure/destructible/cult/attack_animal(mob/living/simple_animal/M) if(istype(M, /mob/living/simple_animal/hostile/construct/builder)) if(obj_integrity < max_integrity) - M.changeNext_move(CLICK_CD_MELEE) + M.DelayNextAction(CLICK_CD_MELEE) obj_integrity = min(max_integrity, obj_integrity + 5) Beam(M, icon_state="sendbeam", time=4) M.visible_message("[M] repairs \the [src].", \ "You repair [src], leaving [p_they()] at [round(obj_integrity * 100 / max_integrity)]% stability.") + return TRUE else to_chat(M, "You cannot repair [src], as [p_theyre()] undamaged!") else - ..() + return ..() /obj/structure/destructible/cult/attackby(obj/I, mob/user, params) if(istype(I, /obj/item/melee/cultblade/dagger) && iscultist(user)) diff --git a/code/modules/antagonists/cult/runes.dm b/code/modules/antagonists/cult/runes.dm index 9b77e70a73..3ea160c5cc 100644 --- a/code/modules/antagonists/cult/runes.dm +++ b/code/modules/antagonists/cult/runes.dm @@ -67,7 +67,7 @@ Runes can either be invoked by one's self or with many different cultists. Each to_chat(user, "You disrupt the magic of [src] with [I].") qdel(src) -/obj/effect/rune/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/effect/rune/on_attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/modules/antagonists/devil/true_devil/_true_devil.dm b/code/modules/antagonists/devil/true_devil/_true_devil.dm index 7d7031dad4..272b154828 100644 --- a/code/modules/antagonists/devil/true_devil/_true_devil.dm +++ b/code/modules/antagonists/devil/true_devil/_true_devil.dm @@ -144,7 +144,7 @@ /mob/living/carbon/true_devil/resist_fire() //They're immune to fire. -/mob/living/carbon/true_devil/attack_hand(mob/living/carbon/human/M) +/mob/living/carbon/true_devil/on_attack_hand(mob/living/carbon/human/M) . = ..() if(.) switch(M.a_intent) diff --git a/code/modules/antagonists/disease/disease_mob.dm b/code/modules/antagonists/disease/disease_mob.dm index e876beb5dc..6a05d07b38 100644 --- a/code/modules/antagonists/disease/disease_mob.dm +++ b/code/modules/antagonists/disease/disease_mob.dm @@ -291,16 +291,19 @@ the new instance inside the host to be updated to the template's stats. /mob/camera/disease/ClickOn(var/atom/A, params) if(freemove && ishuman(A)) - var/mob/living/carbon/human/H = A - if(alert(src, "Select [H.name] as your initial host?", "Select Host", "Yes", "No") != "Yes") - return - if(!freemove) - return - if(QDELETED(H) || !force_infect(H)) - to_chat(src, "[H ? H.name : "Host"] cannot be infected.") + confirm_initial_infection(A) else ..() +/mob/camera/disease/proc/confirm_initial_infection(mob/living/carbon/human/H) + set waitfor = FALSE + if(alert(src, "Select [H.name] as your initial host?", "Select Host", "Yes", "No") != "Yes") + return + if(!freemove) + return + if(QDELETED(H) || !force_infect(H)) + to_chat(src, "[H ? H.name : "Host"] cannot be infected.") + /mob/camera/disease/proc/adapt_cooldown() to_chat(src, "You have altered your genetic structure. You will be unable to adapt again for [DisplayTimeText(adaptation_cooldown)].") next_adaptation_time = world.time + adaptation_cooldown diff --git a/code/modules/antagonists/revenant/revenant_abilities.dm b/code/modules/antagonists/revenant/revenant_abilities.dm index 2d84ed7c22..7a2f661fd9 100644 --- a/code/modules/antagonists/revenant/revenant_abilities.dm +++ b/code/modules/antagonists/revenant/revenant_abilities.dm @@ -17,6 +17,7 @@ //Harvest; activated ly clicking the target, will try to drain their essence. /mob/living/simple_animal/revenant/proc/Harvest(mob/living/carbon/human/target) + set waitfor = FALSE if(!castcheck(0)) return if(draining) diff --git a/code/modules/antagonists/swarmer/swarmer.dm b/code/modules/antagonists/swarmer/swarmer.dm index 9a8b9c8d59..b7503f4b22 100644 --- a/code/modules/antagonists/swarmer/swarmer.dm +++ b/code/modules/antagonists/swarmer/swarmer.dm @@ -36,7 +36,7 @@ if(A) notify_ghosts("A swarmer shell has been created in [A.name].", 'sound/effects/bin_close.ogg', source = src, action = NOTIFY_ATTACK, flashwindow = FALSE, ignore_dnr_observers = TRUE) -/obj/effect/mob_spawn/swarmer/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/effect/mob_spawn/swarmer/on_attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return @@ -158,10 +158,11 @@ face_atom(A) if(!isturf(loc)) return - if(next_move > world.time) + if(!CheckActionCooldown()) return if(!A.Adjacent(src)) return + DelayNextAction() A.swarmer_act(src) /atom/proc/swarmer_act(mob/living/simple_animal/hostile/swarmer/S) @@ -497,7 +498,7 @@ if(resource_gain) resources += resource_gain do_attack_animation(target) - changeNext_move(CLICK_CD_MELEE) + DelayNextAction(CLICK_CD_MELEE) var/obj/effect/temp_visual/swarmer/integrate/I = new /obj/effect/temp_visual/swarmer/integrate(get_turf(target)) I.pixel_x = target.pixel_x I.pixel_y = target.pixel_y @@ -517,10 +518,9 @@ /mob/living/simple_animal/hostile/swarmer/proc/DisIntegrate(atom/movable/target) new /obj/effect/temp_visual/swarmer/disintegration(get_turf(target)) do_attack_animation(target) - changeNext_move(CLICK_CD_MELEE) + DelayNextAction(CLICK_CD_MELEE) target.ex_act(EXPLODE_LIGHT) - /mob/living/simple_animal/hostile/swarmer/proc/DisperseTarget(mob/living/target) if(target == src) return diff --git a/code/modules/antagonists/traitor/IAA/internal_affairs.dm b/code/modules/antagonists/traitor/IAA/internal_affairs.dm index 19144d67c9..ff012e556a 100644 --- a/code/modules/antagonists/traitor/IAA/internal_affairs.dm +++ b/code/modules/antagonists/traitor/IAA/internal_affairs.dm @@ -167,10 +167,10 @@ return if(last_man_standing) if(syndicate) - to_chat(owner.current," All the loyalist agents are dead, and no more is required of you. Die a glorious death, agent. ") + to_chat(owner.current,"All the suspected agents are dead, and no more is required of you. Die a glorious death, agent.") + replace_escape_objective(owner) else - to_chat(owner.current," All the other agents are dead, and you're the last loose end. Stage a Syndicate terrorist attack to cover up for today's events. You no longer have any limits on collateral damage.") - replace_escape_objective(owner) + to_chat(owner.current,"All the other agents are dead. You have done us all a great service and shall be honorably exiled upon returning to base.") /datum/antagonist/traitor/internal_affairs/proc/iaa_process() if(owner&&owner.current&&owner.current.stat!=DEAD) @@ -193,7 +193,7 @@ if(syndicate) fail_msg += " You no longer have permission to die. " else - fail_msg += " The truth could still slip out! Cease any terrorist actions as soon as possible, unneeded property damage or loss of employee life will lead to your contract being terminated." + fail_msg += " The truth could still slip out! Cease any terrorist actions as soon as possible, unneeded property damage or loss of employee life will lead to great shame." reinstate_escape_objective(owner) last_man_standing = FALSE to_chat(owner.current, fail_msg) @@ -226,18 +226,20 @@ add_objective(escape_objective) /datum/antagonist/traitor/internal_affairs/proc/greet_iaa() - 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", "receiving bribes", "malpractice", "worship of prohibited life forms", "possession of profane texts", "murder", "arson", "insulting their manager", "grand theft", "conspiracy", "attempting to unionize", "vandalism", "gross incompetence") + var/crime = pick("distribution of contraband" , "embezzlement", "piloting under the influence", "dereliction of duty", "syndicate collaboration", "mutiny", "multiple homicides", "corporate espionage", "receiving bribes", "malpractice", "worship of prohibited life forms", "possession of profane texts", "murder", "arson", "insulting their manager", "grand theft", "conspiracy", "attempting to unionize", "vandalism", "gross incompetence") to_chat(owner.current, "You are the [special_role].") if(syndicate) - to_chat(owner.current, "Your target has been framed for [crime], and you have been tasked with eliminating them to prevent them defending themselves in court.") - to_chat(owner.current, "Any damage you cause will be a further embarrassment to Nanotrasen, so you have no limits on collateral damage.") - to_chat(owner.current, " You have been provided with a standard uplink to accomplish your task. ") - to_chat(owner.current, "By no means reveal that you, or any other NT employees, are undercover agents.") + to_chat(owner.current, "GREAT LEADER IS DEAD. NANOTRASEN MUST FALL.") + to_chat(owner.current, "Your have infiltrated this vessel to cause chaos and assassinate targets known to have conspired against the Syndicate.") + to_chat(owner.current, "Any damage you cause will be a further embarrassment to Nanotrasen, so you have no limits on collateral damage.") + to_chat(owner.current, "You have been provided with a standard uplink to accomplish your task. ") + to_chat(owner.current, "By no means reveal that you are a Syndicate agent. By no means reveal that your targets are being hunted.") else - to_chat(owner.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(owner.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(owner.current, "For the sake of plausible deniability, you have been equipped with an array of captured Syndicate weaponry available via uplink.") + to_chat(owner.current, "CAUTION: Your legal status as a citizen of NanoTrasen will be permanently revoked upon completion of your first contract.") + to_chat(owner.current, "Your target has been suspected of [crime], and must be removed from this plane.") + to_chat(owner.current, "While you have a license to kill, you are to eliminate your targets with no collateral or unrelated deaths.") + to_chat(owner.current, "For the sake of plausable deniability, you have been equipped with captured Syndicate equipment via uplink.") to_chat(owner.current, "By no means reveal that you, or any other NT employees, are undercover agents.") to_chat(owner.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.") diff --git a/code/modules/assembly/bomb.dm b/code/modules/assembly/bomb.dm index 36c444f02d..1c814fa193 100644 --- a/code/modules/assembly/bomb.dm +++ b/code/modules/assembly/bomb.dm @@ -62,6 +62,7 @@ /obj/item/onetankbomb/analyzer_act(mob/living/user, obj/item/I) bombtank.analyzer_act(user, I) + return TRUE /obj/item/onetankbomb/attack_self(mob/user) //pressing the bomb accesses its assembly bombassembly.attack_self(user, TRUE) @@ -90,7 +91,7 @@ if(bombassembly) bombassembly.on_found(finder) -/obj/item/onetankbomb/attack_hand() //also for mousetraps +/obj/item/onetankbomb/on_attack_hand() //also for mousetraps . = ..() if(.) return diff --git a/code/modules/assembly/holder.dm b/code/modules/assembly/holder.dm index c960a7f039..bf56449a0c 100644 --- a/code/modules/assembly/holder.dm +++ b/code/modules/assembly/holder.dm @@ -87,7 +87,7 @@ if(a_right) a_right.dropped(user) -/obj/item/assembly_holder/attack_hand()//Perhapse this should be a holder_pickup proc instead, can add if needbe I guess +/obj/item/assembly_holder/on_attack_hand()//Perhapse this should be a holder_pickup proc instead, can add if needbe I guess . = ..() if(.) return diff --git a/code/modules/assembly/infrared.dm b/code/modules/assembly/infrared.dm index 8cb6eb66fb..6e8e2846a2 100644 --- a/code/modules/assembly/infrared.dm +++ b/code/modules/assembly/infrared.dm @@ -125,7 +125,7 @@ return refreshBeam() -/obj/item/assembly/infra/attack_hand() +/obj/item/assembly/infra/on_attack_hand() . = ..() refreshBeam() diff --git a/code/modules/assembly/mousetrap.dm b/code/modules/assembly/mousetrap.dm index 90d4662c15..2c005b971d 100644 --- a/code/modules/assembly/mousetrap.dm +++ b/code/modules/assembly/mousetrap.dm @@ -84,8 +84,7 @@ playsound(src, 'sound/weapons/handcuffs.ogg', 30, TRUE, -3) -//ATTACK HAND IGNORING PARENT RETURN VALUE -/obj/item/assembly/mousetrap/attack_hand(mob/living/carbon/human/user) +/obj/item/assembly/mousetrap/on_attack_hand(mob/living/carbon/human/user) if(armed) if((HAS_TRAIT(user, TRAIT_DUMB) || HAS_TRAIT(user, TRAIT_CLUMSY)) && prob(50)) var/which_hand = BODY_ZONE_PRECISE_L_HAND diff --git a/code/modules/atmospherics/machinery/components/components_base.dm b/code/modules/atmospherics/machinery/components/components_base.dm index dc7c106035..a8d9586fc4 100644 --- a/code/modules/atmospherics/machinery/components/components_base.dm +++ b/code/modules/atmospherics/machinery/components/components_base.dm @@ -170,3 +170,4 @@ /obj/machinery/atmospherics/components/analyzer_act(mob/living/user, obj/item/I) atmosanalyzer_scan(airs, user, src) + return TRUE \ No newline at end of file diff --git a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm index ae80825694..0f849af0e3 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm @@ -276,8 +276,6 @@ return occupant /obj/machinery/atmospherics/components/unary/cryo_cell/container_resist(mob/living/user) - user.changeNext_move(CLICK_CD_BREAKOUT) - user.last_special = world.time + CLICK_CD_BREAKOUT user.visible_message("You see [user] kicking against the glass of [src]!", \ "You struggle inside [src], kicking the release with your foot... (this will take about [DisplayTimeText(breakout_time)].)", \ "You hear a thump from [src].") diff --git a/code/modules/atmospherics/machinery/pipes/pipes.dm b/code/modules/atmospherics/machinery/pipes/pipes.dm index 4a6170c251..23fd2292ff 100644 --- a/code/modules/atmospherics/machinery/pipes/pipes.dm +++ b/code/modules/atmospherics/machinery/pipes/pipes.dm @@ -64,6 +64,7 @@ /obj/machinery/atmospherics/pipe/analyzer_act(mob/living/user, obj/item/I) atmosanalyzer_scan(parent.air, user, src) + return TRUE /obj/machinery/atmospherics/pipe/returnPipenet() return parent diff --git a/code/modules/atmospherics/machinery/portable/portable_atmospherics.dm b/code/modules/atmospherics/machinery/portable/portable_atmospherics.dm index 445cc686f3..fa57e683c4 100644 --- a/code/modules/atmospherics/machinery/portable/portable_atmospherics.dm +++ b/code/modules/atmospherics/machinery/portable/portable_atmospherics.dm @@ -145,6 +145,7 @@ /obj/machinery/portable_atmospherics/analyzer_act(mob/living/user, obj/item/I) atmosanalyzer_scan(air_contents, user, src) + return TRUE /obj/machinery/portable_atmospherics/attacked_by(obj/item/I, mob/user, attackchain_flags = NONE, damage_multiplier = 1) if(I.force < 10 && !(stat & BROKEN)) diff --git a/code/modules/awaymissions/capture_the_flag.dm b/code/modules/awaymissions/capture_the_flag.dm index 03c0f5178a..3426208fae 100644 --- a/code/modules/awaymissions/capture_the_flag.dm +++ b/code/modules/awaymissions/capture_the_flag.dm @@ -53,8 +53,7 @@ to_chat(M, "\The [src] has been returned to base!") STOP_PROCESSING(SSobj, src) -//ATTACK HAND IGNORING PARENT RETURN VALUE -/obj/item/ctf/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/item/ctf/on_attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) if(!is_ctf_target(user) && !anyonecanpickup) to_chat(user, "Non players shouldn't be moving the flag!") return @@ -679,10 +678,7 @@ /obj/machinery/control_point/attackby(mob/user, params) capture(user) -/obj/machinery/control_point/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) - . = ..() - if(.) - return +/obj/machinery/control_point/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) capture(user) /obj/machinery/control_point/proc/capture(mob/user) diff --git a/code/modules/awaymissions/corpse.dm b/code/modules/awaymissions/corpse.dm index 4b2f1e9962..e68c45a84c 100644 --- a/code/modules/awaymissions/corpse.dm +++ b/code/modules/awaymissions/corpse.dm @@ -594,8 +594,7 @@ assignedrole = "Space Bar Patron" job_description = "Space Bar Patron" -//ATTACK HAND IGNORING PARENT RETURN VALUE -/obj/effect/mob_spawn/human/alive/space_bar_patron/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/effect/mob_spawn/human/alive/space_bar_patron/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) var/despawn = alert("Return to cryosleep? (Warning, Your mob will be deleted!)",,"Yes","No") if(despawn == "No" || !loc || !Adjacent(user)) return diff --git a/code/modules/cargo/coupon.dm b/code/modules/cargo/coupon.dm index c77050c530..1c1f2a36e1 100644 --- a/code/modules/cargo/coupon.dm +++ b/code/modules/cargo/coupon.dm @@ -8,6 +8,7 @@ icon = 'icons/obj/card.dmi' item_flags = NOBLUDGEON w_class = WEIGHT_CLASS_TINY + attack_speed = CLICK_CD_RAPID var/datum/supply_pack/discounted_pack var/discount_pct_off = 0.05 var/obj/machinery/computer/cargo/inserted_console @@ -34,6 +35,7 @@ if(discount_pct_off == COUPON_OMEN) to_chat(user, "\The [O] validates the coupon as authentic, but refuses to accept it...") O.say("Coupon fulfillment already in progress...") + user.DelayNextAction() return inserted_console = O diff --git a/code/modules/client/client_defines.dm b/code/modules/client/client_defines.dm index 7f1ba86ff5..ae48fddfb4 100644 --- a/code/modules/client/client_defines.dm +++ b/code/modules/client/client_defines.dm @@ -30,6 +30,9 @@ var/move_delay = 0 var/area = null + /// Last time we Click()ed. No clicking twice in one tick! + var/last_click = 0 + /////////////// //SOUND STUFF// /////////////// diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm index 40c159ecf0..5c9b1eec2e 100644 --- a/code/modules/client/client_procs.dm +++ b/code/modules/client/client_procs.dm @@ -774,6 +774,9 @@ GLOBAL_LIST_EMPTY(external_rsc_urls) ip_intel = res.intel /client/Click(atom/object, atom/location, control, params, ignore_spam = FALSE) + if(last_click > world.time - world.tick_lag) + return + last_click = world.time var/ab = FALSE var/list/L = params2list(params) if (object && object == middragatom && L["left"]) diff --git a/code/modules/clothing/glasses/disablerglasses.dm b/code/modules/clothing/glasses/disablerglasses.dm index a46e4c8339..51fb1cec87 100644 --- a/code/modules/clothing/glasses/disablerglasses.dm +++ b/code/modules/clothing/glasses/disablerglasses.dm @@ -4,7 +4,9 @@ var/beamtype = /obj/item/projectile/beam/disabler //change for adminbus /obj/item/clothing/glasses/hud/security/sunglasses/disablers/ranged_attack(mob/living/carbon/human/user,atom/A, params) - user.changeNext_move(CLICK_CD_RANGE) + if(!user.CheckActionCooldown(CLICK_CD_RANGE)) + return + user.last_action = world.time var/obj/item/projectile/beam/disabler/LE = new beamtype( loc ) playsound(usr.loc, 'sound/weapons/taser2.ogg', 75, 1) LE.firer = src @@ -12,4 +14,4 @@ LE.preparePixelProjectile(A, src, params) LE.fire() return TRUE - //shamelessly copied \ No newline at end of file + //shamelessly copied diff --git a/code/modules/clothing/gloves/miscellaneous.dm b/code/modules/clothing/gloves/miscellaneous.dm index dd03eea66f..1c3ac0f340 100644 --- a/code/modules/clothing/gloves/miscellaneous.dm +++ b/code/modules/clothing/gloves/miscellaneous.dm @@ -105,11 +105,11 @@ return var/mob/living/M = loc - M.changeNext_move(CLICK_CD_RAPID) + M.SetNextAction(CLICK_CD_RAPID) if(warcry) M.say("[warcry]", ignore_spam = TRUE, forced = TRUE) - return FALSE + return NO_AUTO_CLICKDELAY_HANDLING | ATTACK_IGNORE_ACTION /obj/item/clothing/gloves/fingerless/pugilist/rapid/AltClick(mob/user) var/input = stripped_input(user,"What do you want your battlecry to be? Max length of 6 characters.", ,"", 7) @@ -135,9 +135,9 @@ if(target.stat != CONSCIOUS) //Can't hug people who are dying/dead return FALSE else - M.changeNext_move(CLICK_CD_RAPID) + M.SetNextAction(CLICK_CD_RAPID) - return FALSE + return NO_AUTO_CLICKDELAY_HANDLING | ATTACK_IGNORE_ACTION /obj/item/clothing/gloves/botanic_leather name = "botanist's leather gloves" diff --git a/code/modules/clothing/head/misc_special.dm b/code/modules/clothing/head/misc_special.dm index 1d9c3dd325..3774ce575f 100644 --- a/code/modules/clothing/head/misc_special.dm +++ b/code/modules/clothing/head/misc_special.dm @@ -290,7 +290,7 @@ if(!target.IsUnconscious()) to_chat(target, "Your zealous conspirationism rapidly dissipates as the donned hat warps up into a ruined mess. All those theories starting to sound like nothing but a ridicolous fanfare.") -/obj/item/clothing/head/foilhat/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/item/clothing/head/foilhat/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(!warped && iscarbon(user)) var/mob/living/carbon/C = user if(src == C.head) diff --git a/code/modules/clothing/neck/_neck.dm b/code/modules/clothing/neck/_neck.dm index c3934aa78c..51a526d089 100644 --- a/code/modules/clothing/neck/_neck.dm +++ b/code/modules/clothing/neck/_neck.dm @@ -219,7 +219,7 @@ lock = TRUE return -/obj/item/clothing/neck/petcollar/locked/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/item/clothing/neck/petcollar/locked/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(loc == user && user.get_item_by_slot(SLOT_NECK) && lock != FALSE) to_chat(user, "The collar is locked! You'll need unlock the collar before you can take it off!") return diff --git a/code/modules/clothing/shoes/_shoes.dm b/code/modules/clothing/shoes/_shoes.dm index d67aea11a1..746bd3458a 100644 --- a/code/modules/clothing/shoes/_shoes.dm +++ b/code/modules/clothing/shoes/_shoes.dm @@ -20,6 +20,15 @@ var/last_blood_DNA = "" //same as last one var/last_blood_color = "" + ///Whether these shoes have laces that can be tied/untied + var/can_be_tied = TRUE + ///Are we currently tied? Can either be SHOES_UNTIED, SHOES_TIED, or SHOES_KNOTTED + var/tied = SHOES_TIED + ///How long it takes to lace/unlace these shoes + var/lace_time = 5 SECONDS + ///any alerts we have active + var/obj/screen/alert/our_alert + /obj/item/clothing/shoes/ComponentInitialize() . = ..() RegisterSignal(src, COMSIG_COMPONENT_CLEAN_ACT, /atom.proc/clean_blood) @@ -43,6 +52,15 @@ playsound(user, 'sound/weapons/genhit2.ogg', 50, 1) return(BRUTELOSS) +/obj/item/clothing/shoes/examine(mob/user) + . = ..() + + if(!ishuman(loc)) + return ..() + if(tied == SHOES_UNTIED) + . += "The shoelaces are untied." + else if(tied == SHOES_KNOTTED) + . += "The shoelaces are all knotted together." /obj/item/clothing/shoes/transfer_blood_dna(list/blood_dna, diseases) ..() @@ -74,6 +92,9 @@ worn_y_dimension -= (offset * 2) user.update_inv_shoes() equipped_before_drop = TRUE + if(can_be_tied && tied == SHOES_UNTIED) + our_alert = user.throw_alert("shoealert", /obj/screen/alert/shoes/untied) + RegisterSignal(src, COMSIG_SHOES_STEP_ACTION, .proc/check_trip, override=TRUE) /obj/item/clothing/shoes/proc/restore_offsets(mob/user) equipped_before_drop = FALSE @@ -81,6 +102,8 @@ worn_y_dimension = world.icon_size /obj/item/clothing/shoes/dropped(mob/user) + if(our_alert && (our_alert.mob_viewer == user)) + user.clear_alert("shoealert") if(offset && equipped_before_drop) restore_offsets(user) . = ..() @@ -101,3 +124,167 @@ /obj/item/proc/negates_gravity() return FALSE + +/** + * adjust_laces adjusts whether our shoes (assuming they can_be_tied) and tied, untied, or knotted + * + * In addition to setting the state, it will deal with getting rid of alerts if they exist, as well as registering and unregistering the stepping signals + * + * Arguments: + * * + * * state: SHOES_UNTIED, SHOES_TIED, or SHOES_KNOTTED, depending on what you want them to become + * * user: used to check to see if we're the ones unknotting our own laces + */ +/obj/item/clothing/shoes/proc/adjust_laces(state, mob/user) + if(!can_be_tied) + return + + var/mob/living/carbon/human/our_guy + if(ishuman(loc)) + our_guy = loc + + tied = state + if(tied == SHOES_TIED) + if(our_guy) + our_guy.clear_alert("shoealert") + UnregisterSignal(src, COMSIG_SHOES_STEP_ACTION) + else + if(tied == SHOES_UNTIED && our_guy && user == our_guy) + our_alert = our_guy.throw_alert("shoealert", /obj/screen/alert/shoes/untied) // if we're the ones unknotting our own laces, of course we know they're untied + RegisterSignal(src, COMSIG_SHOES_STEP_ACTION, .proc/check_trip, override=TRUE) + +/** + * handle_tying deals with all the actual tying/untying/knotting, inferring your intent from who you are in relation to the state of the laces + * + * If you're the wearer, you want them to move towards tied-ness (knotted -> untied -> tied). If you're not, you're pranking them, so you're moving towards knotted-ness (tied -> untied -> knotted) + * + * Arguments: + * * + * * user: who is the person interacting with the shoes? + */ +/obj/item/clothing/shoes/proc/handle_tying(mob/user) + ///our_guy here is the wearer, if one exists (and he must exist, or we don't care) + var/mob/living/carbon/human/our_guy = loc + if(!istype(our_guy)) + return + + if(!in_range(user, our_guy)) + to_chat(user, "You aren't close enough to interact with [src]'s laces!") + return + + if(user == loc && tied != SHOES_TIED) // if they're our own shoes, go tie-wards + if(INTERACTING_WITH(user, our_guy)) + to_chat(user, "You're already interacting with [src]!") + return + user.visible_message("[user] begins [tied ? "unknotting" : "tying"] the laces of [user.p_their()] [src.name].", "You begin [tied ? "unknotting" : "tying"] the laces of your [src.name]...") + + if(do_after(user, lace_time, needhand=TRUE, target=our_guy, extra_checks=CALLBACK(src, .proc/still_shoed, our_guy))) + to_chat(user, "You [tied ? "unknot" : "tie"] the laces of your [src.name].") + if(tied == SHOES_UNTIED) + adjust_laces(SHOES_TIED, user) + else + adjust_laces(SHOES_UNTIED, user) + + else // if they're someone else's shoes, go knot-wards + var/mob/living/L = user + if(istype(L) && (L.mobility_flags & MOBILITY_STAND)) + to_chat(user, "You must be on the floor to interact with [src]!") + return + if(tied == SHOES_KNOTTED) + to_chat(user, "The laces on [loc]'s [src.name] are already a hopelessly tangled mess!") + return + if(INTERACTING_WITH(user, our_guy)) + to_chat(user, "You're already interacting with [src]!") + return + + var/mod_time = lace_time + to_chat(user, "You quietly set to work [tied ? "untying" : "knotting"] [loc]'s [src.name]...") + if(HAS_TRAIT(user, TRAIT_CLUMSY)) // based clowns trained their whole lives for this + mod_time *= 0.75 + + if(do_after(user, mod_time, needhand=TRUE, target=our_guy, extra_checks=CALLBACK(src, .proc/still_shoed, our_guy))) + to_chat(user, "You [tied ? "untie" : "knot"] the laces on [loc]'s [src.name].") + if(tied == SHOES_UNTIED) + adjust_laces(SHOES_KNOTTED, user) + else + adjust_laces(SHOES_UNTIED, user) + else // if one of us moved + user.visible_message("[our_guy] stamps on [user]'s hand, mid-shoelace [tied ? "knotting" : "untying"]!", "Ow! [our_guy] stamps on your hand!", list(our_guy)) + to_chat(our_guy, "You stamp on [user]'s hand! What the- [user.p_they()] [user.p_were()] [tied ? "knotting" : "untying"] your shoelaces!") + user.emote("scream") + if(istype(L)) + var/obj/item/bodypart/ouchie = L.get_bodypart(pick(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM)) + if(ouchie) + ouchie.receive_damage(brute = 10, stamina = 40) + L.Paralyze(10) + +///checking to make sure we're still on the person we're supposed to be, for lacing do_after's +/obj/item/clothing/shoes/proc/still_shoed(mob/living/carbon/our_guy) + return (loc == our_guy) + +///check_trip runs on each step to see if we fall over as a result of our lace status. Knotted laces are a guaranteed trip, while untied shoes are just a chance to stumble +/obj/item/clothing/shoes/proc/check_trip() + var/mob/living/carbon/human/our_guy = loc + if(!istype(our_guy)) // are they REALLY /our guy/? + return + + if(tied == SHOES_KNOTTED) + our_guy.Paralyze(5) + our_guy.Knockdown(10) + our_guy.visible_message("[our_guy] trips on [our_guy.p_their()] knotted shoelaces and falls! What a klutz!", "You trip on your knotted shoelaces and fall over!") + SEND_SIGNAL(our_guy, COMSIG_ADD_MOOD_EVENT, "trip", /datum/mood_event/tripped) // well we realized they're knotted now! + our_alert = our_guy.throw_alert("shoealert", /obj/screen/alert/shoes/knotted) + + else if(tied == SHOES_UNTIED) + var/wiser = TRUE // did we stumble and realize our laces are undone? + switch(rand(1, 1000)) + if(1) // .1% chance to trip and fall over (note these are per step while our laces are undone) + our_guy.Paralyze(5) + our_guy.Knockdown(10) + SEND_SIGNAL(our_guy, COMSIG_ADD_MOOD_EVENT, "trip", /datum/mood_event/tripped) // well we realized they're knotted now! + our_guy.visible_message("[our_guy] trips on [our_guy.p_their()] untied shoelaces and falls! What a klutz!", "You trip on your untied shoelaces and fall over!") + + if(2 to 5) // .4% chance to stumble and lurch forward + our_guy.throw_at(get_step(our_guy, our_guy.dir), 3, 2) + to_chat(our_guy, "You stumble on your untied shoelaces and lurch forward!") + + if(6 to 13) // .7% chance to stumble and fling what we're holding + var/have_anything = FALSE + for(var/obj/item/I in our_guy.held_items) + have_anything = TRUE + our_guy.accident(I) + to_chat(our_guy, "You trip on your shoelaces a bit[have_anything ? ", flinging what you were holding" : ""]!") + + if(14 to 25) // 1.3ish% chance to stumble and be a bit off balance (like being disarmed) + to_chat(our_guy, "You stumble a bit on your untied shoelaces!") + if(!our_guy.has_movespeed_modifier(/datum/movespeed_modifier/shove)) + our_guy.add_movespeed_modifier(/datum/movespeed_modifier/shove) + addtimer(CALLBACK(our_guy, /mob/living/carbon/human/proc/clear_shove_slowdown), SHOVE_SLOWDOWN_LENGTH) + + if(26 to 1000) + wiser = FALSE + if(wiser) + SEND_SIGNAL(our_guy, COMSIG_ADD_MOOD_EVENT, "untied", /datum/mood_event/untied) // well we realized they're untied now! + our_alert = our_guy.throw_alert("shoealert", /obj/screen/alert/shoes/untied) + + +/obj/item/clothing/shoes/on_attack_hand(mob/living/user, act_intent, unarmed_attack_flags) + if(!istype(user)) + return ..() + if(loc == user && tied != SHOES_TIED && (user.mobility_flags & MOBILITY_USE)) + handle_tying(user) + return + return ..() + +/obj/item/clothing/shoes/attack_self(mob/user) + . = ..() + + if(INTERACTING_WITH(user, src)) + to_chat(user, "You're already interacting with [src]!") + return + + to_chat(user, "You begin [tied ? "untying" : "tying"] the laces on [src]...") + + if(do_after(user, lace_time, needhand=TRUE, target=src,extra_checks=CALLBACK(src, .proc/still_shoed, user))) + to_chat(user, "You [tied ? "untie" : "tie"] the laces on [src].") + adjust_laces(tied ? SHOES_TIED : SHOES_UNTIED, user) diff --git a/code/modules/clothing/shoes/miscellaneous.dm b/code/modules/clothing/shoes/miscellaneous.dm index b68bef6329..b0d760ebd9 100644 --- a/code/modules/clothing/shoes/miscellaneous.dm +++ b/code/modules/clothing/shoes/miscellaneous.dm @@ -17,6 +17,7 @@ resistance_flags = NONE permeability_coefficient = 0.05 //Thick soles, and covers the ankle pocket_storage_component_path = /datum/component/storage/concrete/pockets/shoes + lace_time = 12 SECONDS /obj/item/clothing/shoes/combat/sneakboots name = "insidious sneakboots" @@ -49,6 +50,7 @@ strip_delay = 50 equip_delay_other = 50 permeability_coefficient = 0.9 + can_be_tied = FALSE /obj/item/clothing/shoes/sandal/marisa desc = "A pair of magic black shoes." @@ -73,6 +75,7 @@ resistance_flags = NONE armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 40, "acid" = 75) custom_price = PRICE_ABOVE_EXPENSIVE + can_be_tied = FALSE /obj/item/clothing/shoes/galoshes/dry name = "absorbent galoshes" @@ -99,6 +102,7 @@ icon_state = "clown_shoes" slowdown = SHOES_SLOWDOWN+1 pocket_storage_component_path = /datum/component/storage/concrete/pockets/shoes/clown + lace_time = 20 SECONDS // how the hell do these laces even work?? /obj/item/clothing/shoes/clown_shoes/Initialize() . = ..() @@ -130,6 +134,7 @@ resistance_flags = NONE permeability_coefficient = 0.05 //Thick soles, and covers the ankle pocket_storage_component_path = /datum/component/storage/concrete/pockets/shoes + lace_time = 12 SECONDS /obj/item/clothing/shoes/jackboots/fast slowdown = -1 @@ -144,6 +149,7 @@ heat_protection = FEET|LEGS max_heat_protection_temperature = SHOES_MAX_TEMP_PROTECT pocket_storage_component_path = /datum/component/storage/concrete/pockets/shoes + lace_time = 8 SECONDS /obj/item/clothing/shoes/winterboots/ice_boots name = "ice hiking boots" @@ -177,6 +183,7 @@ strip_delay = 40 equip_delay_other = 40 pocket_storage_component_path = /datum/component/storage/concrete/pockets/shoes + lace_time = 8 SECONDS /obj/item/clothing/shoes/workboots/mining name = "mining boots" @@ -196,6 +203,7 @@ min_cold_protection_temperature = SHOES_MIN_TEMP_PROTECT heat_protection = FEET max_heat_protection_temperature = SHOES_MAX_TEMP_PROTECT + lace_time = 10 SECONDS /obj/item/clothing/shoes/cult/alt name = "cultist boots" @@ -226,12 +234,14 @@ strip_delay = 100 equip_delay_other = 100 permeability_coefficient = 0.9 + can_be_tied = FALSE /obj/item/clothing/shoes/griffin name = "griffon boots" desc = "A pair of costume boots fashioned after bird talons." icon_state = "griffinboots" pocket_storage_component_path = /datum/component/storage/concrete/pockets/shoes + lace_time = 8 SECONDS /obj/item/clothing/shoes/bhop name = "jump boots" @@ -284,6 +294,7 @@ desc = "A giant, clunky pair of shoes crudely made out of bronze. Why would anyone wear these?" icon = 'icons/obj/clothing/clockwork_garb.dmi' icon_state = "clockwork_treads" + lace_time = 8 SECONDS /obj/item/clothing/shoes/bronze/Initialize() . = ..() @@ -358,6 +369,7 @@ icon_state = "rus_shoes" item_state = "rus_shoes" pocket_storage_component_path = /datum/component/storage/concrete/pockets/shoes + lace_time = 8 SECONDS // kevin is into feet /obj/item/clothing/shoes/wraps @@ -365,6 +377,7 @@ desc = "Ankle coverings. These ones have a golden design." icon_state = "gildedcuffs" body_parts_covered = FALSE + can_be_tied = FALSE /obj/item/clothing/shoes/wraps/silver name = "silver leg wraps" @@ -385,6 +398,7 @@ name = "cowboy boots" desc = "A standard pair of brown cowboy boots." icon_state = "cowboyboots" + can_be_tied = FALSE /obj/item/clothing/shoes/cowboyboots/black name = "black cowboy boots" diff --git a/code/modules/clothing/spacesuits/chronosuit.dm b/code/modules/clothing/spacesuits/chronosuit.dm index 4590d46219..4dc6fd1f6c 100644 --- a/code/modules/clothing/spacesuits/chronosuit.dm +++ b/code/modules/clothing/spacesuits/chronosuit.dm @@ -80,7 +80,7 @@ if(to_turf) user.forceMove(to_turf) user.SetStun(0) - user.next_move = 1 + user.SetNextAction(0, considered_action = FALSE, immediate = FALSE) user.alpha = 255 user.update_atom_colour() user.animate_movement = FORWARD_STEPS @@ -124,8 +124,8 @@ for(var/obj/item/I in user.held_items) ADD_TRAIT(I, TRAIT_NODROP, CHRONOSUIT_TRAIT) user.animate_movement = NO_STEPS - user.changeNext_move(8 + phase_in_ds) - user.mob_transforming = 1 + user.DelayNextAction(8 + phase_in_ds, considered_action = FALSE, immediate = FALSE) + user.mob_transforming = TRUE user.anchored = TRUE user.Stun(INFINITY) diff --git a/code/modules/clothing/spacesuits/hardsuit.dm b/code/modules/clothing/spacesuits/hardsuit.dm index f563c1029d..b588deaf01 100644 --- a/code/modules/clothing/spacesuits/hardsuit.dm +++ b/code/modules/clothing/spacesuits/hardsuit.dm @@ -107,11 +107,7 @@ /obj/item/clothing/suit/space/hardsuit/Initialize() if(jetpack && ispath(jetpack)) jetpack = new jetpack(src) - . = ..() - -/obj/item/clothing/suit/space/hardsuit/attack_self(mob/user) - user.changeNext_move(CLICK_CD_MELEE) - ..() + return ..() /obj/item/clothing/suit/space/hardsuit/attackby(obj/item/I, mob/user, params) if(istype(I, /obj/item/tank/jetpack/suit)) diff --git a/code/modules/clothing/under/syndicate.dm b/code/modules/clothing/under/syndicate.dm index 8a88e99d05..6a6c38d26e 100644 --- a/code/modules/clothing/under/syndicate.dm +++ b/code/modules/clothing/under/syndicate.dm @@ -73,6 +73,9 @@ item_state = "g_suit" can_adjust = FALSE +/obj/item/clothing/under/syndicate/camo/cosmetic + armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) + /obj/item/clothing/under/syndicate/soviet name = "Ratnik 5 tracksuit" desc = "Badly translated labels tell you to clean this in Vodka. Great for squatting in." diff --git a/code/modules/events/immovable_rod.dm b/code/modules/events/immovable_rod.dm index cf2ac93360..89511a7b15 100644 --- a/code/modules/events/immovable_rod.dm +++ b/code/modules/events/immovable_rod.dm @@ -143,7 +143,7 @@ In my current plan for it, 'solid' will be defined as anything with density == 1 if(L && (L.density || prob(10))) L.ex_act(EXPLODE_HEAVY) -obj/effect/immovablerod/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) +obj/effect/immovablerod/on_attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) if(ishuman(user)) var/mob/living/carbon/human/U = user if(U.job in list("Research Director")) diff --git a/code/modules/events/spacevine.dm b/code/modules/events/spacevine.dm index ad786561f4..7cf11848e8 100644 --- a/code/modules/events/spacevine.dm +++ b/code/modules/events/spacevine.dm @@ -324,7 +324,7 @@ damage_dealt *= 4 if(I.damtype == BURN) damage_dealt *= 4 - + user.DelayNextAction() for(var/datum/spacevine_mutation/SM in mutations) damage_dealt = SM.on_hit(src, user, I, damage_dealt) //on_hit now takes override damage as arg and returns new value for other mutations to permutate further take_damage(damage_dealt, I.damtype, "melee", 1) @@ -345,8 +345,7 @@ for(var/datum/spacevine_mutation/SM in mutations) SM.on_cross(src, AM) -//ATTACK HAND IGNORING PARENT RETURN VALUE -/obj/structure/spacevine/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/structure/spacevine/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) for(var/datum/spacevine_mutation/SM in mutations) SM.on_hit(src, user) user_unbuckle_mob(user, user) @@ -356,6 +355,7 @@ for(var/datum/spacevine_mutation/SM in mutations) SM.on_hit(src, user) user_unbuckle_mob(user,user) + return ..() /obj/structure/spacevine/attack_alien(mob/living/user) eat(user) diff --git a/code/modules/events/travelling_trader.dm b/code/modules/events/travelling_trader.dm index b7afc3440e..08dae1b469 100644 --- a/code/modules/events/travelling_trader.dm +++ b/code/modules/events/travelling_trader.dm @@ -60,7 +60,7 @@ input_speech = replacetext(input_speech, "given_item", given_item.name) return input_speech -/mob/living/carbon/human/dummy/travelling_trader/attack_hand(mob/living/carbon/human/H) +/mob/living/carbon/human/dummy/travelling_trader/on_attack_hand(mob/living/carbon/human/H) if(active && last_speech + 3 < world.realtime) //can only talk once per 3 seconds, to avoid spam last_speech = world.realtime if(initial_speech) @@ -282,6 +282,7 @@ mob/living/carbon/human/dummy/travelling_trader/animal_hunter/Initialize() ..() /datum/outfit/artifact_dealer + name = "Artifact Dealer" uniform = /obj/item/clothing/under/suit/black_really shoes = /obj/item/clothing/shoes/combat head = /obj/item/clothing/head/that @@ -323,6 +324,7 @@ mob/living/carbon/human/dummy/travelling_trader/animal_hunter/Initialize() reward.insert_organ(new_implant) /datum/outfit/otherworldly_surgeon + name = "Otherworldly Surgeon" uniform = /obj/item/clothing/under/pants/white shoes = /obj/item/clothing/shoes/sneakers/white gloves = /obj/item/clothing/gloves/color/latex diff --git a/code/modules/food_and_drinks/drinks/drinks.dm b/code/modules/food_and_drinks/drinks/drinks.dm index 2e68c57abd..45ab6f6af1 100644 --- a/code/modules/food_and_drinks/drinks/drinks.dm +++ b/code/modules/food_and_drinks/drinks/drinks.dm @@ -23,7 +23,6 @@ gulp_size = max(round(reagents.total_volume / 5), 5) /obj/item/reagent_containers/food/drinks/attack(mob/living/M, mob/user, def_zone) - if(!reagents || !reagents.total_volume) to_chat(user, "[src] is empty!") return 0 @@ -37,9 +36,6 @@ if(M == user) user.visible_message("[user] swallows a gulp of [src].", "You swallow a gulp of [src].") - if(HAS_TRAIT(M, TRAIT_VORACIOUS)) - M.changeNext_move(CLICK_CD_MELEE * 0.5) //chug! chug! chug! - else M.visible_message("[user] attempts to feed the contents of [src] to [M].", "[user] attempts to feed the contents of [src] to [M].") if(!do_mob(user, M)) @@ -56,6 +52,10 @@ playsound(M.loc,'sound/items/drink.ogg', rand(10,50), 1) return 1 +/obj/item/reagent_containers/food/drinks/CheckAttackCooldown(mob/user, atom/target) + var/fast = HAS_TRAIT(user, TRAIT_VORACIOUS) && (user == target) + return user.CheckActionCooldown(fast? CLICK_CD_RANGE : CLICK_CD_MELEE) + /obj/item/reagent_containers/food/drinks/afterattack(obj/target, mob/user , proximity) . = ..() if(!proximity) diff --git a/code/modules/food_and_drinks/food/snacks.dm b/code/modules/food_and_drinks/food/snacks.dm index adb8e47c94..4b79dc1fd4 100644 --- a/code/modules/food_and_drinks/food/snacks.dm +++ b/code/modules/food_and_drinks/food/snacks.dm @@ -129,8 +129,6 @@ All foods are distributed among various categories. Use common sense. else if(fullness > (600 * (1 + M.overeatduration / 2000))) // The more you eat - the more you can eat user.visible_message("[user] cannot force any more of \the [src] to go down [user.p_their()] throat!", "You cannot force any more of \the [src] to go down your throat!") return 0 - if(HAS_TRAIT(M, TRAIT_VORACIOUS)) - M.changeNext_move(CLICK_CD_MELEE * 0.5) //nom nom nom else if(!isbrain(M)) //If you're feeding it to someone else. if(fullness <= (600 * (1 + M.overeatduration / 1000))) @@ -167,6 +165,10 @@ All foods are distributed among various categories. Use common sense. return 0 +/obj/item/reagent_containers/food/snacks/CheckAttackCooldown(mob/user, atom/target) + var/fast = HAS_TRAIT(user, TRAIT_VORACIOUS) && (user == target) + return user.CheckActionCooldown(fast? CLICK_CD_RANGE : CLICK_CD_MELEE) + /obj/item/reagent_containers/food/snacks/examine(mob/user) . = ..() if(food_quality >= 70) diff --git a/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm b/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm index f3c63c1ba2..fecc9467a1 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm @@ -130,7 +130,7 @@ God bless America. /obj/machinery/deepfryer/attack_ai(mob/user) return -/obj/machinery/deepfryer/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/machinery/deepfryer/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(frying) if(frying.loc == src) to_chat(user, "You eject [frying] from [src].") @@ -146,6 +146,8 @@ God bless America. fry_loop.stop() return else if(user.pulling && user.a_intent == "grab" && iscarbon(user.pulling) && reagents.total_volume) + if(!user.CheckActionCooldown(CLICK_CD_MELEE)) + return if(user.grab_state < GRAB_AGGRESSIVE) to_chat(user, "You need a better grip to do that!") return @@ -155,5 +157,5 @@ God bless America. C.apply_damage(min(30, reagents.total_volume), BURN, BODY_ZONE_HEAD) reagents.remove_any((reagents.total_volume/2)) C.DefaultCombatKnockdown(60) - user.changeNext_move(CLICK_CD_MELEE) + user.DelayNextAction() return ..() diff --git a/code/modules/food_and_drinks/kitchen_machinery/gibber.dm b/code/modules/food_and_drinks/kitchen_machinery/gibber.dm index 53da7326a2..e4148d849a 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/gibber.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/gibber.dm @@ -63,10 +63,7 @@ /obj/machinery/gibber/relaymove(mob/living/user) go_out() -/obj/machinery/gibber/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) - . = ..() - if(.) - return +/obj/machinery/gibber/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(stat & (NOPOWER|BROKEN)) return if(operating) diff --git a/code/modules/food_and_drinks/kitchen_machinery/grill.dm b/code/modules/food_and_drinks/kitchen_machinery/grill.dm index a5a90b33e4..09e1d7b1c6 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/grill.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/grill.dm @@ -107,7 +107,7 @@ /obj/machinery/grill/attack_ai(mob/user) return -/obj/machinery/grill/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/machinery/grill/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(grilled_item) to_chat(user, "You take out [grilled_item] from [src].") grilled_item.forceMove(drop_location()) diff --git a/code/modules/food_and_drinks/pizzabox.dm b/code/modules/food_and_drinks/pizzabox.dm index 006c3fb6ad..a2603d07ab 100644 --- a/code/modules/food_and_drinks/pizzabox.dm +++ b/code/modules/food_and_drinks/pizzabox.dm @@ -106,8 +106,7 @@ START_PROCESSING(SSobj, src) update_icon() -//ATTACK HAND IGNORING PARENT RETURN VALUE -/obj/item/pizzabox/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/item/pizzabox/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(user.get_inactive_held_item() != src) return ..() if(open) diff --git a/code/modules/holiday/halloween/bartholomew.dm b/code/modules/holiday/halloween/bartholomew.dm index eb90a0c82d..c9a4a946a3 100644 --- a/code/modules/holiday/halloween/bartholomew.dm +++ b/code/modules/holiday/halloween/bartholomew.dm @@ -31,7 +31,7 @@ return say("It doesn't seem like that's magical enough!") -/obj/item/barthpot/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/item/barthpot/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(!active) say("Meow!") return diff --git a/code/modules/holiday/halloween/jacqueen.dm b/code/modules/holiday/halloween/jacqueen.dm index 01e71d1129..4561e0ae3e 100644 --- a/code/modules/holiday/halloween/jacqueen.dm +++ b/code/modules/holiday/halloween/jacqueen.dm @@ -76,7 +76,7 @@ health = 25 poof() -/mob/living/simple_animal/jacq/attack_hand(mob/living/carbon/human/M) +/mob/living/simple_animal/jacq/on_attack_hand(mob/living/carbon/human/M) if(!active) say("Hello there [gender_check(M)]!") return ..() @@ -406,14 +406,14 @@ . = ..() ADD_TRAIT(src, TRAIT_NODROP, GLUED_ITEM_TRAIT) -/obj/item/clothing/suit/ghost_sheet/sticky/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/item/clothing/suit/ghost_sheet/sticky/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(iscarbon(user)) to_chat(user, "Boooooo~!") return else ..() -/obj/item/clothing/suit/ghost_sheet/sticky/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/item/clothing/suit/ghost_sheet/sticky/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(iscarbon(user)) to_chat(user, "Boooooo~!") return diff --git a/code/modules/holodeck/items.dm b/code/modules/holodeck/items.dm index b6c89bcf0e..e4564ecb7e 100644 --- a/code/modules/holodeck/items.dm +++ b/code/modules/holodeck/items.dm @@ -105,10 +105,7 @@ if(user.transferItemToLoc(W, drop_location())) visible_message(" [user] dunks [W] into \the [src]!") -/obj/structure/holohoop/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) - . = ..() - if(.) - return +/obj/structure/holohoop/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(user.pulling && user.a_intent == INTENT_GRAB && isliving(user.pulling)) var/mob/living/L = user.pulling if(user.grab_state < GRAB_AGGRESSIVE) @@ -164,7 +161,7 @@ /obj/machinery/readybutton/attackby(obj/item/W as obj, mob/user as mob, params) to_chat(user, "The device is a solid button, there's nothing you can do with it!") -/obj/machinery/readybutton/attack_hand(mob/user as mob) +/obj/machinery/readybutton/on_attack_hand(mob/user as mob) . = ..() if(.) return diff --git a/code/modules/holodeck/turfs.dm b/code/modules/holodeck/turfs.dm index f686bee63a..169c9061d3 100644 --- a/code/modules/holodeck/turfs.dm +++ b/code/modules/holodeck/turfs.dm @@ -134,7 +134,7 @@ tiled_dirt = FALSE baseturfs = /turf/open/floor/holofloor/snow -/turf/open/floor/holofloor/snow/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) +/turf/open/floor/holofloor/snow/on_attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/modules/hydroponics/fermenting_barrel.dm b/code/modules/hydroponics/fermenting_barrel.dm index 70e204a14f..76e36a1725 100644 --- a/code/modules/hydroponics/fermenting_barrel.dm +++ b/code/modules/hydroponics/fermenting_barrel.dm @@ -56,7 +56,7 @@ else return ..() -/obj/structure/fermenting_barrel/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/structure/fermenting_barrel/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) open = !open if(open) DISABLE_BITFIELD(reagents.reagents_holder_flags, DRAINABLE) diff --git a/code/modules/hydroponics/grown/chili.dm b/code/modules/hydroponics/grown/chili.dm index 42674029fb..1f60afe655 100644 --- a/code/modules/hydroponics/grown/chili.dm +++ b/code/modules/hydroponics/grown/chili.dm @@ -80,10 +80,7 @@ foodtype = FRUIT wine_power = 50 -/obj/item/reagent_containers/food/snacks/grown/ghost_chili/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) - . = ..() - if(.) - return +/obj/item/reagent_containers/food/snacks/grown/ghost_chili/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if( ismob(loc) ) held_mob = loc START_PROCESSING(SSobj, src) diff --git a/code/modules/hydroponics/grown/replicapod.dm b/code/modules/hydroponics/grown/replicapod.dm index 78fddbd989..328b4c391c 100644 --- a/code/modules/hydroponics/grown/replicapod.dm +++ b/code/modules/hydroponics/grown/replicapod.dm @@ -29,6 +29,28 @@ create_reagents(volume, INJECTABLE | DRAWABLE) +/obj/item/seeds/replicapod/pre_attack(obj/machinery/hydroponics/I) + if(istype(I, /obj/machinery/hydroponics)) + if(!I.myseed) + START_PROCESSING(SSobj, src) + return ..() + +/obj/item/seeds/replicapod/proc/check_mind_orbiting(atom/A) + for(var/mob/M in A.orbiters?.orbiters) + if(mind && M.mind && ckey(M.mind.key) == ckey(mind.key) && M.ckey && M.client && M.stat == DEAD && !M.suiciding && isobserver(M)) + return TRUE + return FALSE + +/obj/item/seeds/replicapod/process() + var/obj/machinery/hydroponics/parent = loc + if(parent.harvest != 1) + return + if (check_mind_orbiting(parent)) + icon_harvest = "replicapod-orbit" + else + icon_harvest = "replicapod-harvest" + parent.update_icon_plant() + /obj/item/seeds/replicapod/on_reagent_change(changetype) if(changetype == ADD_REAGENT) var/datum/reagent/blood/B = reagents.has_reagent(/datum/reagent/blood) @@ -59,8 +81,11 @@ /obj/item/seeds/replicapod/get_analyzer_text() var/text = ..() + var/obj/machinery/hydroponics/parent = loc if(contains_sample) text += "\n It contains a blood sample!" + if (parent && istype(parent) && check_mind_orbiting(parent)) + text += "\n The soul is ready to enter the body." return text @@ -115,7 +140,7 @@ features["mcolor"] = "#59CE00" for(var/V in quirks) new V(podman) - podman.hardset_dna(null,null,null,podman.real_name,blood_type, new /datum/species/pod,features)//Discard SE's and UI's, podman cloning is inaccurate, and always make them a podman + podman.hardset_dna(null,null,podman.real_name,blood_type, new /datum/species/pod,features)//Discard SE's and UI's, podman cloning is inaccurate, and always make them a podman podman.set_cloned_appearance() else //else, one packet of seeds. maybe two diff --git a/code/modules/hydroponics/grown/towercap.dm b/code/modules/hydroponics/grown/towercap.dm index 164c27d105..ecbfa7584b 100644 --- a/code/modules/hydroponics/grown/towercap.dm +++ b/code/modules/hydroponics/grown/towercap.dm @@ -207,10 +207,7 @@ return ..() -/obj/structure/bonfire/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) - . = ..() - if(.) - return +/obj/structure/bonfire/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(burning) to_chat(user, "You need to extinguish [src] before removing the logs!") return diff --git a/code/modules/hydroponics/hydroponics.dm b/code/modules/hydroponics/hydroponics.dm index b673937c9c..06179d1087 100644 --- a/code/modules/hydroponics/hydroponics.dm +++ b/code/modules/hydroponics/hydroponics.dm @@ -888,10 +888,7 @@ return ..() -/obj/machinery/hydroponics/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) - . = ..() - if(.) - return +/obj/machinery/hydroponics/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(issilicon(user)) //How does AI know what plant is? return if(harvest) diff --git a/code/modules/integrated_electronics/core/assemblies.dm b/code/modules/integrated_electronics/core/assemblies.dm index c3e0a7abcc..7c9f811c34 100644 --- a/code/modules/integrated_electronics/core/assemblies.dm +++ b/code/modules/integrated_electronics/core/assemblies.dm @@ -519,6 +519,7 @@ /obj/item/electronic_assembly/attack_self(mob/user) + set waitfor = FALSE if(!check_interactivity(user)) return if(opened) @@ -611,7 +612,7 @@ return ..() -/obj/item/electronic_assembly/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/item/electronic_assembly/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(anchored) attack_self(user) return diff --git a/code/modules/integrated_electronics/subtypes/weaponized.dm b/code/modules/integrated_electronics/subtypes/weaponized.dm index 950525ab7f..96a732d08f 100644 --- a/code/modules/integrated_electronics/subtypes/weaponized.dm +++ b/code/modules/integrated_electronics/subtypes/weaponized.dm @@ -45,6 +45,9 @@ /obj/item/integrated_circuit/weaponized/weapon_firing/attackby(var/obj/O, var/mob/user) if(istype(O, /obj/item/gun/energy)) var/obj/item/gun/gun = O + if(!gun.can_circuit) + to_chat(user, "[gun] does not fit into circuits.") + return if(installed_gun) to_chat(user, "There's already a weapon installed.") return diff --git a/code/modules/library/lib_items.dm b/code/modules/library/lib_items.dm index e5d9672d4a..80ce2522ff 100644 --- a/code/modules/library/lib_items.dm +++ b/code/modules/library/lib_items.dm @@ -112,7 +112,7 @@ else return ..() -/obj/structure/bookcase/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/structure/bookcase/on_attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(. || !istype(user)) return diff --git a/code/modules/library/lib_machines.dm b/code/modules/library/lib_machines.dm index f65ea27216..f777246453 100644 --- a/code/modules/library/lib_machines.dm +++ b/code/modules/library/lib_machines.dm @@ -523,10 +523,7 @@ GLOBAL_LIST(cachedbooks) // List of our cached book datums else return ..() -/obj/machinery/libraryscanner/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) - . = ..() - if(.) - return +/obj/machinery/libraryscanner/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) usr.set_machine(src) var/dat = "" // if(cache) diff --git a/code/modules/mining/abandoned_crates.dm b/code/modules/mining/abandoned_crates.dm index d2da0f779e..8c9b0b53e1 100644 --- a/code/modules/mining/abandoned_crates.dm +++ b/code/modules/mining/abandoned_crates.dm @@ -149,8 +149,7 @@ if(100) new /obj/item/clothing/head/bearpelt(src) -//ATTACK HAND IGNORING PARENT RETURN VALUE -/obj/structure/closet/crate/secure/loot/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/structure/closet/crate/secure/loot/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(locked) to_chat(user, "The crate is locked with a Deca-code lock.") var/input = input(usr, "Enter [codelen] digits. All digits must be unique.", "Deca-Code Lock", "") as text diff --git a/code/modules/mining/aux_base.dm b/code/modules/mining/aux_base.dm index bf7a966f7d..006065d048 100644 --- a/code/modules/mining/aux_base.dm +++ b/code/modules/mining/aux_base.dm @@ -99,7 +99,6 @@ interface with the mining shuttle at the landing site if a mobile beacon is also say("Shuttle interface failed.") if(href_list["random"] && !possible_destinations) - usr.changeNext_move(CLICK_CD_RAPID) //Anti-spam var/list/all_mining_turfs = list() for (var/z_level in SSmapping.levels_by_trait(ZTRAIT_MINING)) all_mining_turfs += Z_TURFS(z_level) @@ -275,10 +274,7 @@ interface with the mining shuttle at the landing site if a mobile beacon is also var/anti_spam_cd = 0 //The linking process might be a bit intensive, so this here to prevent over use. var/console_range = 15 //Wifi range of the beacon to find the aux base console -/obj/structure/mining_shuttle_beacon/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) - . = ..() - if(.) - return +/obj/structure/mining_shuttle_beacon/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(anchored) to_chat(user, "Landing zone already set.") return diff --git a/code/modules/mining/aux_base_camera.dm b/code/modules/mining/aux_base_camera.dm index d461523744..be0a41427f 100644 --- a/code/modules/mining/aux_base_camera.dm +++ b/code/modules/mining/aux_base_camera.dm @@ -187,7 +187,7 @@ if(LAZYLEN(S.rcd_vals(owner,B.RCD))) rcd_target = S //If we don't break out of this loop we'll get the last placed thing - owner.changeNext_move(CLICK_CD_RANGE) + owner.DelayNextAction(CLICK_CD_RANGE) B.RCD.afterattack(rcd_target, owner, TRUE) //Activate the RCD and force it to work remotely! playsound(target_turf, 'sound/items/deconstruct.ogg', 60, 1) diff --git a/code/modules/mining/equipment/marker_beacons.dm b/code/modules/mining/equipment/marker_beacons.dm index 8097d243de..296513af8d 100644 --- a/code/modules/mining/equipment/marker_beacons.dm +++ b/code/modules/mining/equipment/marker_beacons.dm @@ -103,7 +103,7 @@ GLOBAL_LIST_INIT(marker_beacon_colors, list( icon_state = "[initial(icon_state)][lowertext(picked_color)]-on" set_light(light_range, light_power, GLOB.marker_beacon_colors[picked_color]) -/obj/structure/marker_beacon/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/structure/marker_beacon/on_attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/modules/mining/equipment/resonator.dm b/code/modules/mining/equipment/resonator.dm index 133cb41c33..16dd893c3a 100644 --- a/code/modules/mining/equipment/resonator.dm +++ b/code/modules/mining/equipment/resonator.dm @@ -41,7 +41,7 @@ return if(LAZYLEN(fields) < fieldlimit) new /obj/effect/temp_visual/resonance(T, user, src, burst_time) - user.changeNext_move(CLICK_CD_MELEE) + user.DelayNextAction(CLICK_CD_MELEE) /obj/item/resonator/pre_attack(atom/target, mob/user, params) if(check_allowed_items(target, 1)) diff --git a/code/modules/mining/equipment/survival_pod.dm b/code/modules/mining/equipment/survival_pod.dm index 2ca5f88ac8..c69e990033 100644 --- a/code/modules/mining/equipment/survival_pod.dm +++ b/code/modules/mining/equipment/survival_pod.dm @@ -167,10 +167,7 @@ qdel(src) return TRUE -/obj/item/gps/computer/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) - . = ..() - if(.) - return +/obj/item/gps/computer/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) attack_self(user) //Bed diff --git a/code/modules/mining/laborcamp/laborstacker.dm b/code/modules/mining/laborcamp/laborstacker.dm index c0d63fab9c..4d0b7dff21 100644 --- a/code/modules/mining/laborcamp/laborstacker.dm +++ b/code/modules/mining/laborcamp/laborstacker.dm @@ -141,10 +141,7 @@ GLOBAL_LIST(labor_sheet_values) icon_state = "console" density = FALSE -/obj/machinery/mineral/labor_points_checker/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) - . = ..() - if(.) - return +/obj/machinery/mineral/labor_points_checker/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) user.examinate(src) /obj/machinery/mineral/labor_points_checker/attackby(obj/item/I, mob/user, params) diff --git a/code/modules/mining/lavaland/ash_flora.dm b/code/modules/mining/lavaland/ash_flora.dm index e39b833793..9710773309 100644 --- a/code/modules/mining/lavaland/ash_flora.dm +++ b/code/modules/mining/lavaland/ash_flora.dm @@ -62,10 +62,7 @@ else return ..() -/obj/structure/flora/ash/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) - . = ..() - if(.) - return +/obj/structure/flora/ash/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(!harvested && !needs_sharp_harvest) user.visible_message("[user] starts to harvest from [src].","You begin to harvest from [src].") if(do_after(user, harvest_time, target = src)) diff --git a/code/modules/mining/lavaland/necropolis_chests.dm b/code/modules/mining/lavaland/necropolis_chests.dm index bfdb731869..270d3601fd 100644 --- a/code/modules/mining/lavaland/necropolis_chests.dm +++ b/code/modules/mining/lavaland/necropolis_chests.dm @@ -667,6 +667,8 @@ var/bleed_stacks_per_hit = 3 total_mass = 2.75 total_mass_on = 5 + attack_speed = 0 + attack_unwieldlyness = CLICK_CD_MELEE * 0.5 /obj/item/melee/transforming/cleaving_saw/examine(mob/user) . = ..() @@ -685,8 +687,12 @@ return FALSE . = ..() if(.) + if(active) + attack_unwieldlyness = CLICK_CD_MELEE + else + attack_unwieldlyness = CLICK_CD_MELEE * 0.5 transform_cooldown = world.time + (CLICK_CD_MELEE * 0.5) - user.changeNext_move(CLICK_CD_MELEE * 0.25) + user.SetNextAction(CLICK_CD_MELEE * 0.25, considered_action = FALSE, flush = TRUE) /obj/item/melee/transforming/cleaving_saw/transform_messages(mob/living/user, supress_message_text) if(!supress_message_text) @@ -701,11 +707,6 @@ to_chat(user, "You accidentally cut yourself with [src], like a doofus!") user.take_bodypart_damage(10) -/obj/item/melee/transforming/cleaving_saw/melee_attack_chain(mob/user, atom/target, params) - ..() - if(!active) - user.changeNext_move(CLICK_CD_MELEE * 0.5) //when closed, it attacks very rapidly - /obj/item/melee/transforming/cleaving_saw/nemesis_effects(mob/living/user, mob/living/target) var/datum/status_effect/stacking/saw_bleed/B = target.has_status_effect(STATUS_EFFECT_SAWBLEED) if(!B) diff --git a/code/modules/mining/lavaland/ruins/gym.dm b/code/modules/mining/lavaland/ruins/gym.dm index d454c3d118..c26631be74 100644 --- a/code/modules/mining/lavaland/ruins/gym.dm +++ b/code/modules/mining/lavaland/ruins/gym.dm @@ -8,7 +8,7 @@ var/list/hit_sounds = list('sound/weapons/genhit1.ogg', 'sound/weapons/genhit2.ogg', 'sound/weapons/genhit3.ogg',\ 'sound/weapons/punch1.ogg', 'sound/weapons/punch2.ogg', 'sound/weapons/punch3.ogg', 'sound/weapons/punch4.ogg') -/obj/structure/punching_bag/attack_hand(mob/user as mob) +/obj/structure/punching_bag/on_attack_hand(mob/user as mob) . = ..() if(.) return @@ -29,7 +29,7 @@ /obj/structure/weightmachine/proc/AnimateMachine(mob/living/user) return -/obj/structure/weightmachine/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/structure/weightmachine/on_attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/modules/mining/mine_items.dm b/code/modules/mining/mine_items.dm index 6567793b80..143aba3fe4 100644 --- a/code/modules/mining/mine_items.dm +++ b/code/modules/mining/mine_items.dm @@ -79,8 +79,7 @@ no_destination_swap = 1 var/static/list/dumb_rev_heads = list() -//ATTACK HAND IGNORING PARENT RETURN VALUE -/obj/machinery/computer/shuttle/mining/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/machinery/computer/shuttle/mining/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(is_station_level(user.z) && user.mind && is_head_revolutionary(user) && !(user.mind in dumb_rev_heads)) to_chat(user, "You get a feeling that leaving the station might be a REALLY dumb idea...") dumb_rev_heads += user.mind diff --git a/code/modules/mining/minebot.dm b/code/modules/mining/minebot.dm index fb37dcbca0..627d79d6ba 100644 --- a/code/modules/mining/minebot.dm +++ b/code/modules/mining/minebot.dm @@ -118,7 +118,7 @@ deathmessage = "blows apart!" ..() -/mob/living/simple_animal/hostile/mining_drone/attack_hand(mob/living/carbon/human/M) +/mob/living/simple_animal/hostile/mining_drone/on_attack_hand(mob/living/carbon/human/M) . = ..() if(.) return diff --git a/code/modules/mining/satchel_ore_boxdm.dm b/code/modules/mining/satchel_ore_boxdm.dm index f9d18fecc2..ae42ca4745 100644 --- a/code/modules/mining/satchel_ore_boxdm.dm +++ b/code/modules/mining/satchel_ore_boxdm.dm @@ -38,10 +38,7 @@ ui_interact(user) . = ..() -/obj/structure/ore_box/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) - . = ..() - if(.) - return +/obj/structure/ore_box/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(Adjacent(user)) ui_interact(user) diff --git a/code/modules/mob/clickdelay.dm b/code/modules/mob/clickdelay.dm new file mode 100644 index 0000000000..b1df87303e --- /dev/null +++ b/code/modules/mob/clickdelay.dm @@ -0,0 +1,200 @@ +/** + * CLICKDELAY HANDLING SYSTEM + * How this works is mobs can never do actions until their next_action is at or below world.time, but things can specify extra cooldown + * to check for either from the time of last_action or from the end of next_action. + * + * Clickdelay should always be checked via [CheckActionCooldown()], never manually! + */ + +/mob + // CLICKDELAY AND RELATED + // Generic clickdelay - Hybrid time-since-last-attack and time-to-next-attack system. + // next_action is a hard cooldown, as Click()s will not pass unless it is passed. + // last_action is not a hard cooldown and different items can check for different delays. + /// Generic clickdelay variable. Marks down the last world.time we did something that should cause or impact generic clickdelay. This should be directly set or set using [DelayNextAction()]. This should only be checked using [CheckActionCooldown()]. + var/last_action = 0 + /** + * The difference between the above and this is this is set immediately before even the pre-attack begins to ensure clickdelay is respected. + * Then, it is flushed or discarded using [FlushLastAttack()] or [DiscardLastAttack()] respectively. + */ + + var/last_action_immediate = 0 + /// Generic clickdelay variable. Next world.time we should be able to do something that respects generic clickdelay. This should be set using [DelayNextAction()] This should only be checked using [CheckActionCooldown()]. + var/next_action = 0 + /// Ditto + var/next_action_immediate = 0 + /// Default clickdelay for an UnarmedAttack() that successfully passes. Respects action_cooldown_mod. + var/unarmed_attack_speed = CLICK_CD_MELEE + /// Simple modification variable multiplied to next action modifier on adjust and on checking time since last action using [CheckActionCooldown()]. + /// This should only be manually modified using multipliers. + var/action_cooldown_mod = 1 + /// Simple modification variable added to amount on adjust and on checking time since last action using [CheckActionCooldown()]. + /// This should only be manually modified via addition. + var/action_cooldown_adjust = 0 + + // Resisting - While resisting will give generic clickdelay, it is also on its own resist delay system. However, resisting does not check generic movedelay. + // Resist cooldown should only be set at the start of a resist chain - whether this is clicking an alert button, pressing or hotkeying the resist button, or moving to resist out of a locker. + /* + * Special clickdelay variable for resisting. Last time we did a special action like resisting. This should only be set using [MarkResistTime()]. + * Use [CheckResistCooldown()] to check cooldowns, this should only be used for the resist action bar visual. + */ + var/last_resist = 0 + /// How long we should wait before allowing another resist. This should only be manually modified using multipliers. + var/resist_cooldown = CLICK_CD_RESIST + /// Minimum world time for another resist. This should only be checked using [CheckResistCooldown()]. + var/next_resist = 0 + +/** + * Applies a delay to next_action before we can do our next action. + * + * @params + * * amount - Amount to delay by + * * ignore_mod - ignores next action adjust and mult + * * considered_action - Defaults to TRUE - If TRUE, sets last_action to world.time. + * * immediate - defaults to TRUE - if TRUE, writes to cached/last_attack_immediate instead of last_attack. This ensures it can't collide with any delay checks in the actual attack. + * * flush - defaults to FALSE - Use this while using this proc outside of clickcode to ensure everything is set properly. This should never be set to TRUE if this is called from clickcode. + */ +/mob/proc/DelayNextAction(amount = 0, ignore_mod = FALSE, considered_action = TRUE, immediate = TRUE, flush = FALSE) + if(immediate) + if(considered_action) + last_action_immediate = world.time + next_action_immediate = max(next_action, world.time + (ignore_mod? amount : (amount * GetActionCooldownMod() + GetActionCooldownAdjust()))) + else + if(considered_action) + last_action = world.time + next_action = max(next_action, world.time + (ignore_mod? amount : (amount * GetActionCooldownMod() + GetActionCooldownAdjust()))) + if(flush) + FlushCurrentAction() + else + hud_used?.clickdelay?.mark_dirty() + +/** + * Get estimated time of next attack. + */ +/mob/proc/EstimatedNextActionTime() + var/attack_speed = unarmed_attack_speed * GetActionCooldownMod() + GetActionCooldownAdjust() + var/obj/item/I = get_active_held_item() + if(I) + attack_speed = I.GetEstimatedAttackSpeed() + if(!I.clickdelay_mod_bypass) + attack_speed = attack_speed * GetActionCooldownMod() + GetActionCooldownAdjust() + return max(next_action, next_action_immediate, max(last_action, last_action_immediate) + attack_speed) + +/** + * Sets our next action to. The difference is DelayNextAction cannot reduce next_action under any circumstances while this can. + */ +/mob/proc/SetNextAction(amount = 0, ignore_mod = FALSE, considered_action = TRUE, immediate = TRUE, flush = FALSE) + if(immediate) + if(considered_action) + last_action_immediate = world.time + next_action_immediate = world.time + (ignore_mod? amount : (amount * GetActionCooldownMod() + GetActionCooldownAdjust())) + else + if(considered_action) + last_action = world.time + next_action = world.time + (ignore_mod? amount : (amount * GetActionCooldownMod() + GetActionCooldownAdjust())) + if(flush) + FlushCurrentAction() + else + hud_used?.clickdelay?.mark_dirty() + +/** + * Checks if we can do another action. + * Returns TRUE if we can and FALSE if we cannot. + * + * @params + * * cooldown - Time required since last action. Defaults to 0.5 + * * from_next_action - Defaults to FALSE. Should we check from the tail end of next_action instead of last_action? + * * ignore_mod - Defaults to FALSE. Ignore all adjusts and multipliers. Do not use this unless you know what you are doing and have a good reason. + * * ignore_next_action - Defaults to FALSE. Ignore next_action and only care about cooldown param and everything else. Generally unused. + * * immediate - Defaults to FALSE. Checks last action using immediate, used on the head end of an attack. This is to prevent colliding attacks in case of sleep. Not that you should sleep() in an attack but.. y'know. + */ +/mob/proc/CheckActionCooldown(cooldown = 0.5, from_next_action = FALSE, ignore_mod = FALSE, ignore_next_action = FALSE, immediate = FALSE) + return (ignore_next_action || (world.time >= (immediate? next_action_immediate : next_action))) && \ + (world.time >= ((from_next_action? (immediate? next_action_immediate : next_action) : (immediate? last_action_immediate : last_action)) + max(0, ignore_mod? cooldown : (cooldown * GetActionCooldownMod() + GetActionCooldownAdjust())))) + +/** + * Gets action_cooldown_mod. + */ +/mob/proc/GetActionCooldownMod() + return action_cooldown_mod + +/** + * Gets action_cooldown_adjust + */ +/mob/proc/GetActionCooldownAdjust() + return action_cooldown_adjust + +/** + * Flushes last_action and next_action + */ +/mob/proc/FlushCurrentAction() + last_action = last_action_immediate + next_action = next_action_immediate + hud_used?.clickdelay?.mark_dirty() + +/** + * Discards last_action and next_action + */ +/mob/proc/DiscardCurrentAction() + last_action_immediate = last_action + next_action_immediate = next_action + hud_used?.clickdelay?.mark_dirty() + +/** + * Checks if we can resist again. + */ +/mob/proc/CheckResistCooldown() + return (world.time >= next_resist) + +/** + * Mark the last resist as now. + * + * @params + * * extra_cooldown - Extra cooldown to apply to next_resist. Defaults to this mob's resist_cooldown. + * * override - Defaults to FALSE - if TRUE, extra_cooldown will replace the old next_resist even if the old is longer. + */ +/mob/proc/MarkResistTime(extra_cooldown = resist_cooldown, override = FALSE) + last_resist = world.time + next_resist = override? (world.time + extra_cooldown) : max(next_resist, world.time + extra_cooldown) + hud_used?.resistdelay?.mark_dirty() + +/atom + // Standard clickdelay variables + // These 3 are all handled at base of atom/attack_hand so uh.. yeah. Make sure that's called. + /// Amount of time to check for from a mob's last attack to allow an attack_hand(). + var/attack_hand_speed = CLICK_CD_MELEE + /// Amount of time to hard stagger (no clicking at all) the mob post attack_hand(). Lower = better + var/attack_hand_unwieldlyness = 0 + /// Should we set last action for attack hand? This implies that attack_hands to this atom should flush to clickdelay buffers instead of discarding. + var/attack_hand_is_action = FALSE + +/obj/item + // Standard clickdelay variables + /// Amount of time to check for from a mob's last attack, checked before an attack happens. Lower = faster attacks + var/attack_speed = CLICK_CD_MELEE + /// Amount of time to hard-stagger (no clicking at all) the mob when attacking. Lower = better + var/attack_unwieldlyness = 0 + /// This item bypasses any click delay mods + var/clickdelay_mod_bypass = FALSE + /// This item checks clickdelay from a user's delayed next action variable rather than the last time they attacked. + var/clickdelay_from_next_action = FALSE + /// This item ignores next action delays. + var/clickdelay_ignores_next_action = FALSE + +/** + * Checks if a user's clickdelay is met for a standard attack, this is called before an attack happens. + */ +/obj/item/proc/CheckAttackCooldown(mob/user, atom/target) + return user.CheckActionCooldown(attack_speed, clickdelay_from_next_action, clickdelay_mod_bypass, clickdelay_ignores_next_action) + +/** + * Called after a successful attack to set a mob's clickdelay. + */ +/obj/item/proc/ApplyAttackCooldown(mob/user, atom/target, attackchain_flags) + user.DelayNextAction(attack_unwieldlyness, clickdelay_mod_bypass, !(attackchain_flags & ATTACK_IGNORE_ACTION)) + +/** + * Get estimated time that a user has to not attack for to use us + */ +/obj/item/proc/GetEstimatedAttackSpeed() + return attack_speed diff --git a/code/modules/mob/inventory.dm b/code/modules/mob/inventory.dm index 83cc09a624..caebb9cf10 100644 --- a/code/modules/mob/inventory.dm +++ b/code/modules/mob/inventory.dm @@ -5,13 +5,11 @@ /mob/proc/get_active_held_item() return get_item_for_held_index(active_hand_index) - //Finds the opposite limb for the active one (eg: upper left arm will find the item in upper right arm) //So we're treating each "pair" of limbs as a team, so "both" refers to them /mob/proc/get_inactive_held_item() return get_item_for_held_index(get_inactive_hand_index()) - //Finds the opposite index for the active one (eg: upper left arm will find the item in upper right arm) //So we're treating each "pair" of limbs as a team, so "both" refers to them /mob/proc/get_inactive_hand_index() @@ -24,12 +22,9 @@ other_hand = 0 return other_hand - /mob/proc/get_item_for_held_index(i) if(i > 0 && i <= held_items.len) return held_items[i] - return FALSE - //Odd = left. Even = right /mob/proc/held_index_to_dir(i) @@ -37,17 +32,14 @@ return "r" return "l" - //Check we have an organ for this hand slot (Dismemberment), Only relevant for humans /mob/proc/has_hand_for_held_index(i) return TRUE - //Check we have an organ for our active hand slot (Dismemberment),Only relevant for humans /mob/proc/has_active_hand() return has_hand_for_held_index(active_hand_index) - //Finds the first available (null) index OR all available (null) indexes in held_items based on a side. //Lefts: 1, 3, 5, 7... //Rights:2, 4, 6, 8... diff --git a/code/modules/mob/living/blood.dm b/code/modules/mob/living/blood.dm index 478599e2c0..36a6f6296b 100644 --- a/code/modules/mob/living/blood.dm +++ b/code/modules/mob/living/blood.dm @@ -14,7 +14,8 @@ var/obj/item/bodypart/BP = X temp_bleed += BP.get_bleed_rate() BP.generic_bleedstacks = max(0, BP.generic_bleedstacks - 1) - bleed(temp_bleed) + if(temp_bleed) + bleed(temp_bleed) //Blood regeneration if there is some space if(blood_volume < BLOOD_VOLUME_NORMAL) @@ -28,20 +29,15 @@ to_chat(src, "The blood soaks through your bandage.") -/mob/living/carbon/monkey/handle_blood() - if(bodytemperature >= TCRYO && !(HAS_TRAIT(src, TRAIT_NOCLONE))) //cryosleep or husked people do not pump the blood. - //Blood regeneration if there is some space - if(blood_volume < (BLOOD_VOLUME_NORMAL * blood_ratio)) - blood_volume += 0.1 // regenerate blood VERY slowly - if(blood_volume < (BLOOD_VOLUME_OKAY * blood_ratio)) - adjustOxyLoss(round(((BLOOD_VOLUME_NORMAL * blood_ratio) - blood_volume) * 0.02, 1)) - // Takes care blood loss and regeneration /mob/living/carbon/human/handle_blood() if(NOBLOOD in dna.species.species_traits || bleedsuppress || (HAS_TRAIT(src, TRAIT_FAKEDEATH))) return + if(HAS_TRAIT(src, TRAIT_NOMARROW)) //Bloodsuckers don't need to be here. + return + if(bodytemperature >= TCRYO && !(HAS_TRAIT(src, TRAIT_HUSK))) //cryosleep or husked people do not pump the blood. //Blood regeneration if there is some space diff --git a/code/modules/mob/living/brain/MMI.dm b/code/modules/mob/living/brain/MMI.dm index d1258ce6e4..891243496a 100644 --- a/code/modules/mob/living/brain/MMI.dm +++ b/code/modules/mob/living/brain/MMI.dm @@ -39,7 +39,9 @@ laws.set_laws_config() /obj/item/mmi/attackby(obj/item/O, mob/user, params) - user.changeNext_move(CLICK_CD_MELEE) + if(!user.CheckActionCooldown(CLICK_CD_MELEE)) + return + user.DelayNextAction() if(istype(O, /obj/item/organ/brain)) //Time to stick a brain in it --NEO var/obj/item/organ/brain/newbrain = O if(brain) diff --git a/code/modules/mob/living/brain/brain_item.dm b/code/modules/mob/living/brain/brain_item.dm index b6f8dd349b..a853416e6f 100644 --- a/code/modules/mob/living/brain/brain_item.dm +++ b/code/modules/mob/living/brain/brain_item.dm @@ -102,7 +102,7 @@ to_chat(brainmob, "You feel slightly disoriented. That's normal when you're just a brain.") /obj/item/organ/brain/attackby(obj/item/O, mob/user, params) - user.changeNext_move(CLICK_CD_MELEE) + user.DelayNextAction(CLICK_CD_MELEE) if(brainmob) O.attack(brainmob, user) //Oh noooeeeee diff --git a/code/modules/mob/living/carbon/alien/alien_defense.dm b/code/modules/mob/living/carbon/alien/alien_defense.dm index 5b92bf3dea..5081fd8a14 100644 --- a/code/modules/mob/living/carbon/alien/alien_defense.dm +++ b/code/modules/mob/living/carbon/alien/alien_defense.dm @@ -45,7 +45,7 @@ In all, this is a lot like the monkey code. /N return attack_alien(L) -/mob/living/carbon/alien/attack_hand(mob/living/carbon/human/M) +/mob/living/carbon/alien/on_attack_hand(mob/living/carbon/human/M) . = ..() if(.) //To allow surgery to return properly. return @@ -74,7 +74,6 @@ In all, this is a lot like the monkey code. /N var/obj/item/bodypart/affecting = get_bodypart(ran_zone(M.zone_selected)) apply_damage(rand(1, 3), BRUTE, affecting) - /mob/living/carbon/alien/attack_animal(mob/living/simple_animal/M) . = ..() if(.) diff --git a/code/modules/mob/living/carbon/alien/humanoid/humanoid_defense.dm b/code/modules/mob/living/carbon/alien/humanoid/humanoid_defense.dm index 5ebf6210d0..8177360d4a 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/humanoid_defense.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/humanoid_defense.dm @@ -21,7 +21,7 @@ "[user] has [hitverb] [src]!", null, COMBAT_MESSAGE_RANGE) return 1 -/mob/living/carbon/alien/humanoid/attack_hand(mob/living/carbon/human/M) +/mob/living/carbon/alien/humanoid/on_attack_hand(mob/living/carbon/human/M) . = ..() if(.) //To allow surgery to return properly. return diff --git a/code/modules/mob/living/carbon/alien/larva/larva_defense.dm b/code/modules/mob/living/carbon/alien/larva/larva_defense.dm index 7dabcf5abf..5832996a2c 100644 --- a/code/modules/mob/living/carbon/alien/larva/larva_defense.dm +++ b/code/modules/mob/living/carbon/alien/larva/larva_defense.dm @@ -1,6 +1,6 @@ -/mob/living/carbon/alien/larva/attack_hand(mob/living/carbon/human/M) +/mob/living/carbon/alien/larva/on_attack_hand(mob/living/carbon/human/M) . = ..() if(. || M.a_intent == INTENT_HELP || M.a_intent == INTENT_GRAB) return diff --git a/code/modules/mob/living/carbon/alien/special/facehugger.dm b/code/modules/mob/living/carbon/alien/special/facehugger.dm index c5a69553aa..ad8828572c 100644 --- a/code/modules/mob/living/carbon/alien/special/facehugger.dm +++ b/code/modules/mob/living/carbon/alien/special/facehugger.dm @@ -58,8 +58,7 @@ /obj/item/clothing/mask/facehugger/attack_alien(mob/user) //can be picked up by aliens return attack_hand(user) -//ATTACK HAND IGNORING PARENT RETURN VALUE -/obj/item/clothing/mask/facehugger/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/item/clothing/mask/facehugger/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if((stat == CONSCIOUS && !sterile) && !isalien(user)) if(Leap(user)) return diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index 4b7e27656b..1e31655278 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -320,14 +320,11 @@ return if(restrained()) // too soon. - if(last_special > world.time) - return var/buckle_cd = 600 if(handcuffed) var/obj/item/restraints/O = src.get_item_by_slot(SLOT_HANDCUFFED) buckle_cd = O.breakouttime - changeNext_move(min(CLICK_CD_BREAKOUT, buckle_cd)) - last_special = world.time + min(CLICK_CD_BREAKOUT, buckle_cd) + MarkResistTime() visible_message("[src] attempts to unbuckle [p_them()]self!", \ "You attempt to unbuckle yourself... (This will take around [round(buckle_cd/600,1)] minute\s, and you need to stay still.)") if(do_after(src, buckle_cd, 0, target = src, required_mobility_flags = MOBILITY_RESIST)) @@ -341,39 +338,26 @@ buckled.user_unbuckle_mob(src,src) /mob/living/carbon/resist_fire() - if(last_special > world.time) - return fire_stacks -= 5 DefaultCombatKnockdown(60, TRUE, TRUE) spin(32,2) visible_message("[src] rolls on the floor, trying to put [p_them()]self out!", \ "You stop, drop, and roll!") - last_special = world.time + 30 + MarkResistTime(30) sleep(30) if(fire_stacks <= 0) visible_message("[src] has successfully extinguished [p_them()]self!", \ "You extinguish yourself.") ExtinguishMob() -/mob/living/carbon/resist_restraints(ignore_delay = FALSE) +/mob/living/carbon/resist_restraints() var/obj/item/I = null - var/type = 0 - if(!ignore_delay && (last_special > world.time)) - to_chat(src, "You don't have the energy to resist your restraints that fast!") - return if(handcuffed) I = handcuffed - type = 1 else if(legcuffed) I = legcuffed - type = 2 if(I) - if(type == 1) - changeNext_move(min(CLICK_CD_BREAKOUT, I.breakouttime)) - last_special = world.time + CLICK_CD_BREAKOUT - if(type == 2) - changeNext_move(min(CLICK_CD_RANGE, I.breakouttime)) - last_special = world.time + CLICK_CD_RANGE + MarkResistTime() cuff_resist(I) /mob/living/carbon/proc/cuff_resist(obj/item/I, breakouttime = 600, cuff_break = 0) @@ -418,7 +402,7 @@ if (W) W.layer = initial(W.layer) W.plane = initial(W.plane) - changeNext_move(0) + SetNextAction(0) if (legcuffed) var/obj/item/W = legcuffed legcuffed = null @@ -431,7 +415,7 @@ if (W) W.layer = initial(W.layer) W.plane = initial(W.plane) - changeNext_move(0) + SetNextAction(0) update_equipment_speed_mods() // In case cuffs ever change speed /mob/living/carbon/proc/clear_cuffs(obj/item/I, cuff_break) diff --git a/code/modules/mob/living/carbon/carbon_defense.dm b/code/modules/mob/living/carbon/carbon_defense.dm index 196cec849d..ac261e6d5b 100644 --- a/code/modules/mob/living/carbon/carbon_defense.dm +++ b/code/modules/mob/living/carbon/carbon_defense.dm @@ -69,7 +69,7 @@ var/totitemdamage = pre_attacked_by(I, user) * damage_multiplier var/impacting_zone = (user == src)? check_zone(user.zone_selected) : ran_zone(user.zone_selected) var/list/block_return = list() - if((user != src) && (mob_run_block(I, totitemdamage, "the [I]", ((attackchain_flags & ATTACKCHAIN_PARRY_COUNTERATTACK)? ATTACK_TYPE_PARRY_COUNTERATTACK : NONE) | ATTACK_TYPE_MELEE, I.armour_penetration, user, impacting_zone, block_return) & BLOCK_SUCCESS)) + if((user != src) && (mob_run_block(I, totitemdamage, "the [I]", ((attackchain_flags & ATTACK_IS_PARRY_COUNTERATTACK)? ATTACK_TYPE_PARRY_COUNTERATTACK : NONE) | ATTACK_TYPE_MELEE, I.armour_penetration, user, impacting_zone, block_return) & BLOCK_SUCCESS)) return FALSE totitemdamage = block_calculate_resultant_damage(totitemdamage, block_return) var/obj/item/bodypart/affecting = get_bodypart(impacting_zone) @@ -111,8 +111,7 @@ /mob/living/carbon/attack_drone(mob/living/simple_animal/drone/user) return //so we don't call the carbon's attack_hand(). -//ATTACK HAND IGNORING PARENT RETURN VALUE -/mob/living/carbon/attack_hand(mob/living/carbon/human/user, act_intent, unarmed_attack_flags) +/mob/living/carbon/on_attack_hand(mob/living/carbon/human/user, act_intent, unarmed_attack_flags) . = ..() if(.) //was the attack blocked? return @@ -151,15 +150,13 @@ if(M.a_intent == INTENT_HELP) help_shake_act(M) - return 0 + return TRUE . = ..() if(.) //successful monkey bite. for(var/thing in M.diseases) var/datum/disease/D = thing ForceContractDisease(D) - return 1 - /mob/living/carbon/attack_slime(mob/living/simple_animal/slime/M) . = ..() diff --git a/code/modules/mob/living/carbon/carbon_defines.dm b/code/modules/mob/living/carbon/carbon_defines.dm index a05480ee01..2ce59fb790 100644 --- a/code/modules/mob/living/carbon/carbon_defines.dm +++ b/code/modules/mob/living/carbon/carbon_defines.dm @@ -24,7 +24,7 @@ var/obj/item/head = null var/obj/item/gloves = null //only used by humans - var/obj/item/shoes = null //only used by humans. + var/obj/item/clothing/shoes/shoes = null //only used by humans. var/obj/item/clothing/glasses/glasses = null //only used by humans. var/obj/item/ears = null //only used by humans. diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 19fdd8dbc8..145db1be1e 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -170,7 +170,11 @@ if(SLOT_SHOES in obscured) dat += "Shoes:Obscured" else - dat += "Shoes:[(shoes && !(shoes.item_flags & ABSTRACT)) ? shoes : "Empty"]" + dat += "Shoes:[(shoes && !(shoes.item_flags & ABSTRACT)) ? shoes : "Empty"]" + if(shoes && shoes.can_be_tied && shoes.tied != SHOES_KNOTTED) + dat += " [shoes.tied ? "Untie shoes" : "Knot shoes"]" + + dat += "" if(SLOT_GLOVES in obscured) dat += "Gloves:Obscured" @@ -294,6 +298,12 @@ if (!strip_silence) to_chat(src, "You feel your [pocket_side] pocket being fumbled with!") + if(usr.canUseTopic(src, BE_CLOSE, NO_DEXTERY, null, FALSE)) + // separate from first canusetopic + var/mob/living/user = usr + if(istype(user) && href_list["shoes"] && (user.mobility_flags & MOBILITY_USE)) // we need to be on the ground, so we'll be a bit looser + shoes.handle_tying(usr) + ..() //CITADEL CHANGE - removes a tab from behind this ..() so that flavortext can actually be examined @@ -735,8 +745,7 @@ /mob/living/carbon/human/resist_restraints() if(wear_suit && wear_suit.breakouttime) - changeNext_move(CLICK_CD_BREAKOUT) - last_special = world.time + CLICK_CD_BREAKOUT + MarkResistTime() cuff_resist(wear_suit) else ..() diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index 6737176d09..1673c57a80 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -122,7 +122,7 @@ apply_damage(15, BRUTE, wound_bonus=10) return 1 -/mob/living/carbon/human/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/mob/living/carbon/human/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) //To allow surgery to return properly. return @@ -131,6 +131,9 @@ dna.species.spec_attack_hand(H, src, null, act_intent, unarmed_attack_flags) /mob/living/carbon/human/attack_paw(mob/living/carbon/monkey/M) + if(!M.CheckActionCooldown(CLICK_CD_MELEE)) + return + M.DelayNextAction() var/dam_zone = pick(BODY_ZONE_CHEST, BODY_ZONE_PRECISE_L_HAND, BODY_ZONE_PRECISE_R_HAND, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG) var/obj/item/bodypart/affecting = get_bodypart(ran_zone(dam_zone)) if(!affecting) diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm index aea4ee2ead..13456ed61c 100644 --- a/code/modules/mob/living/carbon/human/human_defines.dm +++ b/code/modules/mob/living/carbon/human/human_defines.dm @@ -102,7 +102,7 @@ "HUMAN_PARRY_MININUM_EFFICIENCY" = 0.9 ) -/mob/living/carbon/human/on_active_parry(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return, parry_efficiency, parry_time) +/mob/living/carbon/human/on_active_parry(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, list/block_return, parry_efficiency, parry_time) var/datum/block_parry_data/D = return_block_parry_datum(block_parry_data) if(!owner.Adjacent(attacker)) return ..() @@ -110,7 +110,7 @@ return ..() visible_message("[src] strikes back perfectly at [attacker], staggering them!") if(D.parry_data["HUMAN_PARRY_PUNCH"]) - UnarmedAttack(attacker, TRUE, INTENT_HARM, UNARMED_ATTACK_PARRY) + UnarmedAttack(attacker, TRUE, INTENT_HARM, ATTACK_IS_PARRY_COUNTERATTACK | ATTACK_IGNORE_ACTION | ATTACK_IGNORE_CLICKDELAY | NO_AUTO_CLICKDELAY_HANDLING) var/mob/living/L = attacker if(istype(L)) L.Stagger(D.parry_data["HUMAN_PARRY_STAGGER"]) diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm index b5e48e47c9..430227a39c 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -1448,7 +1448,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) target.grabbedby(user) return 1 -/datum/species/proc/harm(mob/living/carbon/human/user, mob/living/carbon/human/target, datum/martial_art/attacker_style, unarmed_attack_flags = NONE) +/datum/species/proc/harm(mob/living/carbon/human/user, mob/living/carbon/human/target, datum/martial_art/attacker_style, attackchain_flags = NONE) if(!attacker_style && HAS_TRAIT(user, TRAIT_PACIFISM)) to_chat(user, "You don't want to harm [target]!") return FALSE @@ -1460,7 +1460,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) target_message = "[target] blocks your attack!") return FALSE - if(!(unarmed_attack_flags & UNARMED_ATTACK_PARRY)) + if(!(attackchain_flags & ATTACK_IS_PARRY_COUNTERATTACK)) if(HAS_TRAIT(user, TRAIT_PUGILIST))//CITADEL CHANGE - makes punching cause staminaloss but funny martial artist types get a discount user.adjustStaminaLossBuffered(1.5) else @@ -1492,17 +1492,17 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) //CITADEL CHANGES - makes resting and disabled combat mode reduce punch damage, makes being out of combat mode result in you taking more damage if(!SEND_SIGNAL(target, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_INACTIVE)) - damage *= 1.5 + damage *= 1.2 if(!CHECK_MOBILITY(user, MOBILITY_STAND)) - damage *= 0.5 + damage *= 0.8 if(SEND_SIGNAL(user, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_INACTIVE)) - damage *= 0.25 + damage *= 0.8 //END OF CITADEL CHANGES var/obj/item/bodypart/affecting = target.get_bodypart(ran_zone(user.zone_selected)) var/miss_chance = 100//calculate the odds that a punch misses entirely. considers stamina and brute damage of the puncher. punches miss by default to prevent weird cases - if(unarmed_attack_flags & UNARMED_ATTACK_PARRY) + if(attackchain_flags & ATTACK_IS_PARRY_COUNTERATTACK) miss_chance = 0 else if(user.dna.species.punchdamagelow) @@ -1689,7 +1689,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) /datum/species/proc/spec_hitby(atom/movable/AM, mob/living/carbon/human/H) return -/datum/species/proc/spec_attack_hand(mob/living/carbon/human/M, mob/living/carbon/human/H, datum/martial_art/attacker_style, act_intent, unarmed_attack_flags) +/datum/species/proc/spec_attack_hand(mob/living/carbon/human/M, mob/living/carbon/human/H, datum/martial_art/attacker_style, act_intent, attackchain_flags) if(!istype(M)) return CHECK_DNA_AND_SPECIES(M) @@ -1709,7 +1709,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) grab(M, H, attacker_style) if("harm") - harm(M, H, attacker_style, unarmed_attack_flags) + harm(M, H, attacker_style, attackchain_flags) if("disarm") disarm(M, H, attacker_style) @@ -1719,7 +1719,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) // Allows you to put in item-specific reactions based on species if(user != H) var/list/block_return = list() - if(H.mob_run_block(I, totitemdamage, "the [I.name]", ((attackchain_flags & ATTACKCHAIN_PARRY_COUNTERATTACK)? ATTACK_TYPE_PARRY_COUNTERATTACK : NONE) | ATTACK_TYPE_MELEE, I.armour_penetration, user, affecting.body_zone, block_return) & BLOCK_SUCCESS) + if(H.mob_run_block(I, totitemdamage, "the [I.name]", ((attackchain_flags & ATTACK_IS_PARRY_COUNTERATTACK)? ATTACK_TYPE_PARRY_COUNTERATTACK : NONE) | ATTACK_TYPE_MELEE, I.armour_penetration, user, affecting.body_zone, block_return) & BLOCK_SUCCESS) return 0 totitemdamage = block_calculate_resultant_damage(totitemdamage, block_return) if(H.check_martial_melee_block()) @@ -1830,6 +1830,9 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) return TRUE CHECK_DNA_AND_SPECIES(M) CHECK_DNA_AND_SPECIES(H) + if(!M.CheckActionCooldown()) + return + M.DelayNextAction(CLICK_CD_MELEE) if(!istype(M)) //sanity check for drones. return TRUE diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm index 725feb214c..e29c6b9ffe 100644 --- a/code/modules/mob/living/carbon/life.dm +++ b/code/modules/mob/living/carbon/life.dm @@ -1,6 +1,8 @@ /mob/living/carbon/BiologicalLife(seconds, times_fired) //Updates the number of stored chemicals for powers handle_changeling() + //Handles the unique mentabolism of bloodsuckers, look at /datum/antagonist/bloodsucker/proc/LifeTick() + handle_bloodsucker() //Reagent processing needs to come before breathing, to prevent edge cases. handle_organs() . = ..() // if . is false, we are dead. @@ -422,6 +424,12 @@ hud_used.lingchemdisplay.invisibility = INVISIBILITY_ABSTRACT +/mob/living/carbon/proc/handle_bloodsucker() + if(mind && AmBloodsucker(src)) + var/datum/antagonist/bloodsucker/B = mind.has_antag_datum(ANTAG_DATUM_BLOODSUCKER) + B.LifeTick() + + /mob/living/carbon/handle_mutations_and_radiation() if(dna && dna.temporary_mutations.len) for(var/mut in dna.temporary_mutations) diff --git a/code/modules/mob/living/carbon/monkey/combat.dm b/code/modules/mob/living/carbon/monkey/combat.dm index 149ec5f0e3..13d234092c 100644 --- a/code/modules/mob/living/carbon/monkey/combat.dm +++ b/code/modules/mob/living/carbon/monkey/combat.dm @@ -90,8 +90,7 @@ else if(legcuffed) I = legcuffed if(I) - changeNext_move(CLICK_CD_BREAKOUT) - last_special = world.time + CLICK_CD_BREAKOUT + MarkResistTime() cuff_resist(I) /mob/living/carbon/monkey/proc/should_target(var/mob/living/L) @@ -354,7 +353,7 @@ battle_screech() a_intent = INTENT_HARM -/mob/living/carbon/monkey/attack_hand(mob/living/L) +/mob/living/carbon/monkey/on_attack_hand(mob/living/L) if(L.a_intent == INTENT_HARM && prob(MONKEY_RETALIATE_HARM_PROB)) retaliate(L) else if(L.a_intent == INTENT_DISARM && prob(MONKEY_RETALIATE_DISARM_PROB)) diff --git a/code/modules/mob/living/carbon/monkey/monkey_defense.dm b/code/modules/mob/living/carbon/monkey/monkey_defense.dm index 8f862af8fa..16b3c1a79e 100644 --- a/code/modules/mob/living/carbon/monkey/monkey_defense.dm +++ b/code/modules/mob/living/carbon/monkey/monkey_defense.dm @@ -42,7 +42,7 @@ adjustBruteLoss(15) return TRUE -/mob/living/carbon/monkey/attack_hand(mob/living/carbon/human/M) +/mob/living/carbon/monkey/on_attack_hand(mob/living/carbon/human/M) . = ..() if(.) //To allow surgery to return properly. return diff --git a/code/modules/mob/living/clickdelay.dm b/code/modules/mob/living/clickdelay.dm new file mode 100644 index 0000000000..dfdb9104bf --- /dev/null +++ b/code/modules/mob/living/clickdelay.dm @@ -0,0 +1,4 @@ +/mob/living/GetActionCooldownMod() + . = ..() + for(var/datum/status_effect/S in status_effects) + . *= S.action_cooldown_mod() diff --git a/code/modules/mob/living/life.dm b/code/modules/mob/living/life.dm index fb71693534..89321082c9 100644 --- a/code/modules/mob/living/life.dm +++ b/code/modules/mob/living/life.dm @@ -139,7 +139,7 @@ ExtinguishMob() return var/datum/gas_mixture/G = loc.return_air() // Check if we're standing in an oxygenless environment - if(G.get_moles(/datum/gas/oxygen, 1)) + if(!G.get_moles(/datum/gas/oxygen, 1)) ExtinguishMob() //If there's no oxygen in the tile we're on, put out the fire return var/turf/location = get_turf(src) diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 9850afc1a3..b04f78f3ec 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -273,7 +273,7 @@ return stop_pulling() - changeNext_move(CLICK_CD_GRABBING) + DelayNextAction(CLICK_CD_GRABBING) if(AM.pulledby) if(!supress_message) @@ -676,7 +676,7 @@ ..(pressure_difference, direction, pressure_resistance_prob_delta) /mob/living/can_resist() - return !((next_move > world.time) || !CHECK_MOBILITY(src, MOBILITY_RESIST)) + return CheckResistCooldown() && CHECK_MOBILITY(src, MOBILITY_RESIST) /// Resist verb for attempting to get out of whatever is restraining your motion. Gives you resist clickdelay if do_resist() returns true. /mob/living/verb/resist() @@ -687,10 +687,12 @@ return if(do_resist()) - changeNext_move(CLICK_CD_RESIST) + MarkResistTime() + DelayNextAction(CLICK_CD_RESIST) -/// The actual proc for resisting. Return TRUE to give clickdelay. +/// The actual proc for resisting. Return TRUE to give CLICK_CD_RESIST clickdelay. /mob/living/proc/do_resist() + set waitfor = FALSE // some of these sleep. SEND_SIGNAL(src, COMSIG_LIVING_RESIST, src) //resisting grabs (as if it helps anyone...) // only works if you're not cuffed. @@ -701,7 +703,7 @@ return old_gs? TRUE : FALSE // unbuckling yourself. stops the chain if you try it. - if(buckled && last_special <= world.time) + if(buckled) log_combat(src, buckled, "resisted buckle") return resist_buckle() @@ -730,13 +732,12 @@ if(CHECK_MOBILITY(src, MOBILITY_USE) && resist_embedded()) //Citadel Change for embedded removal memes - requires being able to use items. // DO NOT GIVE DEFAULT CLICKDELAY - This is a combat action. - changeNext_move(CLICK_CD_MELEE) + DelayNextAction(CLICK_CD_MELEE) return FALSE - if(last_special <= world.time) - resist_restraints() //trying to remove cuffs. - // DO NOT GIVE CLICKDELAY - last_special handles this. - return FALSE + resist_restraints() //trying to remove cuffs. + // DO NOT GIVE CLICKDELAY + return FALSE /// Proc to resist a grab. moving_resist is TRUE if this began by someone attempting to move. Return FALSE if still grabbed/failed to break out. Use this instead of resist_grab() directly. /mob/proc/attempt_resist_grab(moving_resist, forced, log = TRUE) diff --git a/code/modules/mob/living/living_active_block.dm b/code/modules/mob/living/living_active_block.dm index 4211b2cfd9..729e7d3d7a 100644 --- a/code/modules/mob/living/living_active_block.dm +++ b/code/modules/mob/living/living_active_block.dm @@ -10,8 +10,7 @@ REMOVE_TRAIT(src, TRAIT_SPRINT_LOCKED, ACTIVE_BLOCK_TRAIT) remove_movespeed_modifier(/datum/movespeed_modifier/active_block) var/datum/block_parry_data/data = I.get_block_parry_data() - if(timeToNextMove() < data.block_end_click_cd_add) - changeNext_move(data.block_end_click_cd_add) + DelayNextAction(data.block_end_click_cd_add) return TRUE /mob/living/proc/ACTIVE_BLOCK_START(obj/item/I) @@ -97,7 +96,7 @@ return // QOL: Attempt to toggle on combat mode if it isn't already SEND_SIGNAL(src, COMSIG_ENABLE_COMBAT_MODE) - if(!SEND_SIGNAL(src, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_ACTIVE)) + if(SEND_SIGNAL(src, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_INACTIVE)) to_chat(src, "You must be in combat mode to actively block!") return FALSE var/datum/block_parry_data/data = I.get_block_parry_data() diff --git a/code/modules/mob/living/living_active_parry.dm b/code/modules/mob/living/living_active_parry.dm index 4fd2459e70..4a9c4e6311 100644 --- a/code/modules/mob/living/living_active_parry.dm +++ b/code/modules/mob/living/living_active_parry.dm @@ -59,14 +59,14 @@ return FALSE //QOL: Try to enable combat mode if it isn't already SEND_SIGNAL(src, COMSIG_ENABLE_COMBAT_MODE) - if(!SEND_SIGNAL(src, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_ACTIVE)) + if(SEND_SIGNAL(src, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_INACTIVE)) to_chat(src, "You must be in combat mode to parry!") return FALSE data = return_block_parry_datum(data) var/full_parry_duration = data.parry_time_windup + data.parry_time_active + data.parry_time_spindown // no system in place to "fallback" if out of the 3 the top priority one can't parry due to constraints but something else can. // can always implement it later, whatever. - if((data.parry_respect_clickdelay && (next_move > world.time)) || ((parry_end_time_last + data.parry_cooldown) > world.time)) + if((data.parry_respect_clickdelay && !CheckActionCooldown()) || ((parry_end_time_last + data.parry_cooldown) > world.time)) to_chat(src, "You are not ready to parry (again)!") return // Point of no return, make sure everything is set. @@ -121,7 +121,7 @@ Stagger(data.parry_failed_stagger_duration) effect_text += "staggering themselves" if(data.parry_failed_clickcd_duration) - changeNext_move(data.parry_failed_clickcd_duration) + DelayNextAction(data.parry_failed_clickcd_duration, flush = TRUE) effect_text += "throwing themselves off balance" handle_parry_ending_effects(data, effect_text) parrying = NOT_PARRYING @@ -160,17 +160,17 @@ /** * Called when an attack is parried using this, whether or not the parry was successful. */ -/obj/item/proc/on_active_parry(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return, parry_efficiency, parry_time) +/obj/item/proc/on_active_parry(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, list/block_return, parry_efficiency, parry_time) /** * Called when an attack is parried innately, whether or not the parry was successful. */ -/mob/living/proc/on_active_parry(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return, parry_efficiency, parry_time) +/mob/living/proc/on_active_parry(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, list/block_return, parry_efficiency, parry_time) /** * Called when an attack is parried using this, whether or not the parry was successful. */ -/datum/martial_art/proc/on_active_parry(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return, parry_efficiency, parry_time) +/datum/martial_art/proc/on_active_parry(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, list/block_return, parry_efficiency, parry_time) /** * Called when an attack is parried and block_parra_data indicates to use a proc to handle counterattack. @@ -277,7 +277,7 @@ if(data.parry_data[PARRY_COUNTERATTACK_MELEE_ATTACK_CHAIN]) switch(parrying) if(ITEM_PARRY) - active_parry_item.melee_attack_chain(src, attacker, null, ATTACKCHAIN_PARRY_COUNTERATTACK, data.parry_data[PARRY_COUNTERATTACK_MELEE_ATTACK_CHAIN]) + active_parry_item.melee_attack_chain(src, attacker, null, ATTACK_IS_PARRY_COUNTERATTACK | ATTACK_IGNORE_CLICKDELAY | ATTACK_IGNORE_ACTION | NO_AUTO_CLICKDELAY_HANDLING, data.parry_data[PARRY_COUNTERATTACK_MELEE_ATTACK_CHAIN]) effect_text += "reflexively counterattacking with [active_parry_item]" if(UNARMED_PARRY) // WARNING: If you are using these two, the attackchain parry counterattack flags and damage multipliers are unimplemented. Be careful with how you handle this. UnarmedAttack(attacker) diff --git a/code/modules/mob/living/living_blocking_parrying.dm b/code/modules/mob/living/living_blocking_parrying.dm index 9f1ad1c27a..47dae8849d 100644 --- a/code/modules/mob/living/living_blocking_parrying.dm +++ b/code/modules/mob/living/living_blocking_parrying.dm @@ -126,6 +126,8 @@ GLOBAL_LIST_EMPTY(block_parry_data) var/list/parry_imperfect_falloff_percent_override /// Efficiency in percent on perfect parry. var/parry_efficiency_perfect = 120 + /// Override for attack types, list("[ATTACK_TYPE_DEFINE]" = perecntage) for perfect efficiency. + var/parry_efficiency_perfect_override /// Parry effect data. var/list/parry_data = list( PARRY_COUNTERATTACK_MELEE_ATTACK_CHAIN = 1 @@ -180,7 +182,11 @@ GLOBAL_LIST_EMPTY(block_parry_data) if(isnull(leeway)) leeway = parry_time_perfect_leeway difference -= leeway - . = parry_efficiency_perfect + var/perfect = attack_type_list_scan(parry_efficiency_perfect_override, attack_type) + if(isnull(perfect)) + . = parry_efficiency_perfect + else + . = perfect if(difference <= 0) return var/falloff = attack_type_list_scan(parry_imperfect_falloff_percent_override, attack_type) @@ -276,6 +282,7 @@ GLOBAL_LIST_EMPTY(block_parry_data) RENDER_VARIABLE_SIMPLE(parry_imperfect_falloff_percent, "Linear falloff in percent per decisecond for attacks parried outside of perfect window.") RENDER_OVERRIDE_LIST(parry_imperfect_falloff_percent_override, "Override for the above for each attack type") RENDER_VARIABLE_SIMPLE(parry_efficiency_perfect, "Efficiency in percentage a parry in the perfect window is considered.") + RENDER_OVERRIDE_LIST(parry_efficiency_perfect_override, "Override for the above for each attack type") // parry_data dat += "" RENDER_VARIABLE_SIMPLE(parry_efficiency_considered_successful, "Minimum parry efficiency to be considered a successful parry.") diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm index e24e9641bf..5be9dbf195 100644 --- a/code/modules/mob/living/living_defense.dm +++ b/code/modules/mob/living/living_defense.dm @@ -77,6 +77,7 @@ final_percent = returnlist[BLOCK_RETURN_PROJECTILE_BLOCK_PERCENTAGE] if(returned & BLOCK_SHOULD_REDIRECT) handle_projectile_attack_redirection(P, returnlist[BLOCK_RETURN_REDIRECT_METHOD]) + return BULLET_ACT_FORCE_PIERCE if(returned & BLOCK_REDIRECTED) return BULLET_ACT_FORCE_PIERCE if(returned & BLOCK_SUCCESS) @@ -215,8 +216,8 @@ //proc to upgrade a simple pull into a more aggressive grab. /mob/living/proc/grippedby(mob/living/carbon/user, instant = FALSE) if(user.grab_state < GRAB_KILL) - user.changeNext_move(CLICK_CD_GRABBING) - playsound(src.loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) + user.DelayNextAction(CLICK_CD_GRABBING, flush = TRUE) + playsound(src, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) if(user.grab_state) //only the first upgrade is instantaneous var/old_grab_state = user.grab_state @@ -270,10 +271,10 @@ user.set_pull_offsets(src, grab_state) return 1 -/mob/living/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/mob/living/on_attack_hand(mob/user, act_intent = user.a_intent, attackchain_flags) ..() //Ignoring parent return value here. SEND_SIGNAL(src, COMSIG_MOB_ATTACK_HAND, user) - if((user != src) && act_intent != INTENT_HELP && (mob_run_block(user, 0, user.name, ATTACK_TYPE_UNARMED | ATTACK_TYPE_MELEE | ((unarmed_attack_flags & UNARMED_ATTACK_PARRY)? ATTACK_TYPE_PARRY_COUNTERATTACK : NONE), null, user, check_zone(user.zone_selected), null) & BLOCK_SUCCESS)) + if((user != src) && act_intent != INTENT_HELP && (mob_run_block(user, 0, user.name, ATTACK_TYPE_UNARMED | ATTACK_TYPE_MELEE | ((attackchain_flags & ATTACK_IS_PARRY_COUNTERATTACK)? ATTACK_TYPE_PARRY_COUNTERATTACK : NONE), null, user, check_zone(user.zone_selected), null) & BLOCK_SUCCESS)) log_combat(user, src, "attempted to touch") visible_message("[user] attempted to touch [src]!", "[user] attempted to touch you!", target = user, @@ -323,6 +324,9 @@ /mob/living/attack_animal(mob/living/simple_animal/M) M.face_atom(src) + if(!M.CheckActionCooldown(CLICK_CD_MELEE)) + return + M.DelayNextAction() if(M.melee_damage_upper == 0) M.visible_message("\The [M] [M.friendly_verb_continuous] [src]!", "You [M.friendly_verb_simple] [src]!", target = src, @@ -338,7 +342,7 @@ return 0 damage = block_calculate_resultant_damage(damage, return_list) if(M.attack_sound) - playsound(loc, M.attack_sound, 50, 1, 1) + playsound(src, M.attack_sound, 50, 1, 1) M.do_attack_animation(src) visible_message("\The [M] [M.attack_verb_continuous] [src]!", \ "\The [M] [M.attack_verb_continuous] you!", null, COMBAT_MESSAGE_RANGE, null, @@ -347,6 +351,9 @@ return damage /mob/living/attack_paw(mob/living/carbon/monkey/M) + if(!M.CheckActionCooldown(CLICK_CD_MELEE)) + return + M.DelayNextAction() if (M.a_intent == INTENT_HARM) if(HAS_TRAIT(M, TRAIT_PACIFISM)) to_chat(M, "You don't want to hurt anyone!") @@ -368,6 +375,7 @@ visible_message("[M.name] has attempted to bite [src]!", \ "[M.name] has attempted to bite [src]!", null, COMBAT_MESSAGE_RANGE, null, M, "You have attempted to bite [src]!") + return TRUE return FALSE /mob/living/attack_larva(mob/living/carbon/alien/larva/L) diff --git a/code/modules/mob/living/living_defines.dm b/code/modules/mob/living/living_defines.dm index b037221e2c..5495d37297 100644 --- a/code/modules/mob/living/living_defines.dm +++ b/code/modules/mob/living/living_defines.dm @@ -53,7 +53,6 @@ var/hallucination = 0 //Directly affects how long a mob will hallucinate for - var/last_special = 0 //Used by the resist verb, likely used to prevent players from bypassing next_move by logging in/out. var/timeofdeath = 0 //Allows mobs to move through dense areas without restriction. For instance, in space or out of holder objects. diff --git a/code/modules/mob/living/silicon/pai/pai_defense.dm b/code/modules/mob/living/silicon/pai/pai_defense.dm index dcb7ac66c9..64509d2deb 100644 --- a/code/modules/mob/living/silicon/pai/pai_defense.dm +++ b/code/modules/mob/living/silicon/pai/pai_defense.dm @@ -28,8 +28,7 @@ fold_in(force = 1) DefaultCombatKnockdown(200) -//ATTACK HAND IGNORING PARENT RETURN VALUE -/mob/living/silicon/pai/attack_hand(mob/living/carbon/human/user) +/mob/living/silicon/pai/on_attack_hand(mob/living/carbon/human/user) switch(user.a_intent) if(INTENT_HELP) visible_message("[user] gently pats [src] on the head, eliciting an off-putting buzzing from its holographic field.", diff --git a/code/modules/mob/living/silicon/robot/inventory.dm b/code/modules/mob/living/silicon/robot/inventory.dm index 0d8a0880a8..a063d090db 100644 --- a/code/modules/mob/living/silicon/robot/inventory.dm +++ b/code/modules/mob/living/silicon/robot/inventory.dm @@ -16,8 +16,6 @@ return item return module_active - - /mob/living/silicon/robot/proc/uneq_module(obj/item/O) if(!O) return 0 diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 51cff93ceb..4fcd6d1dbd 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -289,7 +289,7 @@ /mob/living/silicon/robot/attackby(obj/item/W, mob/user, params) if(istype(W, /obj/item/weldingtool) && (user.a_intent != INTENT_HARM || user == src)) - user.changeNext_move(CLICK_CD_MELEE) + user.DelayNextAction(CLICK_CD_MELEE) if (!getBruteLoss()) to_chat(user, "[src] is already in good condition!") return @@ -311,7 +311,7 @@ return else if(istype(W, /obj/item/stack/cable_coil) && wiresexposed) - user.changeNext_move(CLICK_CD_MELEE) + user.DelayNextAction(CLICK_CD_MELEE) if (getFireLoss() > 0 || getToxLoss() > 0) if(src == user) to_chat(user, "You start fixing yourself...") diff --git a/code/modules/mob/living/silicon/robot/robot_defense.dm b/code/modules/mob/living/silicon/robot/robot_defense.dm index e337618e4b..746c4f469d 100644 --- a/code/modules/mob/living/silicon/robot/robot_defense.dm +++ b/code/modules/mob/living/silicon/robot/robot_defense.dm @@ -62,8 +62,7 @@ return -//ATTACK HAND IGNORING PARENT RETURN VALUE -/mob/living/silicon/robot/attack_hand(mob/living/carbon/human/user) +/mob/living/silicon/robot/on_attack_hand(mob/living/carbon/human/user) add_fingerprint(user) if(opened && !wiresexposed && cell && !issilicon(user)) cell.update_icon() diff --git a/code/modules/mob/living/silicon/silicon_defense.dm b/code/modules/mob/living/silicon/silicon_defense.dm index 0850f0f886..8be2183d3b 100644 --- a/code/modules/mob/living/silicon/silicon_defense.dm +++ b/code/modules/mob/living/silicon/silicon_defense.dm @@ -70,7 +70,7 @@ return TRUE return FALSE -/mob/living/silicon/attack_hand(mob/living/carbon/human/M) +/mob/living/silicon/on_attack_hand(mob/living/carbon/human/M) . = ..() if(.) //the attack was blocked return diff --git a/code/modules/mob/living/simple_animal/animal_defense.dm b/code/modules/mob/living/simple_animal/animal_defense.dm index 278bb37d0d..b003e066ef 100644 --- a/code/modules/mob/living/simple_animal/animal_defense.dm +++ b/code/modules/mob/living/simple_animal/animal_defense.dm @@ -1,6 +1,6 @@ -/mob/living/simple_animal/attack_hand(mob/living/carbon/human/M) +/mob/living/simple_animal/on_attack_hand(mob/living/carbon/human/M) . = ..() if(.) //the attack was blocked return diff --git a/code/modules/mob/living/simple_animal/astral.dm b/code/modules/mob/living/simple_animal/astral.dm index eee42c214f..f79a2b5b3e 100644 --- a/code/modules/mob/living/simple_animal/astral.dm +++ b/code/modules/mob/living/simple_animal/astral.dm @@ -41,7 +41,11 @@ to_chat(src, "Your astral projection is interrupted and your mind is sent back to your body with a shock!") /mob/living/simple_animal/astral/ClickOn(var/atom/A, var/params) - ..() + . = ..() + attempt_possess(A) + +/mob/living/simple_animal/astral/proc/attempt_possess(atom/A) + set waitfor = FALSE if(pseudo_death == FALSE) if(isliving(A)) if(ishuman(A)) diff --git a/code/modules/mob/living/simple_animal/bot/bot.dm b/code/modules/mob/living/simple_animal/bot/bot.dm index 3ad19deeac..fe6792b5c2 100644 --- a/code/modules/mob/living/simple_animal/bot/bot.dm +++ b/code/modules/mob/living/simple_animal/bot/bot.dm @@ -290,7 +290,7 @@ return TRUE //Successful completion. Used to prevent child process() continuing if this one is ended early. -/mob/living/simple_animal/bot/attack_hand(mob/living/carbon/human/H) +/mob/living/simple_animal/bot/on_attack_hand(mob/living/carbon/human/H) if(H.a_intent == INTENT_HELP) interact(H) else @@ -335,7 +335,6 @@ user.visible_message("[user] uses [W] to pull [paicard] out of [bot_name]!","You pull [paicard] out of [bot_name] with [W].") ejectpai(user) else - user.changeNext_move(CLICK_CD_MELEE) if(istype(W, /obj/item/weldingtool) && user.a_intent != INTENT_HARM) if(health >= maxHealth) to_chat(user, "[src] does not need a repair!") diff --git a/code/modules/mob/living/simple_animal/bot/ed209bot.dm b/code/modules/mob/living/simple_animal/bot/ed209bot.dm index 1f81e8db29..91462a6713 100644 --- a/code/modules/mob/living/simple_animal/bot/ed209bot.dm +++ b/code/modules/mob/living/simple_animal/bot/ed209bot.dm @@ -177,7 +177,7 @@ Auto Patrol[]"}, target = H mode = BOT_HUNT -/mob/living/simple_animal/bot/ed209/attack_hand(mob/living/carbon/human/H) +/mob/living/simple_animal/bot/ed209/on_attack_hand(mob/living/carbon/human/H) if(H.a_intent == INTENT_HARM) retaliate(H) return ..() @@ -532,8 +532,10 @@ Auto Patrol[]"}, /mob/living/simple_animal/bot/ed209/RangedAttack(atom/A) if(!on) - return + return ..() shootAt(A) + DelayNextAction() + return TRUE /mob/living/simple_animal/bot/ed209/proc/stun_attack(mob/living/carbon/C) playsound(src, 'sound/weapons/egloves.ogg', 50, TRUE, -1) diff --git a/code/modules/mob/living/simple_animal/bot/honkbot.dm b/code/modules/mob/living/simple_animal/bot/honkbot.dm index 43f18d3890..0ee600ed1d 100644 --- a/code/modules/mob/living/simple_animal/bot/honkbot.dm +++ b/code/modules/mob/living/simple_animal/bot/honkbot.dm @@ -112,7 +112,7 @@ Maintenance panel panel is [open ? "opened" : "closed"]"}, target = H mode = BOT_HUNT -/mob/living/simple_animal/bot/honkbot/attack_hand(mob/living/carbon/human/H) +/mob/living/simple_animal/bot/honkbot/on_attack_hand(mob/living/carbon/human/H) if(H.a_intent == INTENT_HARM) retaliate(H) addtimer(CALLBACK(src, .proc/react_buzz), 5) diff --git a/code/modules/mob/living/simple_animal/bot/medbot.dm b/code/modules/mob/living/simple_animal/bot/medbot.dm index f998f58f02..fb5a889d89 100644 --- a/code/modules/mob/living/simple_animal/bot/medbot.dm +++ b/code/modules/mob/living/simple_animal/bot/medbot.dm @@ -604,7 +604,7 @@ /mob/living/simple_animal/bot/medbot/proc/get_healchem_toxin(mob/M) return HAS_TRAIT(M, TRAIT_TOXINLOVER)? treatment_tox_toxlover : treatment_tox -/mob/living/simple_animal/bot/medbot/attack_hand(mob/living/carbon/human/H) +/mob/living/simple_animal/bot/medbot/on_attack_hand(mob/living/carbon/human/H) if(H.a_intent == INTENT_DISARM && mode != BOT_TIPPED) H.visible_message("[H] begins tipping over [src].", "You begin tipping over [src]...") diff --git a/code/modules/mob/living/simple_animal/bot/secbot.dm b/code/modules/mob/living/simple_animal/bot/secbot.dm index e14cb488ae..cf9698655b 100644 --- a/code/modules/mob/living/simple_animal/bot/secbot.dm +++ b/code/modules/mob/living/simple_animal/bot/secbot.dm @@ -284,7 +284,7 @@ Auto Patrol: []"}, /mob/living/simple_animal/bot/secbot/proc/special_retaliate_after_attack(mob/user) //allows special actions to take place after being attacked. return -/mob/living/simple_animal/bot/secbot/attack_hand(mob/living/carbon/human/H) +/mob/living/simple_animal/bot/secbot/on_attack_hand(mob/living/carbon/human/H) if((H.a_intent == INTENT_HARM) || (H.a_intent == INTENT_DISARM)) retaliate(H) if(special_retaliate_after_attack(H)) diff --git a/code/modules/mob/living/simple_animal/friendly/cat.dm b/code/modules/mob/living/simple_animal/friendly/cat.dm index d30fa1b49f..c21875d1db 100644 --- a/code/modules/mob/living/simple_animal/friendly/cat.dm +++ b/code/modules/mob/living/simple_animal/friendly/cat.dm @@ -283,7 +283,7 @@ if(!D.is_decorated) D.decorate_donut() -/mob/living/simple_animal/pet/cat/cak/attack_hand(mob/living/L) +/mob/living/simple_animal/pet/cat/cak/on_attack_hand(mob/living/L) . = ..() if(.) //the attack was blocked return diff --git a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm index 1f733a4d55..51e7ee6c03 100644 --- a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm +++ b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm @@ -166,7 +166,7 @@ if(stat == CONSCIOUS) udder.generateMilk(milk_reagent) -/mob/living/simple_animal/cow/attack_hand(mob/living/carbon/M) +/mob/living/simple_animal/cow/on_attack_hand(mob/living/carbon/M) if(!stat && M.a_intent == INTENT_DISARM && icon_state != icon_dead) M.visible_message("[M] tips over [src].", "You tip over [src].") diff --git a/code/modules/mob/living/simple_animal/guardian/types/explosive.dm b/code/modules/mob/living/simple_animal/guardian/types/explosive.dm index d396434708..4e6923615d 100644 --- a/code/modules/mob/living/simple_animal/guardian/types/explosive.dm +++ b/code/modules/mob/living/simple_animal/guardian/types/explosive.dm @@ -86,8 +86,7 @@ /obj/guardian_bomb/attackby(mob/living/user) detonate(user) -//ATTACK HAND IGNORING PARENT RETURN VALUE -/obj/guardian_bomb/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/guardian_bomb/on_attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) detonate(user) /obj/guardian_bomb/examine(mob/user) diff --git a/code/modules/mob/living/simple_animal/guardian/types/standard.dm b/code/modules/mob/living/simple_animal/guardian/types/standard.dm index 2285167df5..d7970daa29 100644 --- a/code/modules/mob/living/simple_animal/guardian/types/standard.dm +++ b/code/modules/mob/living/simple_animal/guardian/types/standard.dm @@ -3,7 +3,7 @@ melee_damage_lower = 20 melee_damage_upper = 20 obj_damage = 80 - next_move_modifier = 0.5 //attacks 50% faster + action_cooldown_mod = 0.5 //attacks 50% faster environment_smash = ENVIRONMENT_SMASH_WALLS playstyle_string = "As a standard type you have no special abilities, but take half damage and have powerful attack capable of smashing through walls." magic_fluff_string = "..And draw the Assistant, faceless and generic, but never to be underestimated." diff --git a/code/modules/mob/living/simple_animal/hostile/bear.dm b/code/modules/mob/living/simple_animal/hostile/bear.dm index dc3c90cc64..057d4bdb45 100644 --- a/code/modules/mob/living/simple_animal/hostile/bear.dm +++ b/code/modules/mob/living/simple_animal/hostile/bear.dm @@ -136,7 +136,7 @@ mob/living/simple_animal/hostile/bear/butter //The mighty companion to Cak. Seve if(health < maxHealth) heal_overall_damage(10) //Fast life regen, makes it hard for you to get eaten to death. -/mob/living/simple_animal/hostile/bear/butter/attack_hand(mob/living/L) //Borrowed code from Cak, feeds people if they hit you. More nutriment but less vitamin to represent BUTTER. +/mob/living/simple_animal/hostile/bear/butter/on_attack_hand(mob/living/L) //Borrowed code from Cak, feeds people if they hit you. More nutriment but less vitamin to represent BUTTER. ..() if(L.a_intent == INTENT_HARM && L.reagents && !stat) L.reagents.add_reagent(/datum/reagent/consumable/nutriment, 1) diff --git a/code/modules/mob/living/simple_animal/hostile/hostile.dm b/code/modules/mob/living/simple_animal/hostile/hostile.dm index 945842d5ed..5ed3cd0cdd 100644 --- a/code/modules/mob/living/simple_animal/hostile/hostile.dm +++ b/code/modules/mob/living/simple_animal/hostile/hostile.dm @@ -523,9 +523,9 @@ mob/living/simple_animal/hostile/proc/DestroySurroundings() // for use with mega if(ranged && ranged_cooldown <= world.time) target = A OpenFire(A) - ..() - - + DelayNextAction() + . = ..() + return TRUE ////// AI Status /////// /mob/living/simple_animal/hostile/proc/AICanContinue(var/list/possible_targets) diff --git a/code/modules/mob/living/simple_animal/hostile/jungle/leaper.dm b/code/modules/mob/living/simple_animal/hostile/jungle/leaper.dm index a4edb21479..55046d6555 100644 --- a/code/modules/mob/living/simple_animal/hostile/jungle/leaper.dm +++ b/code/modules/mob/living/simple_animal/hostile/jungle/leaper.dm @@ -136,7 +136,7 @@ target = A if(!isturf(loc)) return - if(next_move > world.time) + if(!CheckActionCooldown()) return if(hopping) return diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm index 3ef4ef9be9..5c1229c130 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm @@ -70,7 +70,7 @@ Difficulty: Medium /obj/item/melee/transforming/cleaving_saw/miner/attack(mob/living/target, mob/living/carbon/human/user) target.add_stun_absorption("miner", 10, INFINITY) - ..() + . = ..() target.stun_absorption -= "miner" /obj/item/projectile/kinetic/miner @@ -86,8 +86,8 @@ Difficulty: Medium /mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/adjustHealth(amount, updating_health = TRUE, forced = FALSE) var/adjustment_amount = amount * 0.1 - if(world.time + adjustment_amount > next_move) - changeNext_move(adjustment_amount) //attacking it interrupts it attacking, but only briefly + if(world.time + adjustment_amount > next_action) + DelayNextAction(adjustment_amount, considered_action = FALSE, flush = TRUE) //attacking it interrupts it attacking, but only briefly . = ..() /mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/death() @@ -109,7 +109,7 @@ Difficulty: Medium /mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/AttackingTarget() if(QDELETED(target)) return - if(next_move > world.time || !Adjacent(target)) //some cheating + if(!CheckActionCooldown() || !Adjacent(target)) //some cheating INVOKE_ASYNC(src, .proc/quick_attack_loop) return face_atom(target) @@ -125,8 +125,8 @@ Difficulty: Medium adjustHealth(-(L.maxHealth * 0.5)) L.gib() return TRUE - changeNext_move(CLICK_CD_MELEE) - miner_saw.melee_attack_chain(src, target) + miner_saw.melee_attack_chain(src, target, null, ATTACK_IGNORE_CLICKDELAY) + FlushCurrentAction() if(guidance) adjustHealth(-2) transform_weapon() @@ -161,19 +161,19 @@ Difficulty: Medium face_atom(target) new /obj/effect/temp_visual/dir_setting/firing_effect(loc, dir) Shoot(target) - changeNext_move(CLICK_CD_RANGE) + DelayNextAction(CLICK_CD_RANGE, flush = TRUE) //I'm still of the belief that this entire proc needs to be wiped from existence. // do not take my touching of it to be endorsement of it. ~mso /mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/proc/quick_attack_loop() - while(!QDELETED(target) && next_move <= world.time) //this is done this way because next_move can change to be sooner while we sleep. + while(!QDELETED(target) && !CheckActionCooldown()) //this is done this way because next_move can change to be sooner while we sleep. stoplag(1) - sleep((next_move - world.time) * 1.5) //but don't ask me what the fuck this is about + sleep((next_action - world.time) * 1.5) //but don't ask me what the fuck this is about if(QDELETED(target)) return - if(dashing || next_move > world.time || !Adjacent(target)) - if(dashing && next_move <= world.time) - next_move = world.time + 1 + if(dashing || !CheckActionCooldown() || !Adjacent(target)) + if(dashing && next_action <= world.time) + SetNextAction(1, considered_action = FALSE, immediate = FALSE, flush = TRUE) INVOKE_ASYNC(src, .proc/quick_attack_loop) //lets try that again. return AttackingTarget() diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm index aa4ff328b5..18abb019d3 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm @@ -385,10 +385,7 @@ Difficulty: Very Hard if(isliving(speaker)) ActivationReaction(speaker, ACTIVATE_SPEECH) -/obj/machinery/anomalous_crystal/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) - . = ..() - if(.) - return +/obj/machinery/anomalous_crystal/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) ActivationReaction(user, ACTIVATE_TOUCH) /obj/machinery/anomalous_crystal/attackby(obj/item/I, mob/user, params) diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/curse_blob.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/curse_blob.dm index c4f78b6e26..11cc0fe67e 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/curse_blob.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/curse_blob.dm @@ -105,7 +105,7 @@ IGNORE_PROC_IF_NOT_TARGET(attack_slime) /mob/living/simple_animal/hostile/asteroid/curseblob/attacked_by(obj/item/I, mob/living/L, attackchain_flags = NONE, damage_multiplier = 1) if(L != set_target) - L.changeNext_move(I.click_delay) //pre_attacked_by not called + I.ApplyAttackCooldown(L, src) return return ..() diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/elite.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/elite.dm index 982b91c2c9..87ec79abcf 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/elite.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/elite.dm @@ -148,7 +148,7 @@ While using this makes the system rely on OnFire, it still gives options for tim desc = "You're not quite sure how a signal can be menacing." invisibility = 100 -/obj/structure/elite_tumor/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/structure/elite_tumor/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(ishuman(user)) switch(activity) diff --git a/code/modules/mob/living/simple_animal/hostile/mushroom.dm b/code/modules/mob/living/simple_animal/hostile/mushroom.dm index 4c9afd3784..9101430ccc 100644 --- a/code/modules/mob/living/simple_animal/hostile/mushroom.dm +++ b/code/modules/mob/living/simple_animal/hostile/mushroom.dm @@ -170,7 +170,7 @@ Bruise() ..() -/mob/living/simple_animal/hostile/mushroom/attack_hand(mob/living/carbon/human/M) +/mob/living/simple_animal/hostile/mushroom/on_attack_hand(mob/living/carbon/human/M) . = ..() if(.) // the attack was blocked return diff --git a/code/modules/mob/living/simple_animal/hostile/netherworld.dm b/code/modules/mob/living/simple_animal/hostile/netherworld.dm index 3620e3ee5f..e21e3e0693 100644 --- a/code/modules/mob/living/simple_animal/hostile/netherworld.dm +++ b/code/modules/mob/living/simple_animal/hostile/netherworld.dm @@ -86,7 +86,7 @@ .=..() START_PROCESSING(SSprocessing, src) -/obj/structure/spawner/nether/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/structure/spawner/nether/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) user.visible_message("[user] is violently pulled into the link!", \ "Touching the portal, you are quickly pulled through into a world of unimaginable horror!") contents.Add(user) diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/clown.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/clown.dm index 507911c7e0..dec2159dc0 100644 --- a/code/modules/mob/living/simple_animal/hostile/retaliate/clown.dm +++ b/code/modules/mob/living/simple_animal/hostile/retaliate/clown.dm @@ -51,7 +51,7 @@ else clear_alert("temp") -/mob/living/simple_animal/hostile/retaliate/clown/attack_hand(mob/living/carbon/human/M) +/mob/living/simple_animal/hostile/retaliate/clown/on_attack_hand(mob/living/carbon/human/M) ..() playsound(src.loc, 'sound/items/bikehorn.ogg', 50, TRUE) diff --git a/code/modules/mob/living/simple_animal/parrot.dm b/code/modules/mob/living/simple_animal/parrot.dm index de8a6fb6a0..4fcb1ed5bf 100644 --- a/code/modules/mob/living/simple_animal/parrot.dm +++ b/code/modules/mob/living/simple_animal/parrot.dm @@ -271,7 +271,7 @@ * Attack responces */ //Humans, monkeys, aliens -/mob/living/simple_animal/parrot/attack_hand(mob/living/carbon/M) +/mob/living/simple_animal/parrot/on_attack_hand(mob/living/carbon/M) ..() if(client) return diff --git a/code/modules/mob/living/simple_animal/slime/slime.dm b/code/modules/mob/living/simple_animal/slime/slime.dm index f7876b3516..1bdd988694 100644 --- a/code/modules/mob/living/simple_animal/slime/slime.dm +++ b/code/modules/mob/living/simple_animal/slime/slime.dm @@ -296,7 +296,7 @@ discipline_slime(user) return ..() -/mob/living/simple_animal/slime/attack_hand(mob/living/carbon/human/M) +/mob/living/simple_animal/slime/on_attack_hand(mob/living/carbon/human/M) if(buckled) M.do_attack_animation(src, ATTACK_EFFECT_DISARM) if(buckled == M) @@ -356,7 +356,7 @@ attacked += 10 if(prob(25)) user.do_attack_animation(src) - user.changeNext_move(CLICK_CD_MELEE) + W.ApplyAttackCooldown(user, src) to_chat(user, "[W] passes right through [src]!") return if(Discipline && prob(50)) // wow, buddy, why am I getting attacked?? diff --git a/code/modules/mob/login.dm b/code/modules/mob/login.dm index b7546becd8..31bfb5621f 100644 --- a/code/modules/mob/login.dm +++ b/code/modules/mob/login.dm @@ -13,9 +13,7 @@ hud_used.show_hud(hud_used.hud_version) hud_used.update_ui_style(ui_style2icon(client.prefs.UI_style)) - next_move = 1 - - ..() + . = ..() reset_perspective(loc) diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm index 0eff65fda3..195c50e958 100644 --- a/code/modules/mob/mob_defines.dm +++ b/code/modules/mob/mob_defines.dm @@ -11,6 +11,10 @@ blocks_emissive = EMISSIVE_BLOCK_GENERIC vis_flags = VIS_INHERIT_PLANE //when this be added to vis_contents of something it inherit something.plane, important for visualisation of mob in openspace. + + attack_hand_is_action = TRUE + attack_hand_unwieldlyness = CLICK_CD_MELEE + attack_hand_speed = 0 /// What receives our keyboard input. src by default. var/datum/focus @@ -35,7 +39,6 @@ var/list/logging = list() var/atom/machine = null - var/next_move = null var/create_area_cooldown /// Whether or not the mob is currently being transformed into another mob or into another state of being. This will prevent it from moving or doing realistically anything. /// Don't you DARE use this for a cheap way to ensure someone is stunned in your code. diff --git a/code/modules/modular_computers/computers/item/laptop.dm b/code/modules/modular_computers/computers/item/laptop.dm index 4e4c1fcdce..4781cbd8bc 100644 --- a/code/modules/modular_computers/computers/item/laptop.dm +++ b/code/modules/modular_computers/computers/item/laptop.dm @@ -64,10 +64,7 @@ return M.put_in_hand(src, H.held_index) -/obj/item/modular_computer/laptop/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) - . = ..() - if(.) - return +/obj/item/modular_computer/laptop/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(screen_on && isturf(loc)) return attack_self(user) diff --git a/code/modules/modular_computers/computers/machinery/modular_computer.dm b/code/modules/modular_computers/computers/machinery/modular_computer.dm index 89c6166a0d..7e384c3ddd 100644 --- a/code/modules/modular_computers/computers/machinery/modular_computer.dm +++ b/code/modules/modular_computers/computers/machinery/modular_computer.dm @@ -100,7 +100,6 @@ if(cpu) return cpu.AltClick(user) -//ATTACK HAND IGNORING PARENT RETURN VALUE // On-click handling. Turns on the computer if it's off and opens the GUI. /obj/machinery/modular_computer/interact(mob/user) if(cpu) diff --git a/code/modules/ninja/suit/gloves.dm b/code/modules/ninja/suit/gloves.dm index dbe4c80579..a06b753402 100644 --- a/code/modules/ninja/suit/gloves.dm +++ b/code/modules/ninja/suit/gloves.dm @@ -67,6 +67,7 @@ to_chat(H, "Gained [DisplayEnergy(.)] of energy from [A].") else to_chat(H, "\The [A] has run dry of energy, you must find another source!") + . = INTERRUPT_UNARMED_ATTACK else . = FALSE //as to not cancel attack_hand() diff --git a/code/modules/paperwork/filingcabinet.dm b/code/modules/paperwork/filingcabinet.dm index b368589bc3..b8f2c95762 100644 --- a/code/modules/paperwork/filingcabinet.dm +++ b/code/modules/paperwork/filingcabinet.dm @@ -137,7 +137,7 @@ virgin = 0 //tabbing here is correct- it's possible for people to try and use it //before the records have been generated, so we do this inside the loop. -/obj/structure/filingcabinet/security/attack_hand() +/obj/structure/filingcabinet/security/on_attack_hand() populate() . = ..() @@ -170,8 +170,7 @@ virgin = 0 //tabbing here is correct- it's possible for people to try and use it //before the records have been generated, so we do this inside the loop. -//ATTACK HAND IGNORING PARENT RETURN VALUE -/obj/structure/filingcabinet/medical/attack_hand() +/obj/structure/filingcabinet/medical/on_attack_hand() populate() . = ..() diff --git a/code/modules/paperwork/paper_cutter.dm b/code/modules/paperwork/paper_cutter.dm index 770a6682e0..3937720f74 100644 --- a/code/modules/paperwork/paper_cutter.dm +++ b/code/modules/paperwork/paper_cutter.dm @@ -66,10 +66,7 @@ return ..() -/obj/item/papercutter/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) - . = ..() - if(.) - return +/obj/item/papercutter/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) add_fingerprint(user) if(!storedcutter) to_chat(user, "The cutting blade is gone! You can't use [src] now.") diff --git a/code/modules/paperwork/paperbin.dm b/code/modules/paperwork/paperbin.dm index d1141c9f70..28cb5ffae9 100644 --- a/code/modules/paperwork/paperbin.dm +++ b/code/modules/paperwork/paperbin.dm @@ -11,6 +11,8 @@ throw_speed = 3 throw_range = 7 pressure_resistance = 8 + attack_hand_speed = CLICK_CD_RAPID + attack_hand_is_action = TRUE var/papertype = /obj/item/paper var/total_paper = 30 var/list/papers = list() @@ -60,11 +62,9 @@ /obj/item/paper_bin/attack_paw(mob/user) return attack_hand(user) -//ATTACK HAND IGNORING PARENT RETURN VALUE -/obj/item/paper_bin/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/item/paper_bin/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(user.lying) return - user.changeNext_move(CLICK_CD_MELEE) if(bin_pen) var/obj/item/pen/P = bin_pen P.add_fingerprint(user) @@ -148,7 +148,7 @@ papertype = /obj/item/paper/natural resistance_flags = FLAMMABLE -/obj/item/paper_bin/bundlenatural/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/item/paper_bin/bundlenatural/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) ..() if(total_paper < 1) qdel(src) diff --git a/code/modules/photography/camera/camera.dm b/code/modules/photography/camera/camera.dm index 3e76fc874a..b925c67940 100644 --- a/code/modules/photography/camera/camera.dm +++ b/code/modules/photography/camera/camera.dm @@ -221,4 +221,4 @@ p.set_picture(picture, TRUE, TRUE) if(CONFIG_GET(flag/picture_logging_camera)) - picture.log_to_file() \ No newline at end of file + picture.log_to_file() diff --git a/code/modules/photography/photos/frame.dm b/code/modules/photography/photos/frame.dm index 6f7bc643c8..d306c46815 100644 --- a/code/modules/photography/photos/frame.dm +++ b/code/modules/photography/photos/frame.dm @@ -21,8 +21,7 @@ to_chat(user, "\The [src] already contains a photo.") ..() -//ATTACK HAND IGNORING PARENT RETURN VALUE -/obj/item/wallframe/picture/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/item/wallframe/picture/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(user.get_inactive_held_item() != src) ..() return @@ -141,10 +140,7 @@ ..() -/obj/structure/sign/picture_frame/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) - . = ..() - if(.) - return +/obj/structure/sign/picture_frame/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(framed) framed.show(user) diff --git a/code/modules/pool/pool_drain.dm b/code/modules/pool/pool_drain.dm index 8deb9b1ffe..527c25b9f0 100644 --- a/code/modules/pool/pool_drain.dm +++ b/code/modules/pool/pool_drain.dm @@ -154,7 +154,7 @@ else new /mob/living/simple_animal/hostile/shark/laser(loc) -/obj/machinery/pool/filter/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/machinery/pool/filter/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) to_chat(user, "You search the filter.") for(var/obj/O in contents) O.forceMove(loc) diff --git a/code/modules/pool/pool_main.dm b/code/modules/pool/pool_main.dm index 30d1744b57..98189cc8a4 100644 --- a/code/modules/pool/pool_main.dm +++ b/code/modules/pool/pool_main.dm @@ -177,7 +177,7 @@ else return ..() -/turf/open/pool/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) +/turf/open/pool/on_attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/modules/pool/pool_structures.dm b/code/modules/pool/pool_structures.dm index 6b71e95639..ec5d455958 100644 --- a/code/modules/pool/pool_structures.dm +++ b/code/modules/pool/pool_structures.dm @@ -11,7 +11,7 @@ layer = ABOVE_MOB_LAYER dir = EAST -/obj/structure/pool/ladder/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/structure/pool/ladder/on_attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return @@ -52,7 +52,7 @@ user.pixel_x = initial_px user.pixel_y = initial_py -/obj/structure/pool/Lboard/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/structure/pool/Lboard/on_attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) if(iscarbon(user)) var/mob/living/carbon/jumper = user if(jumping) diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm index 3f9ca4f1b7..ba51eb3bef 100644 --- a/code/modules/power/apc.dm +++ b/code/modules/power/apc.dm @@ -38,6 +38,8 @@ #define APC_CHARGING 1 #define APC_FULLY_CHARGED 2 +#define MAXIMUM_COG_REGAIN 100 //How much charge drained by an integration cog can be priority-recharged in one processing-tick + // the Area Power Controller (APC), formerly Power Distribution Unit (PDU) // one per area, needs wire connection to power network through a terminal @@ -94,6 +96,7 @@ var/mob/living/silicon/ai/occupier = null var/transfer_in_progress = FALSE //Is there an AI being transferred out of us? var/obj/item/clockwork/integration_cog/integration_cog //Is there a cog siphoning power? + var/cog_drained = 0 //How much of the cell's charge was drained by an integration cog, recovering this amount takes priority over the normal APC cell recharge calculations, but comes after powering Essentials. var/longtermpower = 10 var/auto_name = 0 var/failure_timer = 0 @@ -499,6 +502,7 @@ cell.forceMove(T) cell.update_icon() cell = null + cog_drained = 0 //No more cell means no more averting celldrain charging = APC_NOT_CHARGING update_icon() return @@ -701,7 +705,7 @@ START_PROCESSING(SSfastprocess, W) playsound(src, 'sound/machines/clockcult/steam_whoosh.ogg', 50, FALSE) opened = APC_COVER_CLOSED - locked = FALSE + locked = TRUE //Clockies get full APC access on cogged APCs, but they can't lock or unlock em unless they steal some ID to give all of them APC access, soo this is pretty much just QoL for them and makes cogs a tiny bit more stealthy update_icon() return else if(panel_open && !opened && is_wire_tool(W)) @@ -833,10 +837,7 @@ // attack with hand - remove cell (if cover open) or interact with the APC -/obj/machinery/power/apc/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) - . = ..() - if(.) - return +/obj/machinery/power/apc/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(opened && (!issilicon(user))) if(cell) user.visible_message("[user] removes \the [cell] from [src]!","You remove \the [cell].") @@ -1314,6 +1315,11 @@ cur_used -= lastused_light lighting_satisfied = TRUE + //If drained by an integration cog: Forcefully avert as much of the powerdrain as possible, though a maximum of MAXIMUM_COG_REGAIN + if(cur_excess && cog_drained && cell) + var/cog_regain = cell.give(min(min(cog_drained, cur_excess), MAXIMUM_COG_REGAIN)) + cur_excess -= cog_regain + cog_drained = max(0, cog_drained - cog_regain) // next: take from or charge to the cell, depending on how much is left if(cell && !shorted) @@ -1576,6 +1582,8 @@ #undef APC_UPOVERLAY_LOCKED #undef APC_UPOVERLAY_OPERATING +#undef MAXIMUM_COG_REGAIN + /*Power module, used for APC construction*/ /obj/item/electronics/apc name = "power control module" diff --git a/code/modules/power/cable.dm b/code/modules/power/cable.dm index c8b02669e8..6dcb08512c 100644 --- a/code/modules/power/cable.dm +++ b/code/modules/power/cable.dm @@ -564,10 +564,7 @@ By design, d1 is the smallest direction and d2 is the highest icon_state = "[initial(item_state)][amount < 3 ? amount : ""]" name = "cable [amount < 3 ? "piece" : "coil"]" -/obj/item/stack/cable_coil/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) - . = ..() - if(.) - return +/obj/item/stack/cable_coil/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) var/obj/item/stack/cable_coil/new_cable = ..() if(istype(new_cable)) new_cable.color = color diff --git a/code/modules/power/floodlight.dm b/code/modules/power/floodlight.dm index 2bd4c04402..466030b83c 100644 --- a/code/modules/power/floodlight.dm +++ b/code/modules/power/floodlight.dm @@ -92,10 +92,7 @@ else . = ..() -/obj/machinery/power/floodlight/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) - . = ..() - if(.) - return +/obj/machinery/power/floodlight/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) var/current = setting if(current == 1) current = light_setting_list.len diff --git a/code/modules/power/gravitygenerator.dm b/code/modules/power/gravitygenerator.dm index 76154907ae..30a7aa152b 100644 --- a/code/modules/power/gravitygenerator.dm +++ b/code/modules/power/gravitygenerator.dm @@ -80,7 +80,7 @@ GLOBAL_LIST_EMPTY(gravity_generators) // We will keep track of this by adding ne /obj/machinery/gravity_generator/part/get_status() return main_part?.get_status() -/obj/machinery/gravity_generator/part/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/machinery/gravity_generator/part/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) return main_part.attack_hand(user) /obj/machinery/gravity_generator/part/set_broken() diff --git a/code/modules/power/lighting.dm b/code/modules/power/lighting.dm index f911a6a4e4..20f7ce099a 100644 --- a/code/modules/power/lighting.dm +++ b/code/modules/power/lighting.dm @@ -595,11 +595,9 @@ // attack with hand - remove tube/bulb // if hands aren't protected and the light is on, burn the player -/obj/machinery/light/attack_hand(mob/living/carbon/human/user) +/obj/machinery/light/on_attack_hand(mob/living/carbon/human/user) . = ..() - if(.) - return - user.changeNext_move(CLICK_CD_MELEE) + user.DelayNextAction(CLICK_CD_MELEE) add_fingerprint(user) if(status == LIGHT_EMPTY) @@ -812,11 +810,11 @@ return /obj/item/light/attack(mob/living/M, mob/living/user, def_zone) - ..() + . = ..() shatter() /obj/item/light/attack_obj(obj/O, mob/living/user) - ..() + . = ..() shatter() /obj/item/light/proc/shatter() diff --git a/code/modules/power/singularity/collector.dm b/code/modules/power/singularity/collector.dm index 4cc9cbe34f..256b13ee72 100644 --- a/code/modules/power/singularity/collector.dm +++ b/code/modules/power/singularity/collector.dm @@ -176,6 +176,7 @@ /obj/machinery/power/rad_collector/analyzer_act(mob/living/user, obj/item/I) if(loaded_tank) loaded_tank.analyzer_act(user, I) + return TRUE /obj/machinery/power/rad_collector/examine(mob/user) . = ..() diff --git a/code/modules/power/singularity/containment_field.dm b/code/modules/power/singularity/containment_field.dm index 5ef66e26d9..dfb51df9cf 100644 --- a/code/modules/power/singularity/containment_field.dm +++ b/code/modules/power/singularity/containment_field.dm @@ -21,8 +21,7 @@ FG2.fields -= src return ..() -//ATTACK HAND IGNORING PARENT RETURN VALUE -/obj/machinery/field/containment/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/machinery/field/containment/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(get_dist(src, user) > 1) return FALSE else diff --git a/code/modules/power/singularity/emitter.dm b/code/modules/power/singularity/emitter.dm index 0d182e0a1b..50dae7d6bb 100644 --- a/code/modules/power/singularity/emitter.dm +++ b/code/modules/power/singularity/emitter.dm @@ -315,6 +315,9 @@ /obj/machinery/power/emitter/proc/integrate(obj/item/gun/energy/E,mob/user) if(istype(E, /obj/item/gun/energy)) + if(!E.can_emitter) + to_chat(user, "[E] cannot fit into emitters.") + return if(!user.transferItemToLoc(E, src)) return gun = E diff --git a/code/modules/power/singularity/particle_accelerator/particle_accelerator.dm b/code/modules/power/singularity/particle_accelerator/particle_accelerator.dm index e33116b02c..528a3abb8b 100644 --- a/code/modules/power/singularity/particle_accelerator/particle_accelerator.dm +++ b/code/modules/power/singularity/particle_accelerator/particle_accelerator.dm @@ -103,7 +103,6 @@ did_something = TRUE if(did_something) - user.changeNext_move(CLICK_CD_MELEE) update_state() update_icon() return diff --git a/code/modules/power/singularity/particle_accelerator/particle_control.dm b/code/modules/power/singularity/particle_accelerator/particle_control.dm index beaf4bfc43..912fc0a72b 100644 --- a/code/modules/power/singularity/particle_accelerator/particle_control.dm +++ b/code/modules/power/singularity/particle_accelerator/particle_control.dm @@ -246,7 +246,6 @@ did_something = TRUE if(did_something) - user.changeNext_move(CLICK_CD_MELEE) update_state() update_icon() return diff --git a/code/modules/power/singularity/singularity.dm b/code/modules/power/singularity/singularity.dm index 96f8b4e996..cc3a19cf55 100644 --- a/code/modules/power/singularity/singularity.dm +++ b/code/modules/power/singularity/singularity.dm @@ -59,7 +59,7 @@ last_failed_movement = direct return 0 -/obj/singularity/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/singularity/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) consume(user) return TRUE diff --git a/code/modules/power/supermatter/supermatter.dm b/code/modules/power/supermatter/supermatter.dm index 823ba75e43..8559b8ba45 100644 --- a/code/modules/power/supermatter/supermatter.dm +++ b/code/modules/power/supermatter/supermatter.dm @@ -571,7 +571,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) /obj/machinery/power/supermatter_crystal/attack_ai(mob/user) return -/obj/machinery/power/supermatter_crystal/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/machinery/power/supermatter_crystal/on_attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/modules/projectiles/ammunition/_ammunition.dm b/code/modules/projectiles/ammunition/_ammunition.dm index ee6a25d8e4..6a73d9a366 100644 --- a/code/modules/projectiles/ammunition/_ammunition.dm +++ b/code/modules/projectiles/ammunition/_ammunition.dm @@ -16,7 +16,8 @@ var/variance = 0 //Variance for inaccuracy fundamental to the casing var/randomspread = 0 //Randomspread for automatics var/delay = 0 //Delay for energy weapons - var/click_cooldown_override = 0 //Override this to make your gun have a faster fire rate, in tenths of a second. 4 is the default gun cooldown. + /// Override this to make the gun check for a different cooldown rather than CLICK_CD_RANGE, which is 4 deciseconds. + var/click_cooldown_override var/firing_effect_type = /obj/effect/temp_visual/dir_setting/firing_effect //the visual effect appearing when the ammo is fired. var/heavy_metal = TRUE var/harmful = TRUE //pacifism check for boolet, set to FALSE if bullet is non-lethal diff --git a/code/modules/projectiles/ammunition/_firing.dm b/code/modules/projectiles/ammunition/_firing.dm index 340cfc2e98..0ef4c680aa 100644 --- a/code/modules/projectiles/ammunition/_firing.dm +++ b/code/modules/projectiles/ammunition/_firing.dm @@ -16,10 +16,7 @@ AddComponent(/datum/component/pellet_cloud, projectile_type, pellets) SEND_SIGNAL(src, COMSIG_PELLET_CLOUD_INIT, target, user, fired_from, randomspread, spread, zone_override, params, distro) - if(click_cooldown_override) - user.changeNext_move(click_cooldown_override) - else - user.changeNext_move(CLICK_CD_RANGE) + user.DelayNextAction(considered_action = TRUE, immediate = FALSE) user.newtonian_move(get_dir(target, user)) update_icon() return 1 diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index 55d44380c2..4126c81367 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -17,6 +17,7 @@ force = 5 item_flags = NEEDS_PERMIT attack_verb = list("struck", "hit", "bashed") + attack_speed = CLICK_CD_RANGE var/fire_sound = "gunshot" var/suppressed = null //whether or not a message is displayed when fired @@ -28,6 +29,13 @@ trigger_guard = TRIGGER_GUARD_NORMAL //trigger guard on the weapon, hulks can't fire them with their big meaty fingers var/sawn_desc = null //description change if weapon is sawn-off var/sawn_off = FALSE + + /// can we be put into a turret + var/can_turret = TRUE + /// can we be put in a circuit + var/can_circuit = TRUE + /// can we be put in an emitter + var/can_emitter = TRUE /// Weapon is burst fire if this is above 1 var/burst_size = 1 @@ -166,6 +174,8 @@ /obj/item/gun/afterattack(atom/target, mob/living/user, flag, params) . = ..() + if(!CheckAttackCooldown(user, target)) + return process_afterattack(target, user, flag, params) /obj/item/gun/proc/process_afterattack(atom/target, mob/living/user, flag, params) @@ -174,9 +184,6 @@ if(firing) return var/stamloss = user.getStaminaLoss() - if(stamloss >= STAMINA_NEAR_SOFTCRIT) //The more tired you are, the less damage you do. - var/penalty = (stamloss - STAMINA_NEAR_SOFTCRIT)/(STAMINA_NEAR_CRIT - STAMINA_NEAR_SOFTCRIT)*STAM_CRIT_GUN_DELAY - user.changeNext_move(CLICK_CD_RANGE+(CLICK_CD_RANGE*penalty)) if(flag) //It's adjacent, is the user, or is on the user's person if(target in user.contents) //can't shoot stuff inside us. return @@ -218,6 +225,8 @@ to_chat(user, "You need both hands free to fire \the [src]!") return + user.DelayNextAction() + //DUAL (or more!) WIELDING var/bonus_spread = 0 var/loop_counter = 0 @@ -248,6 +257,17 @@ to_chat(user, " [src] is lethally chambered! You don't want to risk harming anyone...") return FALSE +/obj/item/gun/CheckAttackCooldown(mob/user, atom/target) + if((user.a_intent == INTENT_HARM) && user.Adjacent(target)) //melee + return user.CheckActionCooldown(CLICK_CD_MELEE) + return user.CheckActionCooldown(get_clickcd()) + +/obj/item/gun/proc/get_clickcd() + return isnull(chambered?.click_cooldown_override)? CLICK_CD_RANGE : chambered.click_cooldown_override + +/obj/item/gun/GetEstimatedAttackSpeed() + return get_clickcd() + /obj/item/gun/proc/handle_pins(mob/living/user) if(no_pin_required) return TRUE @@ -362,17 +382,14 @@ if(user.a_intent == INTENT_HARM) //Flogging if(bayonet) M.attackby(bayonet, user) - attack_delay_done = TRUE return else return ..() - attack_delay_done = TRUE //we are firing the gun, not bashing people with its butt. /obj/item/gun/attack_obj(obj/O, mob/user) if(user.a_intent == INTENT_HARM) if(bayonet) - O.attackby(bayonet, user) - return TRUE + return O.attackby(bayonet, user) return ..() /obj/item/gun/attackby(obj/item/I, mob/user, params) diff --git a/code/modules/projectiles/guns/ballistic.dm b/code/modules/projectiles/guns/ballistic.dm index e5dc056011..fa8099a257 100644 --- a/code/modules/projectiles/guns/ballistic.dm +++ b/code/modules/projectiles/guns/ballistic.dm @@ -97,8 +97,7 @@ w_class += S.w_class //so pistols do not fit in pockets when suppressed update_icon() -//ATTACK HAND IGNORING PARENT RETURN VALUE -/obj/item/gun/ballistic/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/item/gun/ballistic/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(loc == user) if(suppressed && can_unsuppress) var/obj/item/suppressor/S = suppressed @@ -180,13 +179,11 @@ #undef BRAINS_BLOWN_THROW_SPEED #undef BRAINS_BLOWN_THROW_RANGE - - /obj/item/gun/ballistic/proc/sawoff(mob/user) if(sawn_off) to_chat(user, "\The [src] is already shortened!") return - user.changeNext_move(CLICK_CD_MELEE) + user.DelayNextAction(CLICK_CD_MELEE) user.visible_message("[user] begins to shorten \the [src].", "You begin to shorten \the [src]...") //if there's any live ammo inside the gun, makes it go off diff --git a/code/modules/projectiles/guns/ballistic/automatic.dm b/code/modules/projectiles/guns/ballistic/automatic.dm index 89e30e765b..b31fd2d1e0 100644 --- a/code/modules/projectiles/guns/ballistic/automatic.dm +++ b/code/modules/projectiles/guns/ballistic/automatic.dm @@ -327,8 +327,7 @@ . = ..() update_icon() -//ATTACK HAND IGNORING PARENT RETURN VALUE -/obj/item/gun/ballistic/automatic/l6_saw/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/item/gun/ballistic/automatic/l6_saw/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(loc != user) ..() return //let them pick it up diff --git a/code/modules/projectiles/guns/ballistic/laser_gatling.dm b/code/modules/projectiles/guns/ballistic/laser_gatling.dm index c2dd5bb42d..244bc5b124 100644 --- a/code/modules/projectiles/guns/ballistic/laser_gatling.dm +++ b/code/modules/projectiles/guns/ballistic/laser_gatling.dm @@ -29,8 +29,7 @@ /obj/item/minigunpack/process() overheat = max(0, overheat - heat_diffusion) -//ATTACK HAND IGNORING PARENT RETURN VALUE -/obj/item/minigunpack/attack_hand(var/mob/living/carbon/user) +/obj/item/minigunpack/on_attack_hand(var/mob/living/carbon/user) if(src.loc == user) if(!armed) if(user.get_item_by_slot(SLOT_BACK) == src) diff --git a/code/modules/projectiles/guns/ballistic/toy.dm b/code/modules/projectiles/guns/ballistic/toy.dm index 5cdd773894..1f66cfdf8a 100644 --- a/code/modules/projectiles/guns/ballistic/toy.dm +++ b/code/modules/projectiles/guns/ballistic/toy.dm @@ -56,6 +56,7 @@ item_flags = NONE casing_ejector = FALSE can_suppress = FALSE + weapon_weight = WEAPON_MEDIUM /obj/item/gun/ballistic/shotgun/toy/process_chamber(mob/living/user, empty_chamber = 0) ..() diff --git a/code/modules/projectiles/guns/misc/beam_rifle.dm b/code/modules/projectiles/guns/misc/beam_rifle.dm index bcb074023f..fd09aa7f9d 100644 --- a/code/modules/projectiles/guns/misc/beam_rifle.dm +++ b/code/modules/projectiles/guns/misc/beam_rifle.dm @@ -29,6 +29,8 @@ ammo_type = list(/obj/item/ammo_casing/energy/beam_rifle/hitscan) cell_type = /obj/item/stock_parts/cell/beam_rifle canMouseDown = TRUE + can_turret = FALSE + can_circuit = FALSE //Cit changes: beam rifle stats. slowdown = 1 item_flags = NO_MAT_REDEMPTION | SLOWS_WHILE_IN_HAND | NEEDS_PERMIT @@ -418,10 +420,10 @@ var/wall_devastate = 0 var/aoe_structure_range = 0 var/aoe_structure_damage = 0 - var/aoe_fire_range = 0 - var/aoe_fire_chance = 0 - var/aoe_mob_range = 0 - var/aoe_mob_damage = 0 + var/aoe_fire_range = 2 + var/aoe_fire_chance = 100 + var/aoe_mob_range = 2 + var/aoe_mob_damage = 30 var/impact_structure_damage = 0 var/impact_direct_damage = 0 var/turf/cached diff --git a/code/modules/reagents/chemistry/reagents/drug_reagents.dm b/code/modules/reagents/chemistry/reagents/drug_reagents.dm index f1e45d0717..96f2c04598 100644 --- a/code/modules/reagents/chemistry/reagents/drug_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/drug_reagents.dm @@ -467,7 +467,7 @@ /datum/reagent/drug/skooma/on_mob_metabolize(mob/living/L) . = ..() L.add_movespeed_modifier(/datum/movespeed_modifier/reagent/skooma) - L.next_move_modifier *= 2 + L.action_cooldown_mod *= 2 if(ishuman(L)) var/mob/living/carbon/human/H = L if(H.physiology) @@ -480,7 +480,7 @@ /datum/reagent/drug/skooma/on_mob_end_metabolize(mob/living/L) . = ..() L.remove_movespeed_modifier(/datum/movespeed_modifier/reagent/skooma) - L.next_move_modifier *= 0.5 + L.action_cooldown_mod *= 0.5 if(ishuman(L)) var/mob/living/carbon/human/H = L if(H.physiology) @@ -542,13 +542,13 @@ /datum/reagent/syndicateadrenals/on_mob_metabolize(mob/living/M) . = ..() if(istype(M)) - M.next_move_modifier *= 0.5 + M.action_cooldown_mod *= 0.5 to_chat(M, "You feel an intense surge of energy rushing through your veins.") /datum/reagent/syndicateadrenals/on_mob_end_metabolize(mob/living/M) . = ..() if(istype(M)) - M.next_move_modifier *= 2 + M.action_cooldown_mod *= 2 to_chat(M, "You feel as though the world around you is going faster.") /datum/reagent/syndicateadrenals/overdose_start(mob/living/M) diff --git a/code/modules/reagents/reagent_containers.dm b/code/modules/reagents/reagent_containers.dm index fbdbb5f656..b71584982c 100644 --- a/code/modules/reagents/reagent_containers.dm +++ b/code/modules/reagents/reagent_containers.dm @@ -69,7 +69,8 @@ to_chat(user, "[src]'s transfer amount is now [amount_per_transfer_from_this] units.") return -/obj/item/reagent_containers/attack(mob/M, mob/user, def_zone) +/obj/item/reagent_containers/attack(mob/living/M, mob/living/user, attackchain_flags = NONE, damage_multiplier = 1) + . = ..() if(user.a_intent == INTENT_HARM) return ..() diff --git a/code/modules/reagents/reagent_containers/glass.dm b/code/modules/reagents/reagent_containers/glass.dm index 37ea2ca70d..ec26182813 100644 --- a/code/modules/reagents/reagent_containers/glass.dm +++ b/code/modules/reagents/reagent_containers/glass.dm @@ -9,6 +9,11 @@ container_HP = 2 /obj/item/reagent_containers/glass/attack(mob/M, mob/user, obj/target) + // WARNING: This entire section is shitcode and prone to breaking at any time. + INVOKE_ASYNC(src, .proc/attempt_feed, M, user, target) // for example, the arguments in this proc are wrong + // but i don't have time to properly fix it right now. + +/obj/item/reagent_containers/glass/proc/attempt_feed(mob/M, mob/user, obj/target) if(!canconsume(M, user)) return diff --git a/code/modules/reagents/reagent_containers/hypospray.dm b/code/modules/reagents/reagent_containers/hypospray.dm index 7dcf996cab..27db55d7af 100644 --- a/code/modules/reagents/reagent_containers/hypospray.dm +++ b/code/modules/reagents/reagent_containers/hypospray.dm @@ -361,13 +361,17 @@ obj_flags |= EMAGGED return TRUE -/obj/item/hypospray/mkii/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/item/hypospray/mkii/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() //Don't bother changing this or removing it from containers will break. /obj/item/hypospray/mkii/attack(obj/item/I, mob/user, params) return /obj/item/hypospray/mkii/afterattack(atom/target, mob/user, proximity) + . = ..() + INVOKE_ASYNC(src, .proc/attempt_inject, target, user, proximity) + +/obj/item/hypospray/mkii/proc/attempt_inject(atom/target, mob/user, proximity) if(!vial || !proximity || !isliving(target)) return var/mob/living/L = target diff --git a/code/modules/reagents/reagent_containers/maunamug.dm b/code/modules/reagents/reagent_containers/maunamug.dm index 1600699226..3dfac8a631 100644 --- a/code/modules/reagents/reagent_containers/maunamug.dm +++ b/code/modules/reagents/reagent_containers/maunamug.dm @@ -88,7 +88,7 @@ user.visible_message("[user] inserts a power cell into [src].", "You insert the power cell into [src].") update_icon() -/obj/item/reagent_containers/glass/maunamug/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/item/reagent_containers/glass/maunamug/on_attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) if(cell && open) cell.update_icon() user.put_in_hands(cell) diff --git a/code/modules/reagents/reagent_containers/pill.dm b/code/modules/reagents/reagent_containers/pill.dm index ec1e7823ed..3c23794e5a 100644 --- a/code/modules/reagents/reagent_containers/pill.dm +++ b/code/modules/reagents/reagent_containers/pill.dm @@ -28,22 +28,24 @@ /obj/item/reagent_containers/pill/get_w_volume() // DEFAULT_VOLUME_TINY at 25u, DEFAULT_VOLUME_SMALL at 50u return DEFAULT_VOLUME_TINY/2 + reagents.total_volume / reagents.maximum_volume * DEFAULT_VOLUME_TINY -/obj/item/reagent_containers/pill/attack(mob/M, mob/user, def_zone) +/obj/item/reagent_containers/pill/attack(mob/living/M, mob/living/user, attackchain_flags = NONE, damage_multiplier = 1) + INVOKE_ASYNC(src, .proc/attempt_feed, M, user) + +/obj/item/reagent_containers/pill/proc/attempt_feed(mob/living/M, mob/living/user) if(!canconsume(M, user)) - return 0 + return FALSE if(M == user) M.visible_message("[user] attempts to [apply_method] [src].") if(self_delay) if(!do_mob(user, M, self_delay)) - return 0 + return FALSE to_chat(M, "You [apply_method] [src].") - else M.visible_message("[user] attempts to force [M] to [apply_method] [src].", \ "[user] attempts to force [M] to [apply_method] [src].") if(!do_mob(user, M)) - return 0 + return FALSE M.visible_message("[user] forces [M] to [apply_method] [src].", \ "[user] forces [M] to [apply_method] [src].") @@ -56,8 +58,7 @@ reagents.reaction(M, apply_type) reagents.trans_to(M, reagents.total_volume) qdel(src) - return 1 - + return TRUE /obj/item/reagent_containers/pill/afterattack(obj/target, mob/user , proximity) . = ..() @@ -77,6 +78,7 @@ "You dissolve [src] in [target].", vision_distance = 2) reagents.trans_to(target, reagents.total_volume) qdel(src) + return STOP_ATTACK_PROC_CHAIN /obj/item/reagent_containers/pill/tox name = "toxins pill" diff --git a/code/modules/reagents/reagent_containers/rags.dm b/code/modules/reagents/reagent_containers/rags.dm index afa188e9f6..469a8ef907 100644 --- a/code/modules/reagents/reagent_containers/rags.dm +++ b/code/modules/reagents/reagent_containers/rags.dm @@ -55,11 +55,10 @@ if(do_after(user, action_speed, target = A)) user.visible_message("[user] finishes wiping off [A]!", "You finish wiping off [A].") SEND_SIGNAL(A, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_MEDIUM) - return /obj/item/reagent_containers/rag/alt_pre_attack(mob/living/M, mob/living/user, params) if(istype(M) && user.a_intent == INTENT_HELP) - user.changeNext_move(CLICK_CD_MELEE) + user.DelayNextAction(CLICK_CD_MELEE) if(M.on_fire) user.visible_message("\The [user] uses \the [src] to pat out [M == user ? "[user.p_their()]" : "\the [M]'s"] flames!") if(hitsound) @@ -193,4 +192,4 @@ extinguish_efficiency = 5 action_speed = 15 damp_threshold = 0.8 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 20, "bio" = 20, "rad" = 20, "fire" = 50, "acid" = 50) //items don't provide armor to wearers unlike clothing yet. \ No newline at end of file + armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 20, "bio" = 20, "rad" = 20, "fire" = 50, "acid" = 50) //items don't provide armor to wearers unlike clothing yet. diff --git a/code/modules/reagents/reagent_containers/spray.dm b/code/modules/reagents/reagent_containers/spray.dm index 7fea8250d9..9b25a80680 100644 --- a/code/modules/reagents/reagent_containers/spray.dm +++ b/code/modules/reagents/reagent_containers/spray.dm @@ -27,6 +27,8 @@ /obj/item/reagent_containers/spray/afterattack(atom/A, mob/user) . = ..() + if(!user.CheckActionCooldown(CLICK_CD_MELEE)) + return if(istype(A, /obj/structure/sink) || istype(A, /obj/structure/janitorialcart) || istype(A, /obj/machinery/hydroponics)) return @@ -50,7 +52,7 @@ spray(A) playsound(src.loc, 'sound/effects/spray2.ogg', 50, 1, -6) - user.changeNext_move(CLICK_CD_RANGE*2) + user.last_action = world.time user.newtonian_move(get_dir(A, user)) var/turf/T = get_turf(src) if(reagents.has_reagent(/datum/reagent/toxin/acid)) diff --git a/code/modules/reagents/reagent_containers/syringes.dm b/code/modules/reagents/reagent_containers/syringes.dm index 4ab1470667..0220802c3e 100644 --- a/code/modules/reagents/reagent_containers/syringes.dm +++ b/code/modules/reagents/reagent_containers/syringes.dm @@ -42,8 +42,7 @@ mode = !mode update_icon() -//ATTACK HAND IGNORING PARENT RETURN VALUE -/obj/item/reagent_containers/syringe/attack_hand() +/obj/item/reagent_containers/syringe/on_attack_hand() . = ..() update_icon() @@ -53,8 +52,11 @@ /obj/item/reagent_containers/syringe/attackby(obj/item/I, mob/user, params) return -/obj/item/reagent_containers/syringe/afterattack(atom/target, mob/user , proximity) +/obj/item/reagent_containers/syringe/afterattack(atom/target, mob/user, proximity) . = ..() + INVOKE_ASYNC(src, .proc/attempt_inject, target, user, proximity) + +/obj/item/reagent_containers/syringe/proc/attempt_inject(atom/target, mob/user, proximity) if(busy) return if(!proximity) diff --git a/code/modules/reagents/reagent_dispenser.dm b/code/modules/reagents/reagent_dispenser.dm index 0131e6d028..819012a61a 100644 --- a/code/modules/reagents/reagent_dispenser.dm +++ b/code/modules/reagents/reagent_dispenser.dm @@ -79,7 +79,7 @@ else . += "There are no paper cups left." -/obj/structure/reagent_dispensers/water_cooler/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/structure/reagent_dispensers/water_cooler/on_attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/modules/recycling/conveyor2.dm b/code/modules/recycling/conveyor2.dm index d8cb462c97..b81c3b88f8 100644 --- a/code/modules/recycling/conveyor2.dm +++ b/code/modules/recycling/conveyor2.dm @@ -174,10 +174,7 @@ GLOBAL_LIST_EMPTY(conveyors_by_id) return ..() // attack with hand, move pulled object onto conveyor -/obj/machinery/conveyor/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) - . = ..() - if(.) - return +/obj/machinery/conveyor/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) user.Move_Pulled(src) // make the conveyor broken diff --git a/code/modules/research/designs/tool_designs.dm b/code/modules/research/designs/tool_designs.dm index 551d6fa0e3..4fe07cb02f 100644 --- a/code/modules/research/designs/tool_designs.dm +++ b/code/modules/research/designs/tool_designs.dm @@ -92,6 +92,16 @@ category = list("Tool Designs") departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_CARGO +/datum/design/ranged_analyzer + name = "Long-range Analyzer" + desc = "A new advanced atmospheric analyzer design, capable of performing scans at long range." + id = "ranged_analyzer" + build_type = PROTOLATHE + materials = list(/datum/material/iron = 400, /datum/material/glass = 1000, /datum/material/uranium = 800, /datum/material/gold = 200, /datum/material/plastic = 200) + build_path = /obj/item/analyzer/ranged + category = list("Tool Designs") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING + ///////////////////////////////////////// //////////////Alien Tools//////////////// ///////////////////////////////////////// diff --git a/code/modules/research/nanites/nanite_chamber.dm b/code/modules/research/nanites/nanite_chamber.dm index 4a980a0436..01513a0b41 100644 --- a/code/modules/research/nanites/nanite_chamber.dm +++ b/code/modules/research/nanites/nanite_chamber.dm @@ -150,8 +150,6 @@ return if(busy) return - user.changeNext_move(CLICK_CD_BREAKOUT) - user.last_special = world.time + CLICK_CD_BREAKOUT user.visible_message("You see [user] kicking against the door of [src]!", \ "You lean on the back of [src] and start pushing the door open... (this will take about [DisplayTimeText(breakout_time)].)", \ "You hear a metallic creaking from [src].") diff --git a/code/modules/research/nanites/public_chamber.dm b/code/modules/research/nanites/public_chamber.dm index 76392c66e9..b7a8db4080 100644 --- a/code/modules/research/nanites/public_chamber.dm +++ b/code/modules/research/nanites/public_chamber.dm @@ -130,8 +130,6 @@ return if(busy) return - user.changeNext_move(CLICK_CD_BREAKOUT) - user.last_special = world.time + CLICK_CD_BREAKOUT user.visible_message("You see [user] kicking against the door of [src]!", \ "You lean on the back of [src] and start pushing the door open... (this will take about [DisplayTimeText(breakout_time)].)", \ "You hear a metallic creaking from [src].") diff --git a/code/modules/research/techweb/nodes/tools_nodes.dm b/code/modules/research/techweb/nodes/tools_nodes.dm index b084979116..180cdb5778 100644 --- a/code/modules/research/techweb/nodes/tools_nodes.dm +++ b/code/modules/research/techweb/nodes/tools_nodes.dm @@ -44,7 +44,7 @@ id = "exp_tools" display_name = "Experimental Tools" description = "Highly advanced construction tools." - design_ids = list("exwelder", "jawsoflife", "handdrill", "holosigncombifan") + design_ids = list("exwelder", "jawsoflife", "handdrill", "holosigncombifan", "ranged_analyzer") prereq_ids = list("adv_engi") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2750) diff --git a/code/modules/research/xenobiology/crossbreeding/_clothing.dm b/code/modules/research/xenobiology/crossbreeding/_clothing.dm index 996b84131f..1ac09652b5 100644 --- a/code/modules/research/xenobiology/crossbreeding/_clothing.dm +++ b/code/modules/research/xenobiology/crossbreeding/_clothing.dm @@ -57,7 +57,7 @@ Slimecrossing Armor light_color = newcolor set_light(5) -/obj/structure/light_prism/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/structure/light_prism/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) to_chat(user, "You dispel [src]") qdel(src) @@ -118,7 +118,7 @@ Slimecrossing Armor ..() REMOVE_TRAIT(user, TRAIT_PACIFISM, "peaceflower_[REF(src)]") -/obj/item/clothing/head/peaceflower/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/item/clothing/head/peaceflower/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(iscarbon(user)) var/mob/living/carbon/C = user if(src == C.head) diff --git a/code/modules/ruins/lavalandruin_code/elephantgraveyard.dm b/code/modules/ruins/lavalandruin_code/elephantgraveyard.dm index 65530031c0..088683ccd2 100644 --- a/code/modules/ruins/lavalandruin_code/elephantgraveyard.dm +++ b/code/modules/ruins/lavalandruin_code/elephantgraveyard.dm @@ -73,7 +73,7 @@ create_reagents(20) reagents.add_reagent(dispensedreagent, 20) -/obj/structure/sink/oil_well/attack_hand(mob/M) +/obj/structure/sink/oil_well/on_attack_hand(mob/M) flick("puddle-oil-splash",src) reagents.reaction(M, TOUCH, 20) //Covers target in 20u of oil. to_chat(M, "You touch the pool of oil, only to get oil all over yourself. It would be wise to wash this off with water.") diff --git a/code/modules/ruins/objects_and_mobs/necropolis_gate.dm b/code/modules/ruins/objects_and_mobs/necropolis_gate.dm index e6f87eea13..fd2f4377e7 100644 --- a/code/modules/ruins/objects_and_mobs/necropolis_gate.dm +++ b/code/modules/ruins/objects_and_mobs/necropolis_gate.dm @@ -87,8 +87,7 @@ else return QDEL_HINT_LETMELIVE -//ATTACK HAND IGNORING PARENT RETURN VALUE -/obj/structure/necropolis_gate/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/structure/necropolis_gate/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(locked || uses == 0) to_chat(user, "It's [open ? "stuck open":"locked"].") return @@ -166,8 +165,7 @@ GLOBAL_DATUM(necropolis_gate, /obj/structure/necropolis_gate/legion_gate) else return QDEL_HINT_LETMELIVE -//ATTACK HAND IGNORING PARENT RETURN VALUE -/obj/structure/necropolis_gate/legion_gate/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/structure/necropolis_gate/legion_gate/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(!open && !changing_openness) var/safety = alert(user, "You think this might be a bad idea...", "Knock on the door?", "Proceed", "Abort") if(safety == "Abort" || !in_range(src, user) || !src || open || changing_openness || user.incapacitated()) diff --git a/code/modules/ruins/objects_and_mobs/sin_ruins.dm b/code/modules/ruins/objects_and_mobs/sin_ruins.dm index 8a98a1939f..e87382cd6a 100644 --- a/code/modules/ruins/objects_and_mobs/sin_ruins.dm +++ b/code/modules/ruins/objects_and_mobs/sin_ruins.dm @@ -57,7 +57,7 @@ canvas rotting away and contents vanishing.") qdel(src) -/obj/structure/cursed_money/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/structure/cursed_money/on_attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/modules/ruins/spaceruin_code/hilbertshotel.dm b/code/modules/ruins/spaceruin_code/hilbertshotel.dm index b74b32009f..d97eae5766 100644 --- a/code/modules/ruins/spaceruin_code/hilbertshotel.dm +++ b/code/modules/ruins/spaceruin_code/hilbertshotel.dm @@ -263,7 +263,7 @@ GLOBAL_VAR_INIT(hhmysteryRoomNumber, 1337) /turf/closed/indestructible/hoteldoor/attack_tk(mob/user) return //need to be close. -/turf/closed/indestructible/hoteldoor/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/turf/closed/indestructible/hoteldoor/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) promptExit(user) /turf/closed/indestructible/hoteldoor/attack_animal(mob/user) diff --git a/code/modules/shuttle/custom_shuttle.dm b/code/modules/shuttle/custom_shuttle.dm index 6ff15c628e..c71b6ba9a8 100644 --- a/code/modules/shuttle/custom_shuttle.dm +++ b/code/modules/shuttle/custom_shuttle.dm @@ -257,7 +257,7 @@ return ..() -/obj/machinery/computer/camera_advanced/shuttle_docker/custom/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/machinery/computer/camera_advanced/shuttle_docker/custom/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(!shuttleId) to_chat(user, "You must link the console to a shuttle first.") return diff --git a/code/modules/shuttle/navigation_computer.dm b/code/modules/shuttle/navigation_computer.dm index 0cf348a95b..195e87720c 100644 --- a/code/modules/shuttle/navigation_computer.dm +++ b/code/modules/shuttle/navigation_computer.dm @@ -29,7 +29,7 @@ . = ..() GLOB.navigation_computers -= src -/obj/machinery/computer/camera_advanced/shuttle_docker/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/machinery/computer/camera_advanced/shuttle_docker/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(jammed) to_chat(user, "The Syndicate is jamming the console!") return diff --git a/code/modules/shuttle/shuttle_creation/shuttle_creator_console.dm b/code/modules/shuttle/shuttle_creation/shuttle_creator_console.dm index 9af6d7fe9f..314d5e8b80 100644 --- a/code/modules/shuttle/shuttle_creation/shuttle_creator_console.dm +++ b/code/modules/shuttle/shuttle_creation/shuttle_creator_console.dm @@ -61,7 +61,7 @@ if(user?.client) user.client.images -= eyeobj.user_image -/obj/machinery/computer/camera_advanced/shuttle_creator/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/machinery/computer/camera_advanced/shuttle_creator/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(!is_operational()) //you cant use broken machine you chumbis return if(current_user) diff --git a/code/modules/shuttle/syndicate.dm b/code/modules/shuttle/syndicate.dm index 440e6cb03b..0076f584e9 100644 --- a/code/modules/shuttle/syndicate.dm +++ b/code/modules/shuttle/syndicate.dm @@ -1,4 +1,4 @@ -#define SYNDICATE_CHALLENGE_TIMER 12000 //20 minutes +#define SYNDICATE_CHALLENGE_TIMER 9000 // 15 minutes /obj/machinery/computer/shuttle/syndicate name = "syndicate shuttle terminal" @@ -21,8 +21,8 @@ /obj/machinery/computer/shuttle/syndicate/Topic(href, href_list) if(href_list["move"]) var/obj/item/circuitboard/computer/syndicate_shuttle/board = circuit - if(board.challenge && world.time < SYNDICATE_CHALLENGE_TIMER) - to_chat(usr, "You've issued a combat challenge to the station! You've got to give them at least [DisplayTimeText(SYNDICATE_CHALLENGE_TIMER - world.time)] more to allow them to prepare.") + if(board.challenge && ((world.time - SSticker.round_start_time) < SYNDICATE_CHALLENGE_TIMER)) + to_chat(usr, "You've issued a combat challenge to the station! You've got to give them at least [DisplayTimeText(SYNDICATE_CHALLENGE_TIMER - (world.time - SSticker.round_start_time))] more to allow them to prepare.") return 0 board.moved = TRUE ..() diff --git a/code/modules/spells/spell.dm b/code/modules/spells/spell.dm index 21552f7e87..57502e2cd5 100644 --- a/code/modules/spells/spell.dm +++ b/code/modules/spells/spell.dm @@ -56,11 +56,6 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) //needed for th to_chat(caller, "[caller.ranged_ability.name] has been disabled.") caller.ranged_ability.remove_ranged_ability() return TRUE //TRUE for failed, FALSE for passed. - if(ranged_clickcd_override >= 0) - ranged_ability_user.next_click = world.time + ranged_clickcd_override - else - ranged_ability_user.next_click = world.time + CLICK_CD_CLICK_ABILITY - ranged_ability_user.face_atom(A) return FALSE /obj/effect/proc_holder/proc/add_ranged_ability(mob/living/user, msg, forced) diff --git a/code/modules/spells/spell_types/spacetime_distortion.dm b/code/modules/spells/spell_types/spacetime_distortion.dm index bec0f7871a..5797cbf8b7 100644 --- a/code/modules/spells/spell_types/spacetime_distortion.dm +++ b/code/modules/spells/spell_types/spacetime_distortion.dm @@ -110,8 +110,7 @@ else walk_link(user) -//ATTACK HAND IGNORING PARENT RETURN VALUE -/obj/effect/cross_action/spacetime_dist/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/effect/cross_action/spacetime_dist/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) walk_link(user) /obj/effect/cross_action/spacetime_dist/attack_paw(mob/user) diff --git a/code/modules/station_goals/dna_vault.dm b/code/modules/station_goals/dna_vault.dm index 40fb066fe1..6d8ab9cc7f 100644 --- a/code/modules/station_goals/dna_vault.dm +++ b/code/modules/station_goals/dna_vault.dm @@ -279,5 +279,5 @@ H.add_movespeed_modifier(/datum/movespeed_modifier/dna_vault_speedup) if(VAULT_QUICK) to_chat(H, "Your arms move as fast as lightning.") - H.next_move_modifier = 0.5 + H.action_cooldown_mod = 0.5 power_lottery[H] = list() diff --git a/code/modules/surgery/organs/liver.dm b/code/modules/surgery/organs/liver.dm index 2465b63800..f0f98a5fa5 100755 --- a/code/modules/surgery/organs/liver.dm +++ b/code/modules/surgery/organs/liver.dm @@ -73,8 +73,8 @@ /obj/item/organ/liver/proc/sizeMoveMod(value, mob/living/carbon/C) if(cachedmoveCalc == value) return - C.next_move_modifier /= cachedmoveCalc - C.next_move_modifier *= value + C.action_cooldown_mod /= cachedmoveCalc + C.action_cooldown_mod *= value cachedmoveCalc = value /obj/item/organ/liver/fly diff --git a/code/modules/uplink/uplink_items/uplink_bundles.dm b/code/modules/uplink/uplink_items/uplink_bundles.dm index d40e2fcbda..fbeaee8939 100644 --- a/code/modules/uplink/uplink_items/uplink_bundles.dm +++ b/code/modules/uplink/uplink_items/uplink_bundles.dm @@ -50,7 +50,7 @@ Combines with all martial arts, but the user will be unable to bring themselves to use guns, nor remove the armbands." item = /obj/item/storage/box/syndie_kit/northstar cost = 20 - exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops, /datum/game_mode/traitor/internal_affairs) /datum/uplink_item/suits/infiltrator_bundle name = "Insidious Infiltration Gear Case" @@ -117,7 +117,7 @@ you will receive. May contain discontinued and/or exotic items." item = /obj/item/storage/box/syndicate cost = 20 - exclude_modes = list(/datum/game_mode/nuclear) + exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/traitor/internal_affairs) cant_discount = TRUE /datum/uplink_item/bundles_TC/surplus @@ -127,7 +127,7 @@ item = /obj/structure/closet/crate cost = 20 player_minimum = 25 - exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops, /datum/game_mode/traitor/internal_affairs) cant_discount = TRUE var/starting_crate_value = 50 @@ -163,7 +163,7 @@ /datum/uplink_item/bundles_TC/reroll name = "Renegotiate Contract" - desc = "Selecting this will inform the syndicate that you wish to change employers. Can only be done once; no take-backs." + desc = "Selecting this will inform your employers that you wish for new objectives. Can only be done once; no take-backs." item = /obj/effect/gibspawner/generic cost = 0 cant_discount = TRUE @@ -184,6 +184,7 @@ item = /obj/effect/gibspawner/generic // non-tangible item because techwebs use this path to determine illegal tech cost = 0 cant_discount = TRUE + exclude_modes = list(/datum/game_mode/traitor/internal_affairs) /datum/uplink_item/bundles_TC/random/purchase(mob/user, datum/component/uplink/U) var/list/uplink_items = U.uplink_items diff --git a/code/modules/uplink/uplink_items/uplink_dangerous.dm b/code/modules/uplink/uplink_items/uplink_dangerous.dm index 7d96390115..e068094776 100644 --- a/code/modules/uplink/uplink_items/uplink_dangerous.dm +++ b/code/modules/uplink/uplink_items/uplink_dangerous.dm @@ -21,7 +21,7 @@ item = /obj/item/storage/box/syndie_kit/revolver cost = 13 surplus = 50 - exclude_modes = list(/datum/game_mode/nuclear/clown_ops) + exclude_modes = list(/datum/game_mode/nuclear/clown_ops, /datum/game_mode/traitor/internal_affairs) /datum/uplink_item/dangerous/rawketlawnchair name = "84mm Rocket Propelled Grenade Launcher" @@ -112,7 +112,7 @@ item = /obj/item/dualsaber player_minimum = 25 cost = 16 - exclude_modes = list(/datum/game_mode/nuclear/clown_ops) + exclude_modes = list(/datum/game_mode/nuclear/clown_ops, /datum/game_mode/traitor/internal_affairs) /datum/uplink_item/dangerous/doublesword/get_discount() return pick(4;0.8,2;0.65,1;0.5) @@ -123,7 +123,7 @@ pocketed when inactive. Activating it produces a loud, distinctive noise." item = /obj/item/melee/transforming/energy/sword/saber cost = 8 - exclude_modes = list(/datum/game_mode/nuclear/clown_ops) + exclude_modes = list(/datum/game_mode/nuclear/clown_ops, /datum/game_mode/traitor/internal_affairs) /datum/uplink_item/dangerous/shield name = "Energy Shield" @@ -141,7 +141,7 @@ However, due to the size of the blade and obvious nature of the sheath, the weapon stands out as being obviously nefarious." item = /obj/item/storage/belt/sabre/rapier cost = 8 - exclude_modes = list(/datum/game_mode/nuclear/clown_ops) + exclude_modes = list(/datum/game_mode/nuclear/clown_ops, /datum/game_mode/traitor/internal_affairs) /datum/uplink_item/dangerous/flamethrower name = "Flamethrower" @@ -180,7 +180,7 @@ refundable = TRUE cant_discount = TRUE surplus = 0 - exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops, /datum/game_mode/traitor/internal_affairs) player_minimum = 25 restricted = TRUE refund_path = /obj/item/guardiancreator/tech/choose/traitor @@ -211,6 +211,7 @@ deal extra damage and hit targets further. Use a screwdriver to take out any attached tanks." item = /obj/item/melee/powerfist cost = 8 + exclude_modes = list(/datum/game_mode/traitor/internal_affairs) /datum/uplink_item/dangerous/sniper name = "Sniper Rifle" @@ -250,4 +251,4 @@ darts effective at incapacitating a target." item = /obj/item/gun/ballistic/automatic/toy/pistol/riot cost = 3 - surplus = 10 \ No newline at end of file + surplus = 10 diff --git a/code/modules/uplink/uplink_items/uplink_explosives.dm b/code/modules/uplink/uplink_items/uplink_explosives.dm index c52651fee9..6cc1c9fe05 100644 --- a/code/modules/uplink/uplink_items/uplink_explosives.dm +++ b/code/modules/uplink/uplink_items/uplink_explosives.dm @@ -58,6 +58,7 @@ item = /obj/item/storage/backpack/duffelbag/syndie/x4 cost = 4 // cant_discount = TRUE + exclude_modes = list(/datum/game_mode/traitor/internal_affairs) /datum/uplink_item/explosives/clown_bomb_clownops name = "Clown Bomb" @@ -123,6 +124,7 @@ be defused, and some crew may attempt to do so." item = /obj/item/sbeacondrop/bomb cost = 11 + exclude_modes = list(/datum/game_mode/traitor/internal_affairs) /datum/uplink_item/explosives/syndicate_detonator name = "Syndicate Detonator" @@ -140,7 +142,7 @@ in addition to dealing high amounts of damage to nearby personnel." item = /obj/item/grenade/syndieminibomb cost = 6 - exclude_modes = list(/datum/game_mode/nuclear/clown_ops) + exclude_modes = list(/datum/game_mode/nuclear/clown_ops, /datum/game_mode/traitor/internal_affairs) /datum/uplink_item/explosives/tearstache name = "Teachstache Grenade" diff --git a/code/modules/uplink/uplink_items/uplink_roles.dm b/code/modules/uplink/uplink_items/uplink_roles.dm index 859c8c0bd7..b8eaf41371 100644 --- a/code/modules/uplink/uplink_items/uplink_roles.dm +++ b/code/modules/uplink/uplink_items/uplink_roles.dm @@ -30,6 +30,7 @@ item = /obj/item/gun/blastcannon cost = 14 //High cost because of the potential for extreme damage in the hands of a skilled gas masked scientist. restricted_roles = list("Research Director", "Scientist") + exclude_modes = list(/datum/game_mode/traitor/internal_affairs) /datum/uplink_item/role_restricted/alientech name = "Alien Research Disk" @@ -100,6 +101,7 @@ player_minimum = 20 refundable = TRUE restricted_roles = list("Chaplain") + exclude_modes = list(/datum/game_mode/traitor/internal_affairs) /datum/uplink_item/role_restricted/arcane_tome name = "Arcane Tome" @@ -109,6 +111,7 @@ player_minimum = 20 refundable = TRUE restricted_roles = list("Chaplain") + exclude_modes = list(/datum/game_mode/traitor/internal_affairs) /datum/uplink_item/role_restricted/explosive_hot_potato name = "Exploding Hot Potato" diff --git a/code/modules/uplink/uplink_items/uplink_stealth.dm b/code/modules/uplink/uplink_items/uplink_stealth.dm index c60d4ef177..ff6d66a483 100644 --- a/code/modules/uplink/uplink_items/uplink_stealth.dm +++ b/code/modules/uplink/uplink_items/uplink_stealth.dm @@ -65,6 +65,16 @@ surplus = 0 exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) +/datum/uplink_item/stealthy_weapons/martialartsthree + name = "Krav Maga Scroll" + desc = "This scroll contains the secrets of an ancient martial arts technique. You will gain special unarmed attacks for \ + stealthy takedowns." + item = /obj/item/book/granter/martial/krav_maga + cost = 16 + player_minimum = 25 + surplus = 0 + include_modes = list(/datum/game_mode/traitor/internal_affairs) + /datum/uplink_item/stealthy_weapons/crossbow name = "Miniature Energy Crossbow" desc = "A short bow mounted across a tiller in miniature. Small enough to \ diff --git a/code/modules/vehicles/cars/car.dm b/code/modules/vehicles/cars/car.dm index fb30e66f97..4545fab2a7 100644 --- a/code/modules/vehicles/cars/car.dm +++ b/code/modules/vehicles/cars/car.dm @@ -57,7 +57,7 @@ return FALSE return ..() -/obj/vehicle/sealed/car/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/vehicle/sealed/car/on_attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(!(car_traits & CAN_KIDNAP)) return diff --git a/code/modules/vehicles/pimpin_ride.dm b/code/modules/vehicles/pimpin_ride.dm index 547eef7af2..8f9d553ec7 100644 --- a/code/modules/vehicles/pimpin_ride.dm +++ b/code/modules/vehicles/pimpin_ride.dm @@ -62,11 +62,8 @@ if(floorbuffer) . += "cart_buffer" -/obj/vehicle/ridden/janicart/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) - . = ..() - if(.) - return - else if(mybag) +/obj/vehicle/ridden/janicart/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) + if(mybag) mybag.forceMove(get_turf(user)) user.put_in_hands(mybag) mybag = null diff --git a/code/modules/vending/autodrobe.dm b/code/modules/vending/autodrobe.dm index 260b124283..bc824cc994 100644 --- a/code/modules/vending/autodrobe.dm +++ b/code/modules/vending/autodrobe.dm @@ -116,7 +116,8 @@ /obj/item/gun/magic/wand = 2, /obj/item/clothing/glasses/sunglasses/garb = 2, /obj/item/clothing/glasses/sunglasses/blindfold = 1, - /obj/item/clothing/mask/muzzle = 2) + /obj/item/clothing/mask/muzzle = 2, + /obj/item/clothing/under/syndicate/camo/cosmetic = 3) premium = list(/obj/item/clothing/suit/pirate/captain = 2, /obj/item/clothing/head/pirate/captain = 2, /obj/item/clothing/head/helmet/roman/fake = 1, diff --git a/code/modules/vending/cartridge.dm b/code/modules/vending/cartridge.dm index beaf6bb873..69635007c9 100644 --- a/code/modules/vending/cartridge.dm +++ b/code/modules/vending/cartridge.dm @@ -10,6 +10,7 @@ /obj/item/cartridge/security = 10, /obj/item/cartridge/janitor = 10, /obj/item/cartridge/signal/toxins = 10, + /obj/item/cartridge/roboticist = 10, /obj/item/pda/heads = 10) premium = list(/obj/item/cartridge/captain = 2, /obj/item/cartridge/quartermaster = 2) diff --git a/code/modules/vore/eating/belly_obj.dm b/code/modules/vore/eating/belly_obj.dm index 50cdc32bf6..a367abb098 100644 --- a/code/modules/vore/eating/belly_obj.dm +++ b/code/modules/vore/eating/belly_obj.dm @@ -542,8 +542,6 @@ if (!(R in contents)) return // User is not in this belly - R.changeNext_move(CLICK_CD_BREAKOUT*0.5) - if(owner.stat) //If owner is stat (dead, KO) we can actually escape to_chat(R,"You attempt to climb out of \the [lowertext(name)]. (This will take around [escapetime/10] seconds.)") to_chat(owner,"Someone is attempting to climb out of your [lowertext(name)]!") diff --git a/code/modules/vore/eating/living.dm b/code/modules/vore/eating/living.dm index 1c9bf029ea..9395cef952 100644 --- a/code/modules/vore/eating/living.dm +++ b/code/modules/vore/eating/living.dm @@ -349,7 +349,7 @@ if(incapacitated(ignore_restraints = TRUE)) to_chat(src, "You can't do that while incapacitated.") return - if(next_move > world.time) + if(!CheckActionCooldown()) to_chat(src, "You can't do that so fast, slow down.") return @@ -366,11 +366,10 @@ if(QDELETED(tasted) || (tasted.ckey && !(tasted.client?.prefs.vore_flags & LICKABLE)) || !Adjacent(tasted) || incapacitated(ignore_restraints = TRUE)) return - changeNext_move(CLICK_CD_MELEE) + DelayNextAction(CLICK_CD_MELEE) visible_message("[src] licks [tasted]!","You lick [tasted]. They taste rather like [tasted.get_taste_message()].","Slurp!") - /mob/living/proc/get_taste_message(allow_generic = TRUE, datum/species/mrace) if(!vore_taste && !allow_generic) return FALSE diff --git a/code/modules/zombie/items.dm b/code/modules/zombie/items.dm index 7038e9df7c..cf61e4b210 100644 --- a/code/modules/zombie/items.dm +++ b/code/modules/zombie/items.dm @@ -37,11 +37,11 @@ if(!proximity_flag) return else - if(istype(target, /obj/)) //do far more damage to non mobs so we can get through airlocks + if(istype(target, /obj)) //do far more damage to non mobs so we can get through airlocks var/obj/target_object = target target_object.take_damage(force * 3, BRUTE, "melee", 0) - else - if(isliving(target) && ishuman(target)) + else if(isliving(target)) + if(ishuman(target)) try_to_zombie_infect(target) else check_feast(target, user) diff --git a/config/config.txt b/config/config.txt index d6d0097c21..46f9a0cdc4 100644 --- a/config/config.txt +++ b/config/config.txt @@ -525,3 +525,7 @@ FAIL2TOPIC_RULE_NAME _dd_fail2topic ## Enable automatic profiling - Byond 513.1506 and newer only. #AUTO_PROFILE + +## Uncomment to enable global ban DB using the provided URL. The API should expect to receive a ckey at the end of the URL. +## More API details can be found here: https://centcom.melonmesa.com +CENTCOM_BAN_DB https://centcom.melonmesa.com/ban/search diff --git a/html/changelog.html b/html/changelog.html index 420461ee63..b72721fcdd 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -50,6 +50,140 @@ -->
    +

    02 August 2020

    +

    Auris456852 updated:

    +
      +
    • Added B.O.O.P. Remote Control cartridges to the PTech.
    • +
    +

    Hatterhat updated:

    +
      +
    • Durathread reinforcement kits! Sprites by Toriate, sets jumpsuit armor to durathread levels, craft in the crafting menu.
    • +
    +

    KeRSedChaplain updated:

    +
      +
    • The belligerent scripture and a brass multitool, and a new marauder variant which act similar to holoparasites/guardian spirits.
    • +
    • Removed the abductor teleport consoles they get, removes abscond for the time being as I've not seen much use for it other than just spamming it and hoping you end up in the armory.
    • +
    • moved around scriptures to make the cult work better as being based around the station, makes the Ark scream more often and work as a summonable object, clockwork armor now has a flat 0 defense up to 10 instead of negatives against laser damage. Makes the Ark work better in a station based setting, as well as the Heralds beacon in case It works for the mode.
    • +
    • added powerloaderstep.ogg for Neovgre
    • +
    • changes 'Dread_Ipad.dmi' to 'clockwork_slab.dmi'
    • +
    +

    MrJWhit updated:

    +
      +
    • Adjusts abductor spawntext
    • +
    +

    Seris02 updated:

    +
      +
    • fixed replica pods
    • +
    +

    dapnee updated:

    +
      +
    • fixed active turfs on wizard ruin and space hermit, fixed missing APC's and added a light on Delta
    • +
    +

    ike709 and bobbahbrown updated:

    +
      +
    • Admins can now see your bans on (some) other servers.
    • +
    +

    kappa-sama updated:

    +
      +
    • chaplain cultists being able to convert people to full clockwork cult status
    • +
    +

    timothyteakettle updated:

    +
      +
    • combat mode now has weaker buffs in terms of damage dealt and took for being or not being in the mode
    • +
    • damage debuff for laying down has been decreased from 0.5x to 0.7x
    • +
    + +

    01 August 2020

    +

    dapnee updated:

    +
      +
    • added cake hat to bar, adds another atmostech spawn
    • +
    • sinks point in the right direction, APC won't spawn off the wall in circuits
    • +
    • changes commissary APC so it actually powers the room, adds a missing AIR alarm, arrivals no longer has active atmos tiles.
    • +
    +

    silicons updated:

    +
      +
    • toy shotguns no longer need 2 hands to fire
    • +
    • being on fire works again.
    • +
    +

    timothyteakettle updated:

    +
      +
    • monkeys no longer continuously bleed everywhere
    • +
    + +

    30 July 2020

    +

    Adelphon updated:

    +
      +
    • Created a Cosmetic version of the camo.
    • +
    +

    Arturlang updated:

    +
      +
    • Bloodsucker LifeTick runs from BiologicalLife now
    • +
    +

    Ryll-Ryll ported by silicons updated:

    +
      +
    • Shoelaces are now a thing. You can untie them by laying down next to someone.
    • +
    • shoes now have lace delays and some can't be laced at all
    • +
    • do after now tracks who's interacting with who, meaning some actions now break when the target moves away.
    • +
    +

    SiliconMain updated:

    +
      +
    • Ported the long range atmos analyzer from sk*rat, credit to NotRanged
    • +
    +

    silicons updated:

    +
      +
    • energy sword perfect parries now reflect projectiles back at their shooters.
    • +
    • any mob can now parry if they have the right item
    • +
    • beam rifles now go into emitters properly
    • +
    • clickdelay has been refactored into an experimental hybrid system. Check code/modules/mob/clickdelay.dm for more information.
    • +
    • Resisting no longer checks clickdelay, but is standardized to a 2 second per resist system for most forms of resisting. It still sets clickdelay, though.
    • +
    • Meters have been added for estimating time until next attack/resist. Won't be that useful due to our clickdelay currently being very short, though. They're visible from your hand and resist HUD elements. experimental: Most attacks and forms of attacking (minus unarmed because it's too much of a pain to refactor how hugs/gloves of the north star works) now check for time-since-last-attack rather than making it so you can't attack for said time. This means you can very quickly switch to a gun from a melee weapon, whereas in the old system a melee weapon would put you on lockout for 0.8 seconds, in the new system all the gun cares about is that you did not attack for at least 0.4 seconds.
    • +
    • All clickdelay setting/reading are now procs, so it should be trivial to implement another system where drawing/switching to a weapon requires you to have it out for x seconds before using it. I am not personally doing it at this point in time though because it will likely just annoy everyone with no real gain unless we do something like putting a 0.8 second switch-to cooldown for guns (which I did not, yet)
    • +
    • attack_hand has been refactored to on_attack_hand remove: sexchems no longer impact click delay
    • +
    • turrets now automatically stagger their shots. Happy parrying/blocking.
    • +
    • turrets now speed_process, they were shooting slower than they should be
    • +
    • anything can now block with the right items
    • +
    +

    timothyteakettle updated:

    +
      +
    • some crafted crates won't contain items now, and thus have stopped breaking the laws of physics
    • +
    • beepskys hats now follow the laws of gravity and move up/down when he bobs up and down
    • +
    + +

    29 July 2020

    +

    DeltaFire15 updated:

    +
      +
    • The 'Naked' outfit is no longer broken.
    • +
    +

    Ghommie updated:

    +
      +
    • fixed cremator trays, paleness examination strings, chat message for stamping paper, looping sounds, load away missions/VR admin verb, access requirements for using the sechuds.
    • +
    • Alt-Clicking a cigarette packet should pull the lighter out first if present, then cigarettes.
    • +
    +

    Hatterhat updated:

    +
      +
    • Directional windows can now be rotated counterclockwise properly again.
    • +
    +

    NecromancerAnne, Sirich96 updated:

    +
      +
    • Stunbaton sprites by Sirich96.
    • +
    • New sprites for the stunsword.
    • +
    +

    necromanceranne updated:

    +
      +
    • Adds some in-hands for the rapier sheath.
    • +
    +

    timothyteakettle updated:

    +
      +
    • tail wagging should work in all cases now
    • +
    • bluespace jars work as intended now
    • +
    • aliens can remove embeds now
    • +
    • bloodsuckers are not affected by bloodloss
    • +
    +

    zeroisthebiggay updated:

    +
      +
    • Flannel jackets and bartender winter coat
    • +
    +

    28 July 2020

    Cacogen updated:

      diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml index 3af19f51ae..a3a5724548 100644 --- a/html/changelogs/.all_changelog.yml +++ b/html/changelogs/.all_changelog.yml @@ -26581,3 +26581,118 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py. things inside them and also the text shown for resist times is accurate zeroisthebiggay: - rscadd: Black Box theft objective +2020-07-29: + DeltaFire15: + - bugfix: The 'Naked' outfit is no longer broken. + Ghommie: + - bugfix: fixed cremator trays, paleness examination strings, chat message for stamping + paper, looping sounds, load away missions/VR admin verb, access requirements + for using the sechuds. + - tweak: Alt-Clicking a cigarette packet should pull the lighter out first if present, + then cigarettes. + Hatterhat: + - bugfix: Directional windows can now be rotated counterclockwise properly again. + NecromancerAnne, Sirich96: + - rscadd: Stunbaton sprites by Sirich96. + - rscadd: New sprites for the stunsword. + necromanceranne: + - rscadd: Adds some in-hands for the rapier sheath. + timothyteakettle: + - bugfix: tail wagging should work in all cases now + - bugfix: bluespace jars work as intended now + - bugfix: aliens can remove embeds now + - bugfix: bloodsuckers are not affected by bloodloss + zeroisthebiggay: + - rscadd: Flannel jackets and bartender winter coat +2020-07-30: + Adelphon: + - rscadd: Created a Cosmetic version of the camo. + Arturlang: + - code_imp: Bloodsucker LifeTick runs from BiologicalLife now + Ryll-Ryll ported by silicons: + - rscadd: Shoelaces are now a thing. You can untie them by laying down next to someone. + - tweak: shoes now have lace delays and some can't be laced at all + - refactor: do after now tracks who's interacting with who, meaning some actions + now break when the target moves away. + SiliconMain: + - rscadd: Ported the long range atmos analyzer from sk*rat, credit to NotRanged + silicons: + - rscadd: energy sword perfect parries now reflect projectiles back at their shooters. + - balance: any mob can now parry if they have the right item + - rscadd: beam rifles now go into emitters properly + - refactor: clickdelay has been refactored into an experimental hybrid system. Check + code/modules/mob/clickdelay.dm for more information. + - balance: Resisting no longer checks clickdelay, but is standardized to a 2 second + per resist system for most forms of resisting. It still sets clickdelay, though. + - rscadd: 'Meters have been added for estimating time until next attack/resist. + Won''t be that useful due to our clickdelay currently being very short, though. + They''re visible from your hand and resist HUD elements. experimental: Most + attacks and forms of attacking (minus unarmed because it''s too much of a pain + to refactor how hugs/gloves of the north star works) now check for time-since-last-attack + rather than making it so you can''t attack for said time. This means you can + very quickly switch to a gun from a melee weapon, whereas in the old system + a melee weapon would put you on lockout for 0.8 seconds, in the new system all + the gun cares about is that you did not attack for at least 0.4 seconds.' + - code_imp: All clickdelay setting/reading are now procs, so it should be trivial + to implement another system where drawing/switching to a weapon requires you + to have it out for x seconds before using it. I am not personally doing it at + this point in time though because it will likely just annoy everyone with no + real gain unless we do something like putting a 0.8 second switch-to cooldown + for guns (which I did not, yet) + - refactor: 'attack_hand has been refactored to on_attack_hand remove: sexchems + no longer impact click delay' + - rscadd: turrets now automatically stagger their shots. Happy parrying/blocking. + - bugfix: turrets now speed_process, they were shooting slower than they should + be + - balance: anything can now block with the right items + timothyteakettle: + - bugfix: some crafted crates won't contain items now, and thus have stopped breaking + the laws of physics + - tweak: beepskys hats now follow the laws of gravity and move up/down when he bobs + up and down +2020-08-01: + dapnee: + - tweak: added cake hat to bar, adds another atmostech spawn + - bugfix: sinks point in the right direction, APC won't spawn off the wall in circuits + - bugfix: changes commissary APC so it actually powers the room, adds a missing + AIR alarm, arrivals no longer has active atmos tiles. + silicons: + - tweak: toy shotguns no longer need 2 hands to fire + - bugfix: being on fire works again. + timothyteakettle: + - bugfix: monkeys no longer continuously bleed everywhere +2020-08-02: + Auris456852: + - rscadd: Added B.O.O.P. Remote Control cartridges to the PTech. + Hatterhat: + - rscadd: Durathread reinforcement kits! Sprites by Toriate, sets jumpsuit armor + to durathread levels, craft in the crafting menu. + KeRSedChaplain: + - rscadd: The belligerent scripture and a brass multitool, and a new marauder variant + which act similar to holoparasites/guardian spirits. + - rscdel: Removed the abductor teleport consoles they get, removes abscond for the + time being as I've not seen much use for it other than just spamming it and + hoping you end up in the armory. + - tweak: moved around scriptures to make the cult work better as being based around + the station, makes the Ark scream more often and work as a summonable object, + clockwork armor now has a flat 0 defense up to 10 instead of negatives against + laser damage. Makes the Ark work better in a station based setting, as well + as the Heralds beacon in case It works for the mode. + - soundadd: added powerloaderstep.ogg for Neovgre + - tweak: changes 'Dread_Ipad.dmi' to 'clockwork_slab.dmi' + MrJWhit: + - tweak: Adjusts abductor spawntext + Seris02: + - bugfix: fixed replica pods + dapnee: + - bugfix: fixed active turfs on wizard ruin and space hermit, fixed missing APC's + and added a light on Delta + ike709 and bobbahbrown: + - rscadd: Admins can now see your bans on (some) other servers. + kappa-sama: + - bugfix: chaplain cultists being able to convert people to full clockwork cult + status + timothyteakettle: + - tweak: combat mode now has weaker buffs in terms of damage dealt and took for + being or not being in the mode + - tweak: damage debuff for laying down has been decreased from 0.5x to 0.7x diff --git a/html/changelogs/AutoChangeLog-pr-12912.yml b/html/changelogs/AutoChangeLog-pr-12912.yml new file mode 100644 index 0000000000..9f98509351 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-12912.yml @@ -0,0 +1,4 @@ +author: "Linzolle" +delete-after: True +changes: + - bugfix: "uv penlight no longer invisible" diff --git a/html/changelogs/AutoChangeLog-pr-12936.yml b/html/changelogs/AutoChangeLog-pr-12936.yml deleted file mode 100644 index 8bb3b76912..0000000000 --- a/html/changelogs/AutoChangeLog-pr-12936.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "zeroisthebiggay" -delete-after: True -changes: - - rscadd: "Flannel jackets and bartender winter coat" diff --git a/html/changelogs/AutoChangeLog-pr-12937.yml b/html/changelogs/AutoChangeLog-pr-12937.yml deleted file mode 100644 index c1d8c67870..0000000000 --- a/html/changelogs/AutoChangeLog-pr-12937.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "Ghommie" -delete-after: True -changes: - - bugfix: "fixed cremator trays, paleness examination strings, chat message for stamping paper, looping sounds, load away missions/VR admin verb, access requirements for using the sechuds." - - tweak: "Alt-Clicking a cigarette packet should pull the lighter out first if present, then cigarettes." diff --git a/html/changelogs/AutoChangeLog-pr-12938.yml b/html/changelogs/AutoChangeLog-pr-12938.yml deleted file mode 100644 index 20d64c123a..0000000000 --- a/html/changelogs/AutoChangeLog-pr-12938.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "necromanceranne" -delete-after: True -changes: - - rscadd: "Adds some in-hands for the rapier sheath." diff --git a/html/changelogs/AutoChangeLog-pr-12940.yml b/html/changelogs/AutoChangeLog-pr-12940.yml deleted file mode 100644 index f2dcf496ba..0000000000 --- a/html/changelogs/AutoChangeLog-pr-12940.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "NecromancerAnne, Sirich96" -delete-after: True -changes: - - rscadd: "Stunbaton sprites by Sirich96." - - rscadd: "New sprites for the stunsword." diff --git a/html/changelogs/AutoChangeLog-pr-12941.yml b/html/changelogs/AutoChangeLog-pr-12941.yml deleted file mode 100644 index 51c855520c..0000000000 --- a/html/changelogs/AutoChangeLog-pr-12941.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "timothyteakettle" -delete-after: True -changes: - - bugfix: "aliens can remove embeds now" diff --git a/html/changelogs/AutoChangeLog-pr-12945.yml b/html/changelogs/AutoChangeLog-pr-12945.yml deleted file mode 100644 index 730a2b8887..0000000000 --- a/html/changelogs/AutoChangeLog-pr-12945.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "timothyteakettle" -delete-after: True -changes: - - bugfix: "bluespace jars work as intended now" diff --git a/html/changelogs/AutoChangeLog-pr-12950.yml b/html/changelogs/AutoChangeLog-pr-12950.yml deleted file mode 100644 index 8de78f9a6a..0000000000 --- a/html/changelogs/AutoChangeLog-pr-12950.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "timothyteakettle" -delete-after: True -changes: - - bugfix: "tail wagging should work in all cases now" diff --git a/html/changelogs/AutoChangeLog-pr-12983.yml b/html/changelogs/AutoChangeLog-pr-12983.yml new file mode 100644 index 0000000000..ca87590c23 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-12983.yml @@ -0,0 +1,4 @@ +author: "silicons" +delete-after: True +changes: + - tweak: "war operatives now actually time 20 minutes since roundstart to depart instead of 15." diff --git a/html/changelogs/AutoChangeLog-pr-12999.yml b/html/changelogs/AutoChangeLog-pr-12999.yml new file mode 100644 index 0000000000..c2358348fd --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-12999.yml @@ -0,0 +1,4 @@ +author: "KeRSedChaplain" +delete-after: True +changes: + - bugfix: "fixed clockwork guardians being able to reflect ranged weapons" diff --git a/icons/mob/clockwork_mobs.dmi b/icons/mob/clockwork_mobs.dmi index 5985adf12d..54690f6cac 100644 Binary files a/icons/mob/clockwork_mobs.dmi and b/icons/mob/clockwork_mobs.dmi differ diff --git a/icons/mob/screen_alert.dmi b/icons/mob/screen_alert.dmi index 60fe2f9839..30c23601a5 100644 Binary files a/icons/mob/screen_alert.dmi and b/icons/mob/screen_alert.dmi differ diff --git a/icons/mob/secbot_accessories.dmi b/icons/mob/secbot_accessories.dmi index b6c7bad6fa..944aac44f3 100644 Binary files a/icons/mob/secbot_accessories.dmi and b/icons/mob/secbot_accessories.dmi differ diff --git a/icons/obj/clockwork_objects.dmi b/icons/obj/clockwork_objects.dmi index 1948bb605c..ae919d85a4 100644 Binary files a/icons/obj/clockwork_objects.dmi and b/icons/obj/clockwork_objects.dmi differ diff --git a/icons/obj/clothing/reinf_kits.dmi b/icons/obj/clothing/reinf_kits.dmi new file mode 100644 index 0000000000..3b23d53342 Binary files /dev/null and b/icons/obj/clothing/reinf_kits.dmi differ diff --git a/icons/obj/device.dmi b/icons/obj/device.dmi index c27e03bb2a..5a9e1e54b6 100644 Binary files a/icons/obj/device.dmi and b/icons/obj/device.dmi differ diff --git a/icons/obj/hydroponics/growing.dmi b/icons/obj/hydroponics/growing.dmi index c93865ca77..5415f47528 100644 Binary files a/icons/obj/hydroponics/growing.dmi and b/icons/obj/hydroponics/growing.dmi differ diff --git a/icons/obj/lighting.dmi b/icons/obj/lighting.dmi index c3ca67eeae..0e262895fd 100644 Binary files a/icons/obj/lighting.dmi and b/icons/obj/lighting.dmi differ diff --git a/icons/obj/tools.dmi b/icons/obj/tools.dmi index f1a8cf3c02..0a457777c2 100644 Binary files a/icons/obj/tools.dmi and b/icons/obj/tools.dmi differ diff --git a/modular_citadel/code/datums/status_effects/chems.dm b/modular_citadel/code/datums/status_effects/chems.dm index 5356214438..4fa2a51fac 100644 --- a/modular_citadel/code/datums/status_effects/chems.dm +++ b/modular_citadel/code/datums/status_effects/chems.dm @@ -53,7 +53,6 @@ if(last_checked_size != B.cached_size) H.add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/status_effect/breast_hypertrophy, multiplicative_slowdown = moveCalc) - sizeMoveMod(moveCalc) if (B.size == "huge") if(prob(1)) @@ -70,16 +69,8 @@ log_reagent("FERMICHEM: [owner]'s breasts has reduced to an acceptable size. ID: [owner.key]") to_chat(owner, "Your expansive chest has become a more managable size, liberating your movements.") owner.remove_movespeed_modifier(/datum/movespeed_modifier/status_effect/breast_hypertrophy) - sizeMoveMod(1) return ..() -/datum/status_effect/chem/breast_enlarger/proc/sizeMoveMod(var/value) - if(cachedmoveCalc == value) - return - owner.next_move_modifier /= cachedmoveCalc - owner.next_move_modifier *= value - cachedmoveCalc = value - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /datum/status_effect/chem/penis_enlarger diff --git a/modular_citadel/code/game/objects/cit_screenshake.dm b/modular_citadel/code/game/objects/cit_screenshake.dm index 188b8a48f9..222de37f82 100644 --- a/modular_citadel/code/game/objects/cit_screenshake.dm +++ b/modular_citadel/code/game/objects/cit_screenshake.dm @@ -45,18 +45,6 @@ . = ..() shake_camera(user, (pressureSetting * 0.75 + 1), (pressureSetting * 0.75)) -/obj/item/attack(mob/living/M, mob/living/user) - . = ..() - if(force >= 15) - shake_camera(user, ((force - 10) * 0.01 + 1), ((force - 10) * 0.01)) - if(M.client) - switch (M.client.prefs.damagescreenshake) - if (1) - shake_camera(M, ((force - 10) * 0.015 + 1), ((force - 10) * 0.015)) - if (2) - if(!CHECK_MOBILITY(M, MOBILITY_MOVE)) - shake_camera(M, ((force - 10) * 0.015 + 1), ((force - 10) * 0.015)) - /obj/item/attack_obj(obj/O, mob/living/user) . = ..() if(force >= 20) diff --git a/modular_citadel/code/modules/reagents/chemistry/reagents/SDGF.dm b/modular_citadel/code/modules/reagents/chemistry/reagents/SDGF.dm index 8ef302e904..f3059a480a 100644 --- a/modular_citadel/code/modules/reagents/chemistry/reagents/SDGF.dm +++ b/modular_citadel/code/modules/reagents/chemistry/reagents/SDGF.dm @@ -112,7 +112,7 @@ IMPORTANT FACTORS TO CONSIDER WHILE BALANCING M.visible_message("[M] suddenly shudders, and splits into two identical twins!") SM.copy_languages(M, LANGUAGE_MIND) playerClone = TRUE - M.next_move_modifier = 1 + M.action_cooldown_mod = 1 M.adjust_nutrition(-500) //Damage the clone @@ -154,7 +154,7 @@ IMPORTANT FACTORS TO CONSIDER WHILE BALANCING M.adjust_nutrition(M.nutrition/5) if(50) to_chat(M, "The synthetic cells begin to merge with your body, it feels like your body is made of a viscous water, making your movements difficult.") - M.next_move_modifier += 4//If this makes you fast then please fix it, it should make you slow!! + M.action_cooldown_mod += 4//If this makes you fast then please fix it, it should make you slow!! //candidates = pollGhostCandidates("Do you want to play as a clone of [M.name] and do you agree to respect their character and act in a similar manner to them? I swear to god if you diddle them I will be very disapointed in you. ", "FermiClone", null, ROLE_SENTIENCE, 300) // see poll_ignore.dm, should allow admins to ban greifers or bullies if(51 to 79) M.adjust_nutrition(M.nutrition/2) @@ -164,7 +164,7 @@ IMPORTANT FACTORS TO CONSIDER WHILE BALANCING M.set_nutrition(20000) //https://www.youtube.com/watch?v=Bj_YLenOlZI if(86)//Upon splitting, you get really hungry and are capable again. Deletes the chem after you're done. M.set_nutrition(15)//YOU BEST BE EATTING AFTER THIS YOU CUTIE - M.next_move_modifier -= 4 + M.action_cooldown_mod -= 4 to_chat(M, "Your body splits away from the cell clone of yourself, leaving you with a drained and hollow feeling inside.") //clone @@ -195,14 +195,14 @@ IMPORTANT FACTORS TO CONSIDER WHILE BALANCING if (playerClone == TRUE)//If the player made a clone with it, then thats all they get. playerClone = FALSE return - if (M.next_move_modifier == 4 && !M.has_status_effect(/datum/status_effect/chem/SGDF))//checks if they're ingested over 20u of the stuff, but fell short of the required 30u to make a clone. + if (M.action_cooldown_mod == 4 && !M.has_status_effect(/datum/status_effect/chem/SGDF))//checks if they're ingested over 20u of the stuff, but fell short of the required 30u to make a clone. to_chat(M, "You feel the cells begin to merge with your body, unable to reach nucleation, they instead merge with your body, healing any wounds.") M.adjustCloneLoss(-10, 0) //I don't want to make Rezadone obsolete. M.adjustBruteLoss(-25, 0)// Note that this takes a long time to apply and makes you fat and useless when it's in you, I don't think this small burst of healing will be useful considering how long it takes to get there. M.adjustFireLoss(-25, 0) M.blood_volume += 250 M.heal_bodypart_damage(1,1) - M.next_move_modifier = 1 + M.action_cooldown_mod = 1 if (M.nutrition < 1500) M.adjust_nutrition(250) else if (unitCheck == TRUE && !M.has_status_effect(/datum/status_effect/chem/SGDF))// If they're ingested a little bit (10u minimum), then give them a little healing. @@ -211,7 +211,7 @@ IMPORTANT FACTORS TO CONSIDER WHILE BALANCING M.adjustBruteLoss(-10, 0) M.adjustFireLoss(-10, 0) M.blood_volume += 100 - M.next_move_modifier = 1 + M.action_cooldown_mod = 1 if (M.nutrition < 1500) M.adjust_nutrition(500) @@ -325,7 +325,7 @@ IMPORTANT FACTORS TO CONSIDER WHILE BALANCING M.adjust_nutrition(M.nutrition/5) if(50) to_chat(M, "The synethic cells begin to merge with your body, it feels like your body is made of a viscous water, making your movements difficult.") - M.next_move_modifier = 4//If this makes you fast then please fix it, it should make you slow!! + M.action_cooldown_mod = 4//If this makes you fast then please fix it, it should make you slow!! if(51 to 73) M.adjust_nutrition(M.nutrition/2) if(74) @@ -339,7 +339,7 @@ IMPORTANT FACTORS TO CONSIDER WHILE BALANCING if (!M.reagents.has_reagent(/datum/reagent/medicine/pen_acid))//Counterplay is pent.) message_admins("(non-infectious) SDZF: Zombie spawned at [M] [COORD(M)]!") M.set_nutrition(startHunger - 500) //YOU BEST BE RUNNING AWAY AFTER THIS YOU BADDIE - M.next_move_modifier = 1 + M.action_cooldown_mod = 1 to_chat(M, "Your body splits away from the cell clone of yourself, your attempted clone birthing itself violently from you as it begins to shamble around, a terrifying abomination of science.") M.visible_message("[M] suddenly shudders, and splits into a funky smelling copy of themselves!") M.emote("scream") diff --git a/modular_citadel/code/modules/reagents/objects/clothes.dm b/modular_citadel/code/modules/reagents/objects/clothes.dm index d3c566ce70..ab4d49c56f 100644 --- a/modular_citadel/code/modules/reagents/objects/clothes.dm +++ b/modular_citadel/code/modules/reagents/objects/clothes.dm @@ -9,7 +9,7 @@ armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) //item_flags = NODROP //Tips their hat! -/obj/item/clothing/head/hattip/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/item/clothing/head/hattip/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(iscarbon(user)) var/mob/living/carbon/C = user if(is_ninja(C)) diff --git a/modular_citadel/code/modules/reagents/objects/items.dm b/modular_citadel/code/modules/reagents/objects/items.dm index 27b8961835..f4316b3c58 100644 --- a/modular_citadel/code/modules/reagents/objects/items.dm +++ b/modular_citadel/code/modules/reagents/objects/items.dm @@ -9,7 +9,7 @@ w_class = WEIGHT_CLASS_TINY //A little janky with pockets -/obj/item/fermichem/pHbooklet/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/item/fermichem/pHbooklet/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(user.get_held_index_of_item(src))//Does this check pockets too..? if(numberOfPages == 50) icon_state = "pHbookletOpen" diff --git a/sound/machines/clockcult/ratvar_scream.ogg b/sound/machines/clockcult/ratvar_scream.ogg new file mode 100644 index 0000000000..5c0c0a0d63 Binary files /dev/null and b/sound/machines/clockcult/ratvar_scream.ogg differ diff --git a/sound/magic/abomscream.ogg b/sound/magic/abomscream.ogg new file mode 100644 index 0000000000..4f450e05f7 Binary files /dev/null and b/sound/magic/abomscream.ogg differ diff --git a/sound/mecha/neostep1.ogg b/sound/mecha/neostep1.ogg new file mode 100644 index 0000000000..ce7f51ad23 Binary files /dev/null and b/sound/mecha/neostep1.ogg differ diff --git a/sound/mecha/neostep2.ogg b/sound/mecha/neostep2.ogg new file mode 100644 index 0000000000..e828d9eadd Binary files /dev/null and b/sound/mecha/neostep2.ogg differ diff --git a/sound/mecha/powerloader_step.ogg b/sound/mecha/powerloader_step.ogg new file mode 100644 index 0000000000..af427df865 Binary files /dev/null and b/sound/mecha/powerloader_step.ogg differ diff --git a/tgstation.dme b/tgstation.dme index 75914f9d66..b33277b4c0 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -124,6 +124,7 @@ #include "code\__DEFINES\_flags\do_after.dm" #include "code\__DEFINES\_flags\item_flags.dm" #include "code\__DEFINES\_flags\obj_flags.dm" +#include "code\__DEFINES\_flags\return_values.dm" #include "code\__DEFINES\_flags\shields.dm" #include "code\__DEFINES\admin\keybindings.dm" #include "code\__DEFINES\chemistry\reactions.dm" @@ -135,7 +136,6 @@ #include "code\__DEFINES\dcs\signals.dm" #include "code\__DEFINES\mapping\maploader.dm" #include "code\__DEFINES\material\worth.dm" -#include "code\__DEFINES\misc\return_values.dm" #include "code\__DEFINES\mobs\slowdowns.dm" #include "code\__DEFINES\research\stock_parts.dm" #include "code\__DEFINES\skills\defines.dm" @@ -220,6 +220,9 @@ #include "code\_onclick\observer.dm" #include "code\_onclick\other_mobs.dm" #include "code\_onclick\overmind.dm" +#include "code\_onclick\right_click.dm" +#include "code\_onclick\right_item_attack.dm" +#include "code\_onclick\right_other_mobs.dm" #include "code\_onclick\telekinesis.dm" #include "code\_onclick\hud\_defines.dm" #include "code\_onclick\hud\action_button.dm" @@ -229,6 +232,7 @@ #include "code\_onclick\hud\alien_larva.dm" #include "code\_onclick\hud\blob_overmind.dm" #include "code\_onclick\hud\blobbernauthud.dm" +#include "code\_onclick\hud\clockwork_marauder.dm" #include "code\_onclick\hud\constructs.dm" #include "code\_onclick\hud\credits.dm" #include "code\_onclick\hud\devil.dm" @@ -252,7 +256,11 @@ #include "code\_onclick\hud\robot.dm" #include "code\_onclick\hud\screen_objects.dm" #include "code\_onclick\hud\swarmer.dm" +#include "code\_onclick\hud\screen_objects\clickdelay.dm" +#include "code\_onclick\hud\screen_objects\sprint.dm" +#include "code\_onclick\hud\screen_objects\stamina.dm" #include "code\_onclick\hud\screen_objects\storage.dm" +#include "code\_onclick\hud\screen_objects\vore.dm" #include "code\controllers\admin.dm" #include "code\controllers\configuration_citadel.dm" #include "code\controllers\controller.dm" @@ -339,6 +347,7 @@ #include "code\controllers\subsystem\processing\circuit.dm" #include "code\controllers\subsystem\processing\fastprocess.dm" #include "code\controllers\subsystem\processing\fields.dm" +#include "code\controllers\subsystem\processing\huds.dm" #include "code\controllers\subsystem\processing\instruments.dm" #include "code\controllers\subsystem\processing\nanites.dm" #include "code\controllers\subsystem\processing\networks.dm" @@ -369,6 +378,7 @@ #include "code\datums\explosion.dm" #include "code\datums\forced_movement.dm" #include "code\datums\holocall.dm" +#include "code\datums\http.dm" #include "code\datums\hud.dm" #include "code\datums\mind.dm" #include "code\datums\mutable_appearance.dm" @@ -962,6 +972,7 @@ #include "code\game\objects\items\AI_modules.dm" #include "code\game\objects\items\airlock_painter.dm" #include "code\game\objects\items\apc_frame.dm" +#include "code\game\objects\items\armor_kits.dm" #include "code\game\objects\items\balls.dm" #include "code\game\objects\items\binoculars.dm" #include "code\game\objects\items\blueprints.dm" @@ -1533,6 +1544,7 @@ #include "code\modules\antagonists\clockcult\clock_scriptures\scripture_applications.dm" #include "code\modules\antagonists\clockcult\clock_scriptures\scripture_cyborg.dm" #include "code\modules\antagonists\clockcult\clock_scriptures\scripture_drivers.dm" +#include "code\modules\antagonists\clockcult\clock_scriptures\scripture_judgement.dm" #include "code\modules\antagonists\clockcult\clock_scriptures\scripture_scripts.dm" #include "code\modules\antagonists\clockcult\clock_structures\_trap_object.dm" #include "code\modules\antagonists\clockcult\clock_structures\ark_of_the_clockwork_justicar.dm" @@ -1541,6 +1553,7 @@ #include "code\modules\antagonists\clockcult\clock_structures\heralds_beacon.dm" #include "code\modules\antagonists\clockcult\clock_structures\mania_motor.dm" #include "code\modules\antagonists\clockcult\clock_structures\ocular_warden.dm" +#include "code\modules\antagonists\clockcult\clock_structures\prolonging_prism.dm" #include "code\modules\antagonists\clockcult\clock_structures\ratvar_the_clockwork_justicar.dm" #include "code\modules\antagonists\clockcult\clock_structures\reflector.dm" #include "code\modules\antagonists\clockcult\clock_structures\stargazer.dm" @@ -2318,6 +2331,7 @@ #include "code\modules\mining\lavaland\ash_flora.dm" #include "code\modules\mining\lavaland\necropolis_chests.dm" #include "code\modules\mining\lavaland\ruins\gym.dm" +#include "code\modules\mob\clickdelay.dm" #include "code\modules\mob\death.dm" #include "code\modules\mob\emote.dm" #include "code\modules\mob\inventory.dm" @@ -2370,6 +2384,7 @@ #include "code\modules\mob\dead\observer\say.dm" #include "code\modules\mob\living\blood.dm" #include "code\modules\mob\living\bloodcrawl.dm" +#include "code\modules\mob\living\clickdelay.dm" #include "code\modules\mob\living\damage_procs.dm" #include "code\modules\mob\living\death.dm" #include "code\modules\mob\living\emote.dm" @@ -3436,12 +3451,6 @@ #include "interface\menu.dm" #include "interface\stylesheet.dm" #include "interface\skin.dmf" -#include "modular_citadel\code\_onclick\click.dm" -#include "modular_citadel\code\_onclick\item_attack.dm" -#include "modular_citadel\code\_onclick\other_mobs.dm" -#include "modular_citadel\code\_onclick\hud\screen_objects.dm" -#include "modular_citadel\code\_onclick\hud\sprint.dm" -#include "modular_citadel\code\_onclick\hud\stamina.dm" #include "modular_citadel\code\datums\components\souldeath.dm" #include "modular_citadel\code\datums\status_effects\chems.dm" #include "modular_citadel\code\game\objects\cit_screenshake.dm"