diff --git a/_maps/RandomZLevels/moonoutpost19.dmm b/_maps/RandomZLevels/moonoutpost19.dmm index 3fa664d176a..a1c4d3b4548 100644 --- a/_maps/RandomZLevels/moonoutpost19.dmm +++ b/_maps/RandomZLevels/moonoutpost19.dmm @@ -35,14 +35,14 @@ "aI" = (/obj/structure/alien/weeds{icon_state = "weeds1"},/obj/structure/alien/weeds{desc = "A large mottled egg."; health = 100; icon_state = "egg_hatched"; name = "egg"},/obj/effect/decal/cleanable/blood/gibs,/turf/simulated/floor/plating/asteroid{carbon_dioxide = 48.7; heat_capacity = 1e+006; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/awaycontent/a5{always_unpowered = 1; has_gravity = 1; name = "The Hive"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0}) "aJ" = (/obj/structure/alien/weeds,/obj/structure/alien/weeds{desc = "A large mottled egg."; health = 100; icon_state = "egg_hatched"; name = "egg"},/obj/effect/decal/cleanable/blood,/turf/simulated/floor/plating/asteroid{carbon_dioxide = 48.7; heat_capacity = 1e+006; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/awaycontent/a5{always_unpowered = 1; has_gravity = 1; name = "The Hive"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0}) "aK" = (/obj/structure/alien/weeds{icon_state = "weeds2"},/obj/effect/decal/cleanable/blood/gibs,/turf/simulated/floor/plating/asteroid{carbon_dioxide = 48.7; heat_capacity = 1e+006; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/awaycontent/a5{always_unpowered = 1; has_gravity = 1; name = "The Hive"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0}) -"aL" = (/obj/structure/alien/weeds,/mob/living/simple_animal/hostile/alien/drone,/turf/simulated/floor/plating/asteroid{carbon_dioxide = 48.7; heat_capacity = 1e+006; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/awaycontent/a5{always_unpowered = 1; has_gravity = 1; name = "The Hive"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0}) +"aL" = (/obj/structure/alien/weeds,/mob/living/simple_animal/hostile/alien/drone{plants_off = 1},/turf/simulated/floor/plating/asteroid{carbon_dioxide = 48.7; heat_capacity = 1e+006; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/awaycontent/a5{always_unpowered = 1; has_gravity = 1; name = "The Hive"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0}) "aM" = (/obj/machinery/light{dir = 8},/turf/simulated/floor/plasteel{heat_capacity = 1e+006; icon_state = "dark"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"}) "aN" = (/obj/machinery/gateway{dir = 8},/turf/simulated/floor/plasteel{dir = 8; heat_capacity = 1e+006; icon_state = "vault"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"}) "aO" = (/obj/machinery/gateway/centeraway{calibrated = 0},/turf/simulated/floor/plasteel{heat_capacity = 1e+006; icon_state = "dark"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"}) "aP" = (/obj/machinery/gateway{dir = 4},/turf/simulated/floor/plasteel{dir = 8; heat_capacity = 1e+006; icon_state = "vault"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"}) "aQ" = (/obj/machinery/light{icon_state = "tube1"; dir = 4},/turf/simulated/floor/plasteel{heat_capacity = 1e+006; icon_state = "dark"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"}) "aR" = (/obj/item/weapon/ore/iron{pixel_x = 7; pixel_y = -6},/turf/simulated/floor/plating/asteroid{carbon_dioxide = 48.7; heat_capacity = 1e+006; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/awaycontent/a3{always_unpowered = 1; ambientsounds = list('sound/ambience/ambimine.ogg'); has_gravity = 1; name = "Khonsu 19"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0}) -"aS" = (/obj/structure/alien/weeds,/mob/living/simple_animal/hostile/alien/queen/large{desc = "A gigantic alien who is in charge of the hive and all of its loyal servants."; name = "alien queen"; pixel_x = -16},/turf/simulated/floor/plating/asteroid{carbon_dioxide = 48.7; heat_capacity = 1e+006; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/awaycontent/a5{always_unpowered = 1; has_gravity = 1; name = "The Hive"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0}) +"aS" = (/obj/structure/alien/weeds,/mob/living/simple_animal/hostile/alien/queen/large{desc = "A gigantic alien who is in charge of the hive and all of its loyal servants."; name = "alien queen"; pixel_x = -16; plants_off = 1},/turf/simulated/floor/plating/asteroid{carbon_dioxide = 48.7; heat_capacity = 1e+006; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/awaycontent/a5{always_unpowered = 1; has_gravity = 1; name = "The Hive"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0}) "aT" = (/turf/simulated/wall,/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"}) "aU" = (/turf/simulated/floor/plasteel{dir = 8; heat_capacity = 1e+006; icon_state = "darkredcorners"; tag = "icon-darkredcorners (WEST)"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"}) "aV" = (/obj/machinery/gateway{dir = 10},/turf/simulated/floor/plasteel{dir = 4; heat_capacity = 1e+006; icon_state = "vault"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"}) @@ -50,7 +50,7 @@ "aX" = (/obj/machinery/gateway{dir = 6},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel{dir = 1; heat_capacity = 1e+006; icon_state = "vault"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"}) "aY" = (/turf/simulated/floor/plasteel{dir = 2; heat_capacity = 1e+006; icon_state = "darkredcorners"; tag = "icon-darkredcorners"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"}) "aZ" = (/turf/simulated/floor/plating/asteroid{carbon_dioxide = 48.7; heat_capacity = 1e+006; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/awaycontent/a3{always_unpowered = 1; ambientsounds = list('sound/ambience/ambimine.ogg'); has_gravity = 1; name = "Khonsu 19"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0}) -"ba" = (/obj/structure/alien/weeds{icon_state = "weeds1"},/mob/living/simple_animal/hostile/alien/drone,/turf/simulated/floor/plating/asteroid{carbon_dioxide = 48.7; heat_capacity = 1e+006; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/awaycontent/a5{always_unpowered = 1; has_gravity = 1; name = "The Hive"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0}) +"ba" = (/obj/structure/alien/weeds{icon_state = "weeds1"},/mob/living/simple_animal/hostile/alien/drone{plants_off = 1},/turf/simulated/floor/plating/asteroid{carbon_dioxide = 48.7; heat_capacity = 1e+006; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/awaycontent/a5{always_unpowered = 1; has_gravity = 1; name = "The Hive"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0}) "bb" = (/obj/structure/alien/weeds,/obj/effect/decal/cleanable/blood,/turf/simulated/floor/plating/asteroid{carbon_dioxide = 48.7; heat_capacity = 1e+006; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/awaycontent/a5{always_unpowered = 1; has_gravity = 1; name = "The Hive"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0}) "bc" = (/obj/machinery/vending/cola,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"}) "bd" = (/obj/machinery/vending/cigarette,/obj/structure/sign/poster{icon_state = "poster7"; pixel_y = 32; serial_number = 7; subtype = 0},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"}) @@ -156,7 +156,7 @@ "cZ" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/wood{carbon_dioxide = 48.7; heat_capacity = 1e+006; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"}) "da" = (/turf/simulated/floor/wood{heat_capacity = 1e+006},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"}) "db" = (/obj/machinery/door_control{id = "awaydorm5"; name = "Door Bolt Control"; normaldoorcontrol = 1; pixel_x = 0; pixel_y = 25; req_access_txt = "0"; specialfunctions = 4},/obj/structure/dresser,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/wood{heat_capacity = 1e+006},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"}) -"dc" = (/obj/structure/alien/weeds/node,/mob/living/simple_animal/hostile/alien/drone,/turf/simulated/floor/plating/asteroid{carbon_dioxide = 48.7; heat_capacity = 1e+006; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/awaycontent/a5{always_unpowered = 1; has_gravity = 1; name = "The Hive"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0}) +"dc" = (/obj/structure/alien/weeds/node,/mob/living/simple_animal/hostile/alien/drone{plants_off = 1},/turf/simulated/floor/plating/asteroid{carbon_dioxide = 48.7; heat_capacity = 1e+006; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/awaycontent/a5{always_unpowered = 1; has_gravity = 1; name = "The Hive"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0}) "dd" = (/obj/machinery/mineral/stacking_machine{dir = 1; input_dir = 1; output_dir = 2},/turf/simulated/floor/plating{carbon_dioxide = 48.7; dir = 4; heat_capacity = 1e+006; icon_state = "warnplate"; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"}) "de" = (/obj/machinery/mineral/stacking_unit_console{machinedir = 8},/turf/simulated/wall,/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"}) "df" = (/obj/structure/closet/crate,/obj/item/stack/sheet/glass{amount = 10},/obj/structure/alien/weeds,/turf/simulated/floor/plasteel{carbon_dioxide = 48.7; dir = 1; heat_capacity = 1e+006; icon_state = "bot"; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"}) @@ -197,7 +197,7 @@ "dO" = (/obj/structure/alien/weeds,/obj/structure/alien/resin/wall,/turf/simulated/floor/plating/asteroid{carbon_dioxide = 48.7; heat_capacity = 1e+006; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/awaycontent/a3{always_unpowered = 1; ambientsounds = list('sound/ambience/ambimine.ogg'); has_gravity = 1; name = "Khonsu 19"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0}) "dP" = (/obj/structure/alien/weeds/node,/turf/simulated/floor/plating/asteroid{carbon_dioxide = 48.7; heat_capacity = 1e+006; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/awaycontent/a3{always_unpowered = 1; ambientsounds = list('sound/ambience/ambimine.ogg'); has_gravity = 1; name = "Khonsu 19"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0}) "dQ" = (/obj/structure/alien/weeds{icon_state = "weeds2"},/obj/structure/alien/resin/wall,/turf/simulated/floor/plating/asteroid{carbon_dioxide = 48.7; heat_capacity = 1e+006; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/awaycontent/a3{always_unpowered = 1; ambientsounds = list('sound/ambience/ambimine.ogg'); has_gravity = 1; name = "Khonsu 19"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0}) -"dR" = (/obj/structure/alien/weeds{icon_state = "weeds1"},/obj/effect/decal/cleanable/blood,/mob/living/simple_animal/hostile/alien/drone,/turf/simulated/floor/plating/asteroid{carbon_dioxide = 48.7; heat_capacity = 1e+006; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/awaycontent/a5{always_unpowered = 1; has_gravity = 1; name = "The Hive"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0}) +"dR" = (/obj/structure/alien/weeds{icon_state = "weeds1"},/obj/effect/decal/cleanable/blood,/mob/living/simple_animal/hostile/alien/drone{plants_off = 1},/turf/simulated/floor/plating/asteroid{carbon_dioxide = 48.7; heat_capacity = 1e+006; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/awaycontent/a5{always_unpowered = 1; has_gravity = 1; name = "The Hive"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0}) "dS" = (/obj/structure/alien/weeds,/turf/simulated/floor/plating/asteroid{carbon_dioxide = 48.7; heat_capacity = 1e+006; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/awaycontent/a3{always_unpowered = 1; ambientsounds = list('sound/ambience/ambimine.ogg'); has_gravity = 1; name = "Khonsu 19"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0}) "dT" = (/obj/structure/alien/weeds{icon_state = "weeds2"},/turf/simulated/floor/plating/asteroid{carbon_dioxide = 48.7; heat_capacity = 1e+006; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/awaycontent/a3{always_unpowered = 1; ambientsounds = list('sound/ambience/ambimine.ogg'); has_gravity = 1; name = "Khonsu 19"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0}) "dU" = (/obj/structure/alien/weeds/node,/obj/structure/alien/resin/wall,/turf/simulated/floor/plating/asteroid{carbon_dioxide = 48.7; heat_capacity = 1e+006; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/awaycontent/a3{always_unpowered = 1; ambientsounds = list('sound/ambience/ambimine.ogg'); has_gravity = 1; name = "Khonsu 19"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0}) diff --git a/_maps/map_files/MetaStation/MetaStation.v40D.dmm b/_maps/map_files/MetaStation/MetaStation.v40D.dmm index 4a87c6eefcd..16cb900b63b 100644 --- a/_maps/map_files/MetaStation/MetaStation.v40D.dmm +++ b/_maps/map_files/MetaStation/MetaStation.v40D.dmm @@ -1230,12 +1230,12 @@ "axH" = (/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{dir = 8; initialize_directions = 11},/obj/machinery/disposal,/obj/structure/disposalpipe/trunk{dir = 1},/turf/simulated/floor/plasteel{dir = 8; icon_state = "redcorner"},/area/security/brig) "axI" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/turf/simulated/floor/plasteel,/area/security/brig) "axJ" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/obj/machinery/atmospherics/pipe/simple/supply/hidden{req_access_txt = "0"},/turf/simulated/floor/plasteel{dir = 2; icon_state = "redcorner"},/area/security/brig) -"axK" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/obj/machinery/light,/obj/machinery/door_timer/cell_1,/obj/machinery/camera{c_tag = "Brig - Hallway - Port"; dir = 1; network = list("SS13")},/turf/simulated/floor/plasteel{icon_state = "red"},/area/security/brig) +"axK" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/obj/machinery/light,/obj/machinery/camera{c_tag = "Brig - Hallway - Port"; dir = 1; network = list("SS13")},/obj/machinery/door_timer{id = "Cell 1"; name = "Cell 1"; pixel_y = -32},/turf/simulated/floor/plasteel{icon_state = "red"},/area/security/brig) "axL" = (/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{dir = 1; initialize_directions = 11},/turf/simulated/floor/plasteel{dir = 8; icon_state = "redcorner"},/area/security/brig) "axM" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{dir = 2; initialize_directions = 11},/turf/simulated/floor/plasteel,/area/security/brig) -"axN" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/obj/machinery/door_timer/cell_2,/turf/simulated/floor/plasteel{icon_state = "red"},/area/security/brig) +"axN" = (/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{dir = 2; initialize_directions = 11},/obj/machinery/door_timer{id = "Cell 3"; name = "Cell 3"; pixel_y = -32},/turf/simulated/floor/plasteel{dir = 2; icon_state = "redcorner"},/area/security/brig) "axO" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/obj/machinery/atmospherics/pipe/simple/supply/hidden{req_access_txt = "0"},/turf/simulated/floor/plasteel{icon_state = "red"},/area/security/brig) -"axP" = (/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{dir = 2; initialize_directions = 11},/obj/machinery/door_timer/cell_3,/turf/simulated/floor/plasteel{dir = 2; icon_state = "redcorner"},/area/security/brig) +"axP" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/obj/machinery/door_timer{id = "Cell 2"; name = "Cell 2"; pixel_y = -32},/turf/simulated/floor/plasteel{icon_state = "red"},/area/security/brig) "axQ" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/obj/machinery/atmospherics/pipe/simple/supply/hidden{req_access_txt = 1},/turf/simulated/floor/plasteel{icon_state = "red"; dir = 9},/area/security/brig) "axR" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/turf/simulated/floor/plasteel{icon_state = "red"; dir = 1},/area/security/brig) "axS" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{dir = 1; initialize_directions = 11},/turf/simulated/floor/plasteel{icon_state = "red"; dir = 5},/area/security/brig) @@ -7953,7 +7953,7 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaatJatJatJatJatJaahatJatJaahcrMatJatJaahaahaahaahalWalWatKalWalWatLatMatMatMatMatMatNalWalWalWalWatOavbatPatPatPatPatQatRaheatSavcatUatVatWatXatYatZauaaubaucaudaheangaavaavaavanmahAaukaulansaumavdavgajSauoadRadRanBanyanoakjadRautanBahJahJajQanCauwauxanCajQaodanZajQaoiaqtaqtauBauBauBajQajQauCaheaiYauDauEarWauFauGauHauIauJauKauLauMauNauOauParWauQaocaxqauSauTauUaocauVaocaocaocauWaocaocauXauYauZajoajoajoajoauVapwapxavaazvatHaBwaBjaveatHaobatHaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaQxaahatJatJatJatJatJatJatJatJatJatJatJavfatJaahcrMalWalWalWaBFavhalWaahaahaahaahaahaahaahaahaahaahaahalWankaviaotalOavjalOavkavlavmavnavoavpaheaheaheaokaojaojaojaolaheaheaoAaoOaoMaoPaoAahAahAagKavzavAameavBavBavCavDavBavEavBavDavBavFavBavEavGavHavIavDavJavKavBavBavBavDavBavLahCavMavNavNavNavNagKaquaheauEaiYaiYarWarWarWarWarWavOavPavQavRavSarWarWarWavTaocapwavUatyapxaocapxaocavVaocavWavXavYavZawaawbawcawdaweawfawgawhaweawiapxapxavUapxawjatIawkatIabjabjaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacrMaahatJaraatJatJatJatJawlaahatJatJatJatJatJatJawmawnawmawoawpalWalWaahaaaaaaaaaaaaaaaaaaaaaaaaaahalWalWalWapRalOawqalOawrawsawtawuawvawwaheaaaaahaaaaaaaaaaaaaaaaahaaaaoUapyapvapCapzawCavNapDawEawFawGawHawHawIawGawHawJawKawGawLawMawHawNawOawPawHawQawRawSawTawTawUawVawWawXawYawZaxaaxbaxcaxdagKaquaheaxeahfaxfarWaxgaxhaxiatratsattaxjarWaxkatpaxlarWaxmaocaocaocauWaocaocapxaocaqKaocaxnatHatHatAaxoajoatHatHatHatHatHatHatHatHatHaoaatHatHatHatHatHaxpatHaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaatJatJatJatJatJatJatJatJatJatJatJaahatJatJatJaahalWalWalWaBHawwaotalWaaaangadoaavadoanmaahaahaahaahalWapFalWaxwasvasvasvaxxaxyalWaxzaxAaxBaheaaaaxCaxCaxCaxCaxCaxCaxCaaaaoAapLapGaqbaoAahAahAagKaxHaxIaxJaxKaxLaxMaxJaxNaxLaxIaxOaxPaxQaxRaxSaxTaxUaxVaxWaxXaxYaxZayaaxYaybaycaydayeayfaygayhayiayjagKaquaykaykaykaykaykauPaylaymaynayoaypauLayqayraysauFarWaqhaytayuayvaywayvayxayvayyayvayvayzayAayBayCayDayEayFayGayFayHayIayJayIayKatHatHatHayHayIayKayLayLayFaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaatJatJatJatJatJatJatJatJatJatJatJaahatJatJatJaahalWalWalWaBHawwaotalWaaaangadoaavadoanmaahaahaahaahalWapFalWaxwasvasvasvaxxaxyalWaxzaxAaxBaheaaaaxCaxCaxCaxCaxCaxCaxCaaaaoAapLapGaqbaoAahAahAagKaxHaxIaxJaxKaxLaxMaxJaxPaxLaxIaxOaxNaxQaxRaxSaxTaxUaxVaxWaxXaxYaxZayaaxYaybaycaydayeayfaygayhayiayjagKaquaykaykaykaykaykauPaylaymaynayoaypauLayqayraysauFarWaqhaytayuayvaywayvayxayvayyayvayvayzayAayBayCayDayEayFayGayFayHayIayJayIayKatHatHatHayHayIayKayLayLayFaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaahaahaahaahatJatJatJatJatJatJatJayMatJaahaahaahaahalWalOawwaouagAaaaaoAarlaqQarlaoAarCarCarCayUayUayUayUaxFayUayUayWayWayWayWayTayWayYaheaahaxCayXayVazaayZazbaxCaaaaoAasJasJaueaoAaaaaaaazgaufaziaugagKaufazlaugagKaufazoaugagKavyahAawxagKahAauhazuahAahAazxazxauiazzaujazxazxazBagKagKagKagKagKaquaykazCazDazEaykarWarWarWarWazFazGazHavRavSarWarWarWaocazIapwaoaapxapwazJapxatHatHatHatHatHazKazLazMazNazOazPazOazQazRazSazRazTayIazUayIazVazRazSazRayLazWazXaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaQxaahaahaahatJatJatJatJaraatJatJatJazYatJatJatJatJaahaaaaahagAaviawwanfalWaaaaavasJaupasJaavarCaAcaAdayUaAeaAfaAgaAhaAiayUaAjaAkaAlaAmaAnayWayYaheaaaaxCazdazcaAoazeaApaxCaaaaoUauqasJauraoAausausaboaAxaAyaAzagKaAAaAyaAzagKaABaAyaAzagKaACaADaAEagKaAFaAGaAHaAIawyazxaAKaALaAMaANaAOaAPazBaAQaARaARaASaARaATaykaAUaAVaAWaykaAXaAYaAXarWaAZaBaaBbaBcaBdaBeaBfaBgayvaBhatHatHatHatHatHatHatHaBiaBIauuaBkaBlaBmaBnaBoayFayFayFaahaahaJzaBqazRazRazRazRazRaBraJzazRaBsayFayFazXaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahatJatJatJatJatJatJatJaahatJaahaahatJatJaahaahalWalWardawwalWalWaaaaoAasJasJasJaBLaBuaBvaBvaCTaBxaByaBzaBAaBBaBCaBDaBEaCVaBGaDHayWayYaheaaaaxCaAraAqaBJaAsaBKaxCaaaaoAauyasJasJauzaBOauAaboaBQaAyaBRagKaBQaAyaBSagKaBQaAyaBTagKaBUaBVaBWagKaBXaBYaBZaCaaCbazxaCcaCdaCeaCfaCgaChazBaCiapjapjapjaCjaCkaykaClaCmaCnaykaCoaCpaCpaCqaCraCsaCtarWarWarWarWarWaocaCuatHavqaCwaCxaCyavraCAaCBaCCaCCaCCaCCaCDaCEaCFavsaCHayFaCIaahaahaaaaaaaaaaahaahaaaaaaaahaaaatJazRayFazXaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa diff --git a/_maps/map_files/MiniStation/MiniStation.dmm b/_maps/map_files/MiniStation/MiniStation.dmm index d63590ecb3c..ba976b45402 100644 --- a/_maps/map_files/MiniStation/MiniStation.dmm +++ b/_maps/map_files/MiniStation/MiniStation.dmm @@ -252,7 +252,7 @@ "eR" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/grille,/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0},/turf/simulated/floor/plating,/area/security/brig) "eS" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plasteel,/area/security/brig) "eT" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plasteel,/area/security/brig) -"eU" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden,/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/light{dir = 4; icon_state = "tube1"},/obj/machinery/door_timer/cell_2{dir = 4; pixel_x = 32; pixel_y = 0},/turf/simulated/floor/plasteel{icon_state = "red"; dir = 4},/area/security/brig) +"eU" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/door_timer{id = "Cell 2"; name = "Cell 2"; pixel_x = 32; pixel_y = 0},/turf/simulated/floor/plasteel{icon_state = "red"; dir = 4},/area/security/brig) "eV" = (/obj/machinery/door/window/northleft{base_state = "right"; dir = 8; icon_state = "right"; name = "Containment Pen"; req_access_txt = "55"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/door/poddoor/preopen{id = "xenobio1"; name = "containment blast door"},/turf/simulated/floor/engine,/area/medical/research{name = "Research Division"}) "eW" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/medical/research{name = "Research Division"}) "eX" = (/turf/simulated/wall,/area/space) @@ -345,7 +345,7 @@ "gG" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 10},/obj/structure/stool/bed/chair{dir = 4},/obj/effect/landmark/start{name = "Security Officer"},/turf/simulated/floor/plasteel,/area/security/brig) "gH" = (/obj/structure/table,/obj/item/weapon/storage/box/chemimp{pixel_x = 4; pixel_y = 3},/obj/item/weapon/storage/box/trackimp,/turf/simulated/floor/plasteel,/area/security/brig) "gI" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/obj/structure/table,/obj/item/weapon/paper_bin{pixel_x = 1; pixel_y = 9},/obj/item/weapon/storage/box/handcuffs,/obj/item/weapon/pen,/turf/simulated/floor/plasteel,/area/security/brig) -"gJ" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/door_timer/cell_3{dir = 4; pixel_x = 32; pixel_y = 0},/turf/simulated/floor/plasteel{icon_state = "red"; dir = 4},/area/security/brig) +"gJ" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden,/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/light{dir = 4; icon_state = "tube1"},/obj/machinery/door_timer{id = "Cell 1"; name = "Cell 1"; pixel_x = 32; pixel_y = 0},/turf/simulated/floor/plasteel{icon_state = "red"; dir = 4},/area/security/brig) "gK" = (/obj/machinery/computer/security/wooden_tv,/obj/item/device/radio/intercom{broadcasting = 0; freerange = 0; listening = 1; name = "Common Channel"; pixel_y = 25},/turf/simulated/floor/plasteel{icon_state = "grimy"},/area/security/brig) "gL" = (/obj/item/weapon/storage/secure/safe{pixel_x = 4; pixel_y = 26},/obj/machinery/light/small{dir = 1},/turf/simulated/floor/fancy/carpet,/area/security/brig) "gM" = (/obj/structure/table/wood,/obj/item/device/camera{desc = "A one use - polaroid camera. 30 photos left."; name = "detectives camera"; pictures_left = 30},/obj/machinery/atmospherics/unary/vent_pump{dir = 8; on = 1},/obj/item/device/taperecorder{pixel_y = 0},/obj/machinery/camera/autoname,/obj/item/weapon/folder/yellow,/obj/machinery/newscaster{pixel_y = 32},/turf/simulated/floor/fancy/carpet,/area/security/brig) @@ -396,7 +396,7 @@ "hF" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden,/turf/simulated/floor/plasteel,/area/security/brig) "hG" = (/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{dir = 8},/turf/simulated/floor/plasteel,/area/security/brig) "hH" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 10},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/turf/simulated/floor/plasteel,/area/security/brig) -"hI" = (/obj/machinery/door/window/brigdoor{dir = 4; id = "Cell 3"; name = "Cell 3"; req_access_txt = "2"},/obj/machinery/door/firedoor/border_only{dir = 8},/turf/simulated/floor/plasteel{icon_state = "red"; dir = 4},/area/security/brig) +"hI" = (/obj/machinery/door/window/brigdoor{dir = 4; id = "Cell 1"; name = "Cell 1"; req_access_txt = "2"},/obj/machinery/door/firedoor/border_only{dir = 8},/turf/simulated/floor/plasteel{icon_state = "red"; dir = 4},/area/security/brig) "hJ" = (/obj/machinery/flasher{id = "Cell 3"; pixel_x = 28},/turf/simulated/floor/plasteel,/area/security/brig) "hK" = (/obj/structure/closet/secure_closet/detective,/turf/simulated/floor/plasteel{icon_state = "grimy"},/area/security/brig) "hL" = (/turf/simulated/floor/fancy/carpet,/area/security/brig) @@ -1703,7 +1703,7 @@ "GM" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/tcommsat/computer) "GN" = (/obj/structure/closet/radiation,/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 1},/area/tcommsat/computer) "GO" = (/obj/docking_port/stationary{dir = 8; dwidth = 2; height = 12; id = "ferry_home"; name = "station"; turf_type = /turf/space; width = 5},/turf/simulated/floor/plating,/area/space) - + (1,1,1) = {" aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -1825,13 +1825,13 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadadadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaambqcMcNcOcOcPcOcQcRcSbqbNbNbNcTcUcVcUcWcXcYcZcWdadbcUdccjdddedfdgdhdidjckamamamamamambUcscscsdkdlcpcpdmdncmcmdobUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadadadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamamambqdpcScScScScSdqcSdrdsbNdtdudvdwdxdydwdzdAdBdCdDdEcjcjcjdFdedGdHdedIdJckaaaaaaaaaaambUbUbUbUdKbUdLdMbUbUbUbUbUbUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamamamamamambqdNcSdOcScSdPcSdOdQbqbqbqdRdSdTdUdVdWdXdYdZeaebecedeeefdeegeheiejekelckaaaaaaaaaaaabUclcmcmemencpcpeoepeqeresetaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeuamamamamamamambqevewexeyezezezeAeBeCeDeEeFeGeHeIeJeKeLeMeNeOePeQeReSeSeSeTeUckckckckckaaaaaaaaaaambUcFcGcseVcIcpcpcpcpcpcpcpeWamaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeuamamamamamamambqevewexeyezezezeAeBeCeDeEeFeGeHeIeJeKeLeMeNeOePeQeReSeSeSeTgJckckckckckaaaaaaaaaaambUcFcGcseVcIcpcpcpcpcpcpcpeWamaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeXamaaaaaaaaaaambJeZfafbfccScScSfdfebqffcSfbfgfheIfieKeLfjfkflebfmedfndedefofpfqfrfsckamamamamamamambUcscscsftfucpcpcpcpfvcpcpfwamamaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeXaaaaaaaaaaaaaabqfxcSfyfzfAfAfAfAfBfCfDfAfEfFfGfHfIfJeLfKfLcjfMfNckdededefofOfPdefQckamaaaaaaaaaaambUbUbUbUbUbUcpcpfRfSfTfUbUbUbUbUbUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeXaaaaaaaaaaaaaabqfxcSfyfzfAfAfAfAfBfCfDfAfEfFfGfHfIfJeLfKfLcjfMfNckdededefofOhIdefQckamaaaaaaaaaaambUbUbUbUbUbUcpcpfRfSfTfUbUbUbUbUbUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeXaaaaaaaaaaaaaabqcScSfbfccScScScSdrfVcScSfafWbIfXfXfXfYfZgacjgbgcgdgegfggghgigjgegkcjckckckckglgmgngogpgqgrgsbUgtgugvbUbUgwbUgxgygzbUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeXaaaaaaaaaaaaaagAgBcSfbfccScSgCcSdrfVcScScSdrgDfXfXfXeLfjgacjgEgFgFgGgHgIdegJckckckcjgKgLgMckgNgOgPgogQcpcpcpcpcpgRgSgTgUgVbUgWgXgYbUamaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeXaaaaaaaaaaaaaagAgBcSfbfccScSgCcSdrfVcScScSdrgDfXfXfXeLfjgacjgEgFgFgGgHgIdeeUckckckcjgKgLgMckgNgOgPgogQcpcpcpcpcpgRgSgTgUgVbUgWgXgYbUamaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeXaaaaaaaaaaaaaagZhacShbhchdbqbqbqbqbqbqbqbqbqbqbxbxbxeLfjhecjcjhfdehghhhigFhjfqfrhkcjhlhmhnckhofXhphqhrcpcpcphshthuhvhththwbUhxhyhxbUbUamaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeXaaaaaaaaaaaaaaeHhAcSfbfccSbqbNbNbNbNbNbNbNbNbNbNbxhBeLfjgahCcjhDhEhFdehGgehHhIdehJcjhKhLhMckhNfXhOgohPhQhRhShThUhVhWcpcphXbUgRhYhZiabUamamaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeXaaaaaaaaaaaaaaeHhAcSfbfccSbqbNbNbNbNbNbNbNbNbNbNbxhBeLfjgahCcjhDhEhFdehGgehHfPdehJcjhKhLhMckhNfXhOgohPhQhRhShThUhVhWcpcphXbUgRhYhZiabUamamaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeXaaaaaaaaaaaaaaibcScShbhcicbqbNbxbxbxbxbxbxbxbxidbxieeLfjgaifcjigihiiijikilimgjgegkcjinioipckiqfXfXgoirhQisitiuiviwixiyiziAbUcpiBiCbUbUbUbUbUamamamamamamamamamamamamamamamamamiDiDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeXaaaaaaaaaaaaaafhgBcSfbfccSbqiEdwiFiGbxiHiIiJiKiLbxbxiMiNiOiPcjcjcjcjcjcjcjcjcjcjcjcjiQiRiSckiTfXiUgobUbUbUbUbUgviVbUbUbUbUbUcpiWcpiXbUiYiZjabLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaajbjcjdaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeXaaaaaaaaaaaaxJgZhaewjehcjfbqbOjgjhjijjjkjljljljmjnjofYdAjpjpjqjqjqjqjqjqjqjqjrjqjqjqjsjtjujqdzjqjvjwjxjyjzjAjBjCjDjEjFjEjGjHcpjIjJjKjLjMjLbUamamamamamamamamamamamamamamamamamiDiDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa diff --git a/_maps/map_files/TgStation/tgstation.2.1.3.dmm b/_maps/map_files/TgStation/tgstation.2.1.3.dmm index d54c10c66f8..be76146f855 100644 --- a/_maps/map_files/TgStation/tgstation.2.1.3.dmm +++ b/_maps/map_files/TgStation/tgstation.2.1.3.dmm @@ -502,13 +502,13 @@ "ajH" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/turf/simulated/floor/plasteel{dir = 8; icon_state = "redcorner"},/area/security/brig) "ajI" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/turf/simulated/floor/plasteel,/area/security/brig) "ajJ" = (/obj/machinery/atmospherics/pipe/manifold/supply/hidden{tag = "icon-manifold-b-f (NORTH)"; dir = 1},/turf/simulated/floor/plasteel{dir = 2; icon_state = "redcorner"},/area/security/brig) -"ajK" = (/obj/machinery/door_timer/cell_1,/obj/machinery/light,/obj/machinery/atmospherics/pipe/manifold/supply/hidden,/turf/simulated/floor/plasteel{icon_state = "red"},/area/security/brig) +"ajK" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/obj/machinery/door_timer{id = "Cell 2"; name = "Cell 2"; pixel_y = -32},/turf/simulated/floor/plasteel{icon_state = "red"},/area/security/brig) "ajL" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/turf/simulated/floor/plasteel{dir = 8; icon_state = "redcorner"},/area/security/brig) -"ajM" = (/obj/machinery/door_timer/cell_2,/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/turf/simulated/floor/plasteel{icon_state = "red"},/area/security/brig) -"ajN" = (/obj/machinery/door_timer/cell_3,/obj/machinery/camera{c_tag = "Brig Central"; dir = 1},/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/turf/simulated/floor/plasteel{icon_state = "red"},/area/security/brig) +"ajM" = (/obj/machinery/light,/obj/machinery/atmospherics/pipe/manifold/supply/hidden,/obj/machinery/door_timer{id = "Cell 1"; name = "Cell 1"; pixel_y = -32},/turf/simulated/floor/plasteel{icon_state = "red"},/area/security/brig) +"ajN" = (/obj/machinery/light,/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/obj/machinery/door_timer{id = "Cell 4"; name = "Cell 4"; pixel_y = -32},/turf/simulated/floor/plasteel{icon_state = "red"},/area/security/brig) "ajO" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/turf/simulated/floor/plasteel{icon_state = "red"},/area/security/brig) "ajP" = (/obj/machinery/atmospherics/pipe/manifold/supply/hidden,/turf/simulated/floor/plasteel{icon_state = "red"; dir = 9},/area/security/brig) -"ajQ" = (/obj/machinery/door_timer/cell_4,/obj/machinery/light,/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/turf/simulated/floor/plasteel{icon_state = "red"},/area/security/brig) +"ajQ" = (/obj/machinery/camera{c_tag = "Brig Central"; dir = 1},/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/obj/machinery/door_timer{id = "Cell 3"; name = "Cell 3"; pixel_y = -32},/turf/simulated/floor/plasteel{icon_state = "red"},/area/security/brig) "ajR" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/manifold/supply/hidden,/turf/simulated/floor/plasteel{dir = 8; icon_state = "redcorner"},/area/security/brig) "ajS" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/turf/simulated/floor/plasteel,/area/security/brig) "ajT" = (/obj/machinery/atmospherics/pipe/manifold/supply/hidden{tag = "icon-manifold-b-f (NORTH)"; dir = 1},/turf/simulated/floor/plasteel{icon_state = "red"; dir = 4},/area/security/brig) @@ -6556,7 +6556,7 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfacfafPafPafPafPafPaaaafdaaaafPafPafPafPafPaafabfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaafaaaaaaaaiaieagWaigafRaihaiiaiiaijahcafRaikailafUaimainaioaipaipaiqairafUafUaisaitaduaduaduabmabmabmabmabmabmabmabmaiuaivaiwaidaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfaaaadwadxadxadxadxadyadzadAadBadBadBadBadCaaaabfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfaaaaaaaaaaafaaaaaaaaaafdaaaaaaaaaaafaaaaaaaaaabfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaixaixaiyaixaizaiAafRafRafRafRafRafRaiBaiCafRaiDaiEaiFaiFaiFaiFaiFaiFaiFaiFaiGaiHaiIaiJaiFailaiAaiKaiLaiMaiNaiOaiPaiQaiRaiuaivaiwaidaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfaafaemaemaemaemaemaaaadzaaaaemaemaemaemaemaiSabqaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfaafaenaenaenaenaenaaaafdaaaaenaenaenaenaenaafabfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaixaiTaiUaiVaiWaiXaiYaiZajaajbajcajdajeajfajgajhajiajjajkajjajjajjajjajjajjajlajjajiajmajkajnajoajpajqajrajsajtajuajvajwaiuaivaiwacAaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfaaaaaaaafaaaaafaaaaaaadzaaaaaaaafaaaaafaaaaaaabfaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfaaaafaafbafbafbafbafcafdafeaffaffaffaffafgaaaabfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaajxaeZaeZaeZaelaaaaafaizajyajzajAajBajCajDajEajFajGajHajIajJajKajLajIajJajMajLajIajJajNajOajOajOajPahCajQajRajSajTajUajVajWajVajVajVajXajYaiPaiuaivaiwaidaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfabfabfaafaafaafaafaafadzaafaafaafaafaafabfabfabfaafaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfaaaafaafbafbafbafbafcafdafeaffaffaffaffafgaaaabfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaajxaeZaeZaeZaelaaaaafaizajyajzajAajBajCajDajEajFajGajHajIajJajMajLajIajJajKajLajIajJajQajOajOajOajPahCajNajRajSajTajUajVajWajVajVajVajXajYaiPaiuaivaiwaidaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfabfabfaafaafaafaafaafadzaafaafaafaafaafabfabfabfaafaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaiSafPafPafPafPafPaaaafdaaaafPafPafPafPafPaafabfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaajZakaakbakcajZaiyaiyakdakeakfakgakhaiAafRakiafRafRakjakkaklakmaknakoaklakmaknakpakqakmakraksakmaktakuakmakvakwakxaiAakyakzaiPakAaiPakBakCaiPaiuaivaiwaidaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaaaaaaaafaaaaaaakDaaaaaaaafaaaaaaaafaaaaafaafaafaaaaaaaaaaaaaaaaaaaafaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfaaaaaaaafaaaaafaaaaaaakEaaaaaaaafaaaaafaaaaaaabfaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaakFakGakHakIakJakKakLakKakeakMakNakOaiAakPakQakPafRakRakSakTafRakUakSakTafRakUakSakTafRakVakWakXakYailafRakZalaalbaiAalcaldalealfalealgalhaliaiuaivaiwaidaafaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaafaafaaaaaaaaaaafaaaaaaaljaaaaaaaafaaaaaaaafaaaaaaaaaaafaafaaaaaaaaaaaaaaaallalmallaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfabfabfaafaafaafaafalnaloalnaafaafaafaafabfabfabfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaajZalpalqalrajZaiyaiyaiyalsaltalualvaiAakPakQakPafRalwakSalxafRalyakSalzafRalAakSalBafRalCalDalEakYalFafRalGakSalHaiAalIalJalIalKalIalIalLalIaiuaivaiwacAacAaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaaaaaaaaaaaaaafaaaalMalNalMaaaaafaaaaaaaafaaaaaaaaaaaaaafaafaaaaaaaaaaaaallalOallaafaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa diff --git a/_maps/map_files/generic/z2.dmm b/_maps/map_files/generic/z2.dmm index a209cde1838..7453230b960 100644 --- a/_maps/map_files/generic/z2.dmm +++ b/_maps/map_files/generic/z2.dmm @@ -354,13 +354,21 @@ "gP" = (/obj/structure/optable,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/space) "gQ" = (/obj/structure/table,/obj/item/weapon/circular_saw,/obj/item/weapon/cautery,/obj/item/weapon/surgicaldrill,/obj/item/robot_parts/l_arm,/obj/item/robot_parts/r_arm,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/space) "gR" = (/obj/structure/table,/obj/item/weapon/scalpel,/obj/item/weapon/retractor,/obj/item/weapon/hemostat,/obj/item/weapon/surgical_drapes,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/space) +"gS" = (/obj/item/weapon/shard{color = "#008000"; icon_state = "small"},/obj/structure/grille{color = "#008000"; density = 0; icon_state = "brokengrille"},/turf/unsimulated/floor/plating,/area/wizard_station) "gT" = (/obj/machinery/door/airlock/shuttle,/obj/docking_port/mobile{dir = 8; dwidth = 2; height = 12; id = "ferry"; name = "ferry shuttle"; travelDir = 180; width = 5},/obj/docking_port/stationary{dir = 8; dwidth = 2; height = 12; id = "ferry_away"; name = "unknown"; turf_type = /turf/unsimulated/floor; width = 5},/turf/simulated/shuttle/floor,/area/space) "gU" = (/obj/machinery/door/airlock/external{name = "Ferry Airlock"; req_access_txt = "0"},/turf/unsimulated/floor{icon_state = "engine"},/area/centcom/ferry) "gV" = (/turf/unsimulated/floor{icon_state = "engine"},/area/centcom/ferry) "gW" = (/turf/unsimulated/floor{icon_state = "greencorner"; dir = 4},/area/centcom/ferry) "gX" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; icon_state = "space"; layer = 4; name = "EXTERNAL AIRLOCK"; pixel_x = 0},/turf/unsimulated/wall,/area/centcom/evac) +"gY" = (/obj/structure/shuttle/engine/heater{tag = "icon-heater (WEST)"; icon_state = "heater"; dir = 8},/turf/unsimulated/floor/plating,/area/wizard_station) +"gZ" = (/obj/machinery/door/poddoor/preopen,/obj/effect/decal/cleanable/blood/splatter,/turf/unsimulated/floor/plating,/area/wizard_station) "ha" = (/turf/unsimulated/wall/fakeglass{icon_state = "fakewindows"; dir = 5},/area/centcom/ferry) +"hb" = (/obj/structure/table/wood,/obj/item/clothing/suit/wizrobe/magusblue,/obj/item/clothing/head/wizard/magus,/obj/item/weapon/staff,/obj/structure/mirror/magic{pixel_y = 28},/turf/unsimulated/floor{tag = "icon-cult"; icon_state = "cult"},/area/wizard_station) "hc" = (/obj/structure/flora/bush,/turf/unsimulated/floor{icon = 'icons/turf/snow.dmi'; icon_state = "snow"},/area/syndicate_mothership) +"hd" = (/obj/machinery/door/poddoor/preopen,/obj/effect/decal/cleanable/blood/splatter,/obj/effect/decal/cleanable/blood/gibs/body,/turf/unsimulated/floor/plating,/area/wizard_station) +"he" = (/obj/structure/shuttle/engine/heater{icon_state = "heater"; dir = 4},/turf/unsimulated/floor/plating,/area/wizard_station) +"hf" = (/obj/item/weapon/shard{color = "#008000"; icon_state = "medium"},/obj/structure/grille{color = "#008000"; density = 0; icon_state = "brokengrille"},/turf/unsimulated/floor/plating,/area/wizard_station) +"hg" = (/obj/structure/shuttle/engine/heater,/obj/structure/window/reinforced{dir = 1},/turf/unsimulated/floor/plating,/area/wizard_station) "hi" = (/turf/unsimulated/floor{name = "plating"},/turf/simulated/shuttle/wall{icon_state = "swall_f9"; dir = 2},/area/space) "hj" = (/turf/unsimulated/floor{icon_state = "greencorner"},/area/centcom/ferry) "hk" = (/obj/structure/stool/bed/chair{dir = 4},/turf/unsimulated/floor{icon_state = "greencorner"; dir = 8},/area/centcom/evac) @@ -445,7 +453,6 @@ "iX" = (/obj/structure/table/reinforced,/obj/item/weapon/clipboard,/turf/unsimulated/floor{icon_state = "green"; dir = 8},/area/centcom/evac) "iY" = (/obj/structure/stool/bed/chair/office/dark{dir = 1},/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/evac) "iZ" = (/obj/structure/filingcabinet/filingcabinet,/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/evac) -"ja" = (/obj/item/weapon/shard{color = "#008000"; icon_state = "small"},/obj/structure/grille{color = "#008000"; density = 0; icon_state = "brokengrille"},/turf/simulated/floor/plating/airless,/area/wizard_station) "jb" = (/turf/unsimulated/wall/fakeglass{color = "#008000"; dir = 8; icon_state = "fakewindows2"},/area/wizard_station) "jc" = (/turf/unsimulated/wall/fakeglass{color = "#008000"; dir = 4; icon_state = "fakewindows"},/area/wizard_station) "jd" = (/turf/unsimulated/wall/normal{tag = "icon-uranium2"; icon_state = "uranium2"},/area/wizard_station) @@ -527,7 +534,6 @@ "kQ" = (/turf/space,/area/tdome/tdomeobserve) "kR" = (/obj/effect/decal/remains/human,/obj/effect/decal/cleanable/blood,/turf/unsimulated/floor{tag = "icon-cultdamage6"; icon_state = "cultdamage6"},/area/wizard_station) "kS" = (/obj/effect/decal/cleanable/blood/splatter,/turf/unsimulated/floor{tag = "icon-cultdamage"; icon_state = "cultdamage"},/area/wizard_station) -"kT" = (/obj/structure/mirror{pixel_x = 28},/turf/unsimulated/floor{tag = "icon-cult"; icon_state = "cult"},/area/wizard_station) "kU" = (/obj/machinery/suit_storage_unit/syndicate,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/space) "kV" = (/obj/effect/landmark{name = "Syndicate-Uplink"},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/space) "kW" = (/turf/unsimulated/wall/fakeglass,/area/syndicate_mothership) @@ -557,10 +563,8 @@ "lz" = (/turf/unsimulated/floor{icon_state = "redbluefull"; dir = 2},/area/tdome/tdomeobserve) "lA" = (/obj/structure/stool/bed/chair,/obj/effect/landmark{name = "tdomeobserve"},/turf/unsimulated/floor{icon_state = "redbluefull"; dir = 2},/area/tdome/tdomeobserve) "lB" = (/obj/structure/shuttle/engine/propulsion{tag = "icon-propulsion (EAST)"; icon_state = "propulsion"; dir = 4},/turf/space/transit,/area/wizard_station) -"lC" = (/obj/structure/shuttle/engine/heater{tag = "icon-heater (WEST)"; icon_state = "heater"; dir = 8},/turf/simulated/floor/plating/airless,/area/wizard_station) "lD" = (/obj/effect/decal/cleanable/blood/gibs/body,/turf/unsimulated/floor{icon_state = "floor"},/area/wizard_station) "lE" = (/turf/unsimulated/floor{icon_state = "floor"},/area/wizard_station) -"lF" = (/obj/machinery/door/poddoor/preopen,/obj/effect/decal/cleanable/blood/splatter,/turf/simulated/floor/plating/airless,/area/wizard_station) "lG" = (/turf/unsimulated/floor{tag = "icon-cultdamage"; icon_state = "cultdamage"},/area/wizard_station) "lH" = (/obj/effect/forcefield,/turf/unsimulated/floor{tag = "icon-cultdamage7"; icon_state = "cultdamage7"},/area/wizard_station) "lI" = (/obj/effect/forcefield,/turf/unsimulated/floor{tag = "icon-cultdamage5"; icon_state = "cultdamage5"},/area/wizard_station) @@ -613,7 +617,6 @@ "mF" = (/obj/structure/stool/bed/chair/wood/wings,/turf/unsimulated/floor{tag = "icon-cult"; icon_state = "cult"},/area/wizard_station) "mG" = (/obj/structure/table/wood,/obj/item/stack/medical/bruise_pack,/obj/item/stack/medical/ointment,/turf/unsimulated/floor{tag = "icon-cult"; icon_state = "cult"},/area/wizard_station) "mH" = (/obj/structure/table/wood,/obj/item/weapon/retractor,/turf/unsimulated/floor{tag = "icon-cult"; icon_state = "cult"},/area/wizard_station) -"mI" = (/obj/structure/table/wood,/obj/item/clothing/suit/wizrobe/magusblue,/obj/item/clothing/head/wizard/magus,/obj/item/weapon/staff,/turf/unsimulated/floor{tag = "icon-cult"; icon_state = "cult"},/area/wizard_station) "mJ" = (/obj/structure/table/wood,/obj/item/clothing/suit/wizrobe/magusred,/obj/item/clothing/head/wizard/magus,/obj/item/weapon/staff,/turf/unsimulated/floor{tag = "icon-cult"; icon_state = "cult"},/area/wizard_station) "mK" = (/obj/structure/rack,/obj/item/clothing/head/helmet/space/hardsuit/wizard,/turf/unsimulated/floor{tag = "icon-cult"; icon_state = "cult"},/area/wizard_station) "mL" = (/obj/effect/decal/cleanable/blood/splatter,/obj/effect/decal/cleanable/blood/gibs/body,/turf/unsimulated/floor{tag = "icon-cultdamage"; icon_state = "cultdamage"},/area/wizard_station) @@ -655,10 +658,8 @@ "nx" = (/obj/structure/cult/talisman{desc = "A altar dedicated to the Wizard's Federation"},/obj/item/weapon/kitchenknife/ritual,/turf/unsimulated/floor{tag = "icon-cult"; icon_state = "cult"},/area/wizard_station) "ny" = (/obj/item/clothing/shoes/sandal/marisa,/obj/item/clothing/suit/wizrobe/marisa,/obj/item/clothing/head/wizard/marisa,/obj/item/weapon/staff/broom,/turf/unsimulated/floor{tag = "icon-cult"; icon_state = "cult"},/area/wizard_station) "nz" = (/obj/effect/decal/cleanable/blood/splatter,/mob/living/simple_animal/hostile/creature{name = "Experiment 35b"},/turf/unsimulated/floor{tag = "icon-cult"; icon_state = "cult"},/area/wizard_station) -"nA" = (/obj/machinery/door/poddoor/preopen,/obj/effect/decal/cleanable/blood/splatter,/obj/effect/decal/cleanable/blood/gibs/body,/turf/simulated/floor/plating/airless,/area/wizard_station) "nB" = (/obj/effect/decal/cleanable/blood/splatter,/obj/effect/decal/remains/human,/turf/unsimulated/floor{icon_state = "floor"},/area/wizard_station) "nC" = (/obj/effect/decal/cleanable/blood/splatter,/obj/effect/decal/cleanable/blood/gibs/body,/turf/unsimulated/floor{icon_state = "floor"},/area/wizard_station) -"nD" = (/obj/structure/shuttle/engine/heater{icon_state = "heater"; dir = 4},/turf/simulated/floor/plating/airless,/area/wizard_station) "nE" = (/obj/structure/shuttle/engine/propulsion{icon_state = "propulsion"; dir = 8},/turf/space/transit,/area/wizard_station) "nF" = (/obj/machinery/sleeper{icon_state = "sleeper-open"; dir = 4},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/space) "nG" = (/obj/machinery/door/window{base_state = "right"; dir = 4; icon_state = "right"; name = "Infirmary"; req_access_txt = "150"},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/space) @@ -668,7 +669,6 @@ "nK" = (/obj/machinery/flasher{id = "tdomeflash"; name = "Thunderdome Flash"},/turf/simulated/floor/bluegrid,/area/tdome/arena) "nL" = (/obj/machinery/camera{pixel_x = 12; pixel_y = -10; network = list("thunder"); c_tag = "Green Team"},/obj/effect/landmark{name = "tdome1"},/turf/unsimulated/floor{name = "plating"},/area/tdome/tdome1) "nM" = (/turf/unsimulated/wall/fakeglass{color = "#008000"},/area/wizard_station) -"nN" = (/obj/item/weapon/shard{color = "#008000"; icon_state = "medium"},/obj/structure/grille{color = "#008000"; density = 0; icon_state = "brokengrille"},/turf/simulated/floor/plating,/area/wizard_station) "nO" = (/obj/effect/landmark/start{name = "wizard"},/turf/unsimulated/floor{tag = "icon-cultdamage5"; icon_state = "cultdamage5"},/area/wizard_station) "nP" = (/obj/effect/decal/remains/human,/obj/effect/decal/cleanable/blood/splatter,/turf/unsimulated/floor{tag = "icon-cult"; icon_state = "cult"},/area/wizard_station) "nQ" = (/turf/unsimulated/floor{tag = "icon-cult"; icon_state = "cult"},/turf/simulated/shuttle/wall{icon_state = "swall_f5"; dir = 2},/area/wizard_station) @@ -738,7 +738,6 @@ "ph" = (/turf/unsimulated/wall/fakedoor{name = "Squad 2 Pod"},/area/wizard_station) "pi" = (/turf/unsimulated/wall/normal{tag = "icon-uranium13"; icon_state = "uranium13"},/area/wizard_station) "pj" = (/turf/simulated/shuttle/wall,/area/wizard_station) -"pk" = (/obj/structure/shuttle/engine/heater,/obj/structure/window/reinforced{dir = 1},/turf/simulated/shuttle/plating,/area/wizard_station) "pl" = (/obj/structure/table/wood,/turf/unsimulated/floor{tag = "icon-cult"; icon_state = "cult"},/area/wizard_station) "pm" = (/obj/structure/table/wood,/obj/item/weapon/gun/magic/wand{desc = "Used in emergency's to reignite magma engines. This one appears spent."; name = "wand of emergency engine ignition"},/turf/unsimulated/floor{tag = "icon-cult"; icon_state = "cult"},/area/wizard_station) "pn" = (/obj/structure/shuttle/engine/propulsion{icon_state = "propulsion_l"},/turf/space,/area/wizard_station) @@ -951,31 +950,31 @@ ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababgzgIgIgIgIgIhMhNhOhOhOhOhOhNhPgIgIgIgIhcgIhygJhygJgIgKgIgKgzabababababababababababababababababababababababababababababababfhhUhUhUhUfDhUfDhUhUhUhUhUhUisfhhZhZiaibicidiehZhZekgigigigjfxfyfzdGhJhJhJhJdGfqfqfqifdGabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababgzgIgIgIgIgIhNigihiiijikililhNimgIgIhygzgziniogzgzhyipiqhygzabababababababababababababababababababababababababababababababfhiJhUhUiKiKiKiKfRhUhUhUhUhUiLfhitiuiviwixiyiviuiuekgiiziAiBekababdGiCiCiDiDdGfrfqfqhLezabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababgzgIgIgIgIgIhNiEihihiFihihihhNimgIiGgzgziHiIiIiHgzgzgzgzgzgzgzgzabababababababababababababababababababababababababababababfhiMhUfTiKiNiOiKhUhUhUhUhUhUiPfhiuiUiViwixiyiViWiuekgiiXiYiZekababebfeedededededededfeeeabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaajajbjcjdaaaaaaaaaaaaaaaaaaaaaaababababababgzgIgIgIgIgIhNjeihihihjfihjghNimhciGgzjhjijijijijjjkjljmjnjojpgzabababababababababababababababababababababababababababababfhiQhUhUiKiKiKiKfRhUhUhUhUhUiRfhjriujriwixiyjriujrekgigigigiekabababebegegegegegegegeeababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagSjbjcjdaaaaaaaaaaaaaaaaaaaaaaababababababgzgIgIgIgIgIhNjeihihihjfihjghNimhciGgzjhjijijijijjjkjljmjnjojpgzabababababababababababababababababababababababababababababfhiQhUhUiKiKiKiKfRhUhUhUhUhUiRfhjriujriwixiyjriujrekgigigigiekabababebegegegegegegegeeababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaajsaajtjujvjwjxaaaaaaaaaaaaaaaaaaaaababababababgzgIgIgIgIgIjyhNhNhNjzhNhNhNjAgIgIjBgzjCjijDjDjEjijijijFjGjGjGgzabababababababababababababababababababababababababababababfhiShUhUgnhUgnhUhUhUhUhUhUhUiTfhjPiuiuiwixiyiuiujQekjRjSjSjTekababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaajsjUjVjWjvjXjYaaaaaaaaaaaaaaaaaaaaababababababgzgIgIgIgIgIgIgIhNjZihkahNkbhyhyhykcgzjijDkdkejDjikfkgjmkhkigzgzabababababababababababababababababababababababababababababfhjqhUhUhUhUhUhUhUjHjJjIgpiTjLfhklkmkmiwixiyknknkoekekkpekekekababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaajYkqlGjXksktjYaaaaaaaaaaaaaaaaaaaaababababababgzgIgIgIgIgIgIgIhNkuihkvhNkwkxkxkxiogzjijDkykzjDjikfkAgzgzgzgzababababababababababababababababababababababababababababababfhfhfhfhfhgBfhfhfhfhfhfhfhfhfhfhhZhZhZhZixhZhZhZhZekeoeoeoeoekababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaajwjxkIkJkIkKkLaaaaaaaaaaaaaaaaaaaaababababababgzgIgIhMhNhNhNhNhNkuihkvhNkMkNkNkNkNkOjijijijijijikfkAgzgzgzgzabababababababababababababababababababababababababababababababababababababababababababababababababhZixhZkQkQkQeoeoeoeoeoekababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababaaaaaaaaaaaaaaaaaaaaaaaajsjskLkRkSkTjwaaaaaaaaaaaaaaaaaaaaaaababababababgzgIgIhNkUihihkVhNkuihkvhNkWkXinkxiogzkYjDjDjDjijikfkZgzlalbgzgzabababababababababababababababababababababababababababababababababababababababababkQhZhZhZhZhZhZhZichZhZhZhZhZhZhZhZekekababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababaaaaaaaaaaaaaaaaaaaaaaaajsjskLkRkSjvjwaaaaaaaaaaaaaaaaaaaaaaababababababgzgIgIhNkUihihkVhNkuihkvhNkWkXinkxiogzkYjDjDjDjijikfkZgzlalbgzgzabababababababababababababababababababababababababababababababababababababababababkQhZhZhZhZhZhZhZichZhZhZhZhZhZhZhZekekababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab ababababababababababaaaaaaaaaaaaaaaaaaaaaalhliljlklllmjvlnjsaaaaaaaaaaaaaaaaaaaaababababababgzgIgIhNkUihlolphNkuihkvhNhNnrlrhPlsgzltlulvlulujijijilwlxlxlygzabababababababababababababababababababababababababababababababababababababababababhZlzlAlAlAlAlAlzlzlzlAlAlAlAlAlzhZababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababaaaaaaaaaaaaaaaaaaaalBlClDlElFlljvlGlHlIjsjsaaaaaaaaaaaaaaaaababababababgzlJgIhNkUihihlKhNihihihhNihihihhNjBgzlLlMlLlLlNjijijigzlOlPlygzababababababababababababababababababababababababababababababababababababababababablQlzlzlzlRlzlzlzlzlzlzlzlRlzlzlzlQababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababaaaaaaaaaaaaaaaaaaaalBgYlDlEgZlljvlGlHlIjsjsaaaaaaaaaaaaaaaaababababababgzlJgIhNkUihihlKhNihihihhNihihihhNjBgzlLlMlLlLlNjijijigzlOlPlygzababababababababababababababababababababababababababababababababababababababababablQlzlzlzlRlzlzlzlzlzlzlzlRlzlzlzlQababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab ababababababababababaaaaaaaaaaaaaaaaaajsaaljlSlSlTlljvlUlGlIaalVlWaaaaaaaaaaaaaaababababababgzgIgIhNkUihihihlXihihihlYihihihhNiGgzgzkglZmambgzmcjigzgzgzgzgzabababababababababababababababababababababababababababababababababababababababababhZlzlAlAlAlAlAlzlzlzlAlAlAlAlAlzhZababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab ababababababababababaaaaaaaaaaaaaaaaaalnjsaaaajsmdmejWmfjWlnjsjsaaaaaaaaaaaaaaaaababababababgzgIgIhNkUihihihmgihihihmhihihmihNmjmjlsgzgzgzgzgzgNgCmlmmmnmogzabababababababababababababababababababababababababababababababababababababababababhZidmpmpmpmpmpmpmpmpmpmpmpmpmpibhZababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab ababababababababababaaaaaaaaaaaaaakKmqmrmsmtmumtmtmqmvmsmtmtmumtmtaajsaaaaaaaaaaababababababgzgIhMhNhNhNhNhNhNmwihihhNhNhNhNhNhNhPmxmxmxmylsgzmzmzmzmzmzmzgzabababababababababababababababababababababababababababababababababmBmBmBmBmBmBmBmBmBmCmDmDmDmDmDmDmDmDmDmDmDmDmDmCmBmBmBmBmBmBmBmBmBababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababaaaaaaaaaaaaaamEmFjvjvmFmEmGmHjvjvjvmImJmEmKmLlnmMjsjsaaaaaaababababababgzgIhNmNmNmOmPmQhNihihihhNmRmSmTmUmVhNgIgJgIgIgLjmmzmzmzmzmzmWgzabababababababababababababababababababababababababababababababababmBmZnanbnbnbnbnbncndmDmDmDmDmDmDmDmDmDmDmDmDmDnencnfnfnfnfnfnangmBababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababaaaaaaaaaaaaaamEmFjvjvmFmEmGmHjvjvjvhbmJmEmKmLlnmMjsjsaaaaaaababababababgzgIhNmNmNmOmPmQhNihihihhNmRmSmTmUmVhNgIgJgIgIgLjmmzmzmzmzmzmWgzabababababababababababababababababababababababababababababababababmBmZnanbnbnbnbnbncndmDmDmDmDmDmDmDmDmDmDmDmDmDnencnfnfnfnfnfnangmBababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab ababababababababababaaaaaaaaaaaaaanhnijvjvninhmMmMjvjvjvjvnjnhnknllSlSnmaaaaaaaaababababababgzgIhNihihihloihnnihihihnoihloihlonphNgIhcgKgJhcgznqnqnqnqnqlqgzabababababababababababababababababababababababababababababababababmBmZnanbnsnbnsnbncndmDmDmDmDmDmDmDmDmDmDmDmDmDnencnfntnfntnfnangmBababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababaaaaaaaaaaaaaanunvjvlGjvnwlUlGjvnxjvjvnynunznAnBnCnDnEaaaaaaababababababgzgIhNnFihihihihnGihihihnHihihihihihhNgIgIgIgKiGgzgzgzgzgzgzgzgzabababababababababababababababababababababababababababababababababmBmZnanbnbnInbnbncndmDmDmDmDmDnJnKnJmDmDmDmDmDnencnfnfnLnfnfnangmBababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababaaaaaaaaaaaaaanMnijvjWlUnNjWjvjvnOjvjvjvnMnPnQnmnRlhaaaaaaaaababababababgzgIhNnFihihnSnThNnUnVnUhNnWnXihihihhNgIgKgIhciGgzababababababababababababababababababababababababababababababababababababababababmBmZnanbnbnbnbnbncndmDmDmDmDmDnJnYnJmDmDmDmDmDnencnfnfnfnfnfnangmBababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababaaaaaaaaaaaaaanunvjvlGjvnwlUlGjvnxjvjvnynunzhdnBnChenEaaaaaaababababababgzgIhNnFihihihihnGihihihnHihihihihihhNgIgIgIgKiGgzgzgzgzgzgzgzgzabababababababababababababababababababababababababababababababababmBmZnanbnbnInbnbncndmDmDmDmDmDnJnKnJmDmDmDmDmDnencnfnfnLnfnfnangmBababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababaaaaaaaaaaaaaanMnijvjWlUhfjWjvjvnOjvjvjvnMnPnQnmnRlhaaaaaaaaababababababgzgIhNnFihihnSnThNnUnVnUhNnWnXihihihhNgIgKgIhciGgzababababababababababababababababababababababababababababababababababababababababmBmZnanbnbnbnbnbncndmDmDmDmDmDnJnYnJmDmDmDmDmDnencnfnfnfnfnfnangmBababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab ababababababababababaaaaaaaaaaaaaajdnZjvjvnZjdoajvlGjWjvjvoajdobocodoeaaaaaaaaaaababababababgzgIhNihihgOhNhNhNofogihhNhNhNihihihhNgIgIgJgIiGgzababababababababababababababababababababababababababababababababababababababababmBmZnanbnsnbnsnbncndmDmDmDmDmDmDmDmDmDmDmDmDmDnencnfntnfntnfnangmBababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab ababababababababababaaaaaaaaaaaaaajwmqojmsmtokmtmqkIolkImsmtokmtmqjsjsjsaaaaaaaaababababababgzgIhNgQgPgRhNgIhNopopophNgIhNiloqorhNgIgIgIgIiGgzababababababababababababababababababababababababababababababababababababababababmBmZnanbnbnbnbnbncndmDmDmDmDmDmDmDmDmDmDmDmDmDnencnfnfnfnfnfnangmBababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab ababababababababababaaaaaaaaaaaaaaaaaamdlGaajsaajsoslmmdaaaajsaaaaaaaajsaaaaaaaaababababababgzgIhNopopophNgIjyotegoujAgIhNopopophNgIgIgIgIiGgzababababababababababababababababababababababababababababababababababababababababmBmBmBovovovovovmBmCmDmDmDmDmDmDmDmDmDmDmDmDmDmCmBovovovovovmBmBmBababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab ababababababababababaaaaaaaaaaaaaaaaaajsjsaaowlGaaoxoymdjsaalUaaaaaaaaaaaaaaaaaaababababababgzgIjyotegoujAgIgIgIgIgIgIgIjyotegoujAgIgIgIgIiGgzababababababababababababababababababababababababababababababababababababababababababmBozozozozozmBoAoBoBoBoBoBoBoBoBoBoBoBoBoBoCmBoDoDoDoDoDmBababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab ababababababababababaaaaaaaaaaaaaaaaaaaaaaaajsjsaaoElGoFaaaaaajsaaaaaaaaaaaaaaaaababababababgzgIgIgIgIgIgIgIgIgIgIgIgIgIgIgIgIgIgIgIgIgIgIiGgzababababababababababababababababababababababababababababababababababababababababababmBmBmBmBmBmBmBoGoHoHoHoHoHoIoJoKoHoHoHoHoHoGmBmBmBmBmBmBmBababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaajsmumqoLmsmujsaajsjsaaaaaaaaaaaaaaababababababgzgzgzgzgzgzgzgzgzgzgzgzgzgzgzgzgzgzgzgzgzgzgzgzgzababababababababababababababababababababababababababababababababababababababababababababababababoMoGoGoGoNoGoOoOoOoOoOoGoNoGoGoGoMababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaamEoPoQoRmEownllFoSoTjsaaaaaaaaaaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababoMoMoUoMoMoMoMoVoWoXoMoMoMoMoUoMoMababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaamEoPoQoRmEownlgZoSoTjsaaaaaaaaaaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababoMoMoUoMoMoMoMoVoWoXoMoMoMoMoUoMoMababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaakIoYoZpakIpbpclEpdjvjYaaaaaaaaaaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababoMoMoMoMoMababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab ababababababababababaaaaaaaaaaaaaaaaaaaaaaaalmjsjdpepfpgjdjWphlEpdaajsaaaaaaaaaaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababaaaaaaaaaaaaaaaaaaaaaaaajsmupimqkImspimupjpkpdaajsaaaaaaaaaaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababhshshshshshshshshshshshshshshshshshshsababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababaaaaaaaaaaaaaaaaaaaaaaaajsmupimqkImspimupjhgpdaajsaaaaaaaaaaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababhshshshshshshshshshshshshshshshshshshsababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab ababababababababababaaaaaaaaaaaaaaaaaaaaaaaajsmEjvplpmpljvmEaapnaaaajsaaaaaaaaaaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababhspopppqprprpppsptpupvpwpxpypxpxpxpzhsababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab ababababababababababaaaaaaaaaaaaaaaaaaaaaajslGpAjvjvjvjvjvpAaaaaaaaalGaaaaaaaaaaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababhspopppppppppppBpwpwpwpCpxpxpxpDpxpxhsababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab ababababababababababaaaaaaaaaaaaaaaaaajsjslmjvjdpEjvjvjvpEjdaaaaaaaaaaaaaaaaaaaaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababhspopppFpopGpHpIpwpwpwpwpxpxpJpxpKpyhsababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab diff --git a/code/__DEFINES/combat.dm b/code/__DEFINES/combat.dm index e9b5c883731..9f46ab5c791 100644 --- a/code/__DEFINES/combat.dm +++ b/code/__DEFINES/combat.dm @@ -44,14 +44,27 @@ #define GRAB_UPGRADING 4 #define GRAB_KILL 5 + +//Hostile Mob Stances #define HOSTILE_STANCE_IDLE 1 //#define HOSTILE_STANCE_ALERT 2 //Was only used by bears #define HOSTILE_STANCE_ATTACK 3 #define HOSTILE_STANCE_ATTACKING 4 //#define HOSTILE_STANCE_TIRED 5 //Was also only used by bears +//Hostile Mob AI Status +#define AI_ON 1 +#define AI_SLEEP 2 +#define AI_OFF 3 + //Embedded objects -#define EMBEDDED_PAIN_CHANCE 15 //Chance for embedded objects to cause pain (damage user) -#define EMBEDDED_ITEM_FALLOUT 5 //Chance for embedded object to fall out (causing pain but removing the object) -#define EMBED_CHANCE 45 //Chance for an object to embed into somebody when thrown (if it's sharp) \ No newline at end of file +#define EMBEDDED_PAIN_CHANCE 15 //Chance for embedded objects to cause pain (damage user) +#define EMBEDDED_ITEM_FALLOUT 5 //Chance for embedded object to fall out (causing pain but removing the object) +#define EMBED_CHANCE 45 //Chance for an object to embed into somebody when thrown (if it's sharp) +#define EMBEDDED_PAIN_MULTIPLIER 2 //Coefficient of multiplication for the damage the item does while embedded (this*item.w_class) +#define EMBEDDED_FALL_PAIN_MULTIPLIER 5 //Coefficient of multiplication for the damage the item does when it falls out (this*item.w_class) +#define EMBEDDED_IMPACT_PAIN_MULTIPLIER 4 //Coefficient of multiplication for the damage the item does when it first embeds (this*item.w_class) +#define EMBED_THROWSPEED_THRESHOLD 4 //The minimum value of an item's throw_speed for it to embed (Unless it has embedded_ignore_throwspeed_threshold set to 1) +#define EMBEDDED_UNSAFE_REMOVAL_PAIN_MULTIPLIER 8 //Coefficient of multiplication for the damage the item does when removed without a surgery (this*item.w_class) +#define EMBEDDED_UNSAFE_REMOVAL_TIME 30 //A Time in ticks, total removal time = (this*item.w_class) diff --git a/code/__DEFINES/preferences.dm b/code/__DEFINES/preferences.dm index c21cb6c999f..d6c41b34888 100644 --- a/code/__DEFINES/preferences.dm +++ b/code/__DEFINES/preferences.dm @@ -4,21 +4,27 @@ #define SOUND_MIDI 2 #define SOUND_AMBIENCE 4 #define SOUND_LOBBY 8 -#define CHAT_OOC 16 -#define CHAT_DEAD 32 -#define CHAT_GHOSTEARS 64 -#define CHAT_GHOSTSIGHT 128 -#define CHAT_PRAYER 256 -#define CHAT_RADIO 512 -#define MEMBER_PUBLIC 1024 -#define CHAT_PULLR 2048 -#define INTENT_STYLE 4096 -#define CHAT_GHOSTWHISPER 8192 -#define MIDROUND_ANTAG 16384 -#define CHAT_GHOSTPDA 32768 +#define MEMBER_PUBLIC 16 +#define INTENT_STYLE 32 +#define MIDROUND_ANTAG 64 -#define TOGGLES_DEFAULT (SOUND_ADMINHELP|SOUND_MIDI|SOUND_AMBIENCE|SOUND_LOBBY|CHAT_OOC|CHAT_DEAD|CHAT_GHOSTEARS|CHAT_GHOSTSIGHT|CHAT_PRAYER|CHAT_RADIO|MEMBER_PUBLIC|CHAT_PULLR|INTENT_STYLE|CHAT_GHOSTWHISPER|MIDROUND_ANTAG|CHAT_GHOSTPDA) +#define TOGGLES_DEFAULT (SOUND_ADMINHELP|SOUND_MIDI|SOUND_AMBIENCE|SOUND_LOBBY|MEMBER_PUBLIC|INTENT_STYLE|MIDROUND_ANTAG) +//Chat toggles +#define CHAT_OOC 1 +#define CHAT_DEAD 2 +#define CHAT_GHOSTEARS 4 +#define CHAT_GHOSTSIGHT 8 +#define CHAT_PRAYER 16 +#define CHAT_RADIO 32 +#define CHAT_PULLR 64 +#define CHAT_GHOSTWHISPER 128 +#define CHAT_GHOSTPDA 256 +#define CHAT_GHOSTRADIO 512 + +#define TOGGLES_DEFAULT_CHAT (CHAT_OOC|CHAT_DEAD|CHAT_GHOSTEARS|CHAT_GHOSTSIGHT|CHAT_PRAYER|CHAT_RADIO|CHAT_PULLR|CHAT_GHOSTWHISPER|CHAT_GHOSTPDA|CHAT_GHOSTRADIO) + +//Antag toggles #define BE_TRAITOR 1 #define BE_OPERATIVE 2 #define BE_CHANGELING 4 diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index f3b61f94ba4..904dc495e06 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -798,7 +798,7 @@ Turf and target are seperate in case you want to teleport some distance from a t sleep(delayfraction) - if(!user || user.incapacitated() || !(user.loc == T)) + if(!user || user.stat || user.weakened || user.stunned || !(user.loc == T)) return 0 if(needhand) //Sometimes you don't want the user to have to keep their active hand diff --git a/code/_onclick/hud/alert.dm b/code/_onclick/hud/alert.dm index 5dffc0127b2..fbde37f1d94 100644 --- a/code/_onclick/hud/alert.dm +++ b/code/_onclick/hud/alert.dm @@ -76,7 +76,7 @@ alerts -= category if(client && hud_used) hud_used.reorganize_alerts() - client.screen -= alert + client.screen -= alert qdel(alert) // Make sure any alerts you throw have a path that matches /obj/screen/alert/[id] or /obj/screen/alert/[category] diff --git a/code/_onclick/hud/alien.dm b/code/_onclick/hud/alien.dm index 4f13c983594..a0422e05b91 100644 --- a/code/_onclick/hud/alien.dm +++ b/code/_onclick/hud/alien.dm @@ -106,7 +106,7 @@ mymob.pullin = new /obj/screen/pull() mymob.pullin.icon = 'icons/mob/screen_alien.dmi' - mymob.pullin.icon_state = "pull0" + mymob.pullin.update_icon(mymob) mymob.pullin.screen_loc = ui_pull_resist //begin indicators diff --git a/code/_onclick/hud/alien_larva.dm b/code/_onclick/hud/alien_larva.dm index 3f9ea8e37d6..ab395f371e1 100644 --- a/code/_onclick/hud/alien_larva.dm +++ b/code/_onclick/hud/alien_larva.dm @@ -29,7 +29,7 @@ mymob.pullin = new /obj/screen/pull() mymob.pullin.icon = 'icons/mob/screen_alien.dmi' - mymob.pullin.icon_state = "pull0" + mymob.pullin.update_icon(mymob) mymob.pullin.screen_loc = ui_pull_resist mymob.blind = new /obj/screen() diff --git a/code/_onclick/hud/drones.dm b/code/_onclick/hud/drones.dm index 086dc39c95a..63600d94053 100644 --- a/code/_onclick/hud/drones.dm +++ b/code/_onclick/hud/drones.dm @@ -11,7 +11,7 @@ mymob.pullin = new /obj/screen/pull() mymob.pullin.icon = ui_style - mymob.pullin.icon_state = "pull0" + mymob.pullin.update_icon(mymob) mymob.pullin.screen_loc = ui_drone_pull adding += mymob.pullin diff --git a/code/_onclick/hud/human.dm b/code/_onclick/hud/human.dm index 4d2ea2b32f0..18b4f72a13b 100644 --- a/code/_onclick/hud/human.dm +++ b/code/_onclick/hud/human.dm @@ -267,7 +267,7 @@ mymob.pullin = new /obj/screen/pull() mymob.pullin.icon = ui_style - mymob.pullin.icon_state = "pull0" + mymob.pullin.update_icon(mymob) mymob.pullin.screen_loc = ui_pull_resist hotkeybuttons += mymob.pullin diff --git a/code/_onclick/hud/monkey.dm b/code/_onclick/hud/monkey.dm index 3cd2871960c..c96e2556de9 100644 --- a/code/_onclick/hud/monkey.dm +++ b/code/_onclick/hud/monkey.dm @@ -96,7 +96,7 @@ mymob.pullin = new /obj/screen/pull() mymob.pullin.icon = ui_style - mymob.pullin.icon_state = "pull0" + mymob.pullin.update_icon(mymob) mymob.pullin.screen_loc = ui_pull_resist lingchemdisplay = new /obj/screen/ling/chems() diff --git a/code/_onclick/hud/robot.dm b/code/_onclick/hud/robot.dm index fe5b38db0ab..878efe59e65 100644 --- a/code/_onclick/hud/robot.dm +++ b/code/_onclick/hud/robot.dm @@ -127,7 +127,7 @@ mymob.pullin = new /obj/screen/pull() mymob.pullin.icon = 'icons/mob/screen_cyborg.dmi' - mymob.pullin.icon_state = "pull0" + mymob.pullin.update_icon(mymob) mymob.pullin.screen_loc = ui_borg_pull mymob.blind = new /obj/screen() diff --git a/code/_onclick/hud/screen_objects.dm b/code/_onclick/hud/screen_objects.dm index 0a289671a7a..856dce11be8 100644 --- a/code/_onclick/hud/screen_objects.dm +++ b/code/_onclick/hud/screen_objects.dm @@ -187,6 +187,13 @@ /obj/screen/pull/Click() usr.stop_pulling() +/obj/screen/pull/update_icon(mob/mymob) + if(!mymob) return + if(mymob.pulling) + icon_state = "pull" + else + icon_state = "pull0" + /obj/screen/resist name = "resist" icon = 'icons/mob/screen_midnight.dmi' diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm index 66422fdb659..6cc5abb7a18 100644 --- a/code/controllers/configuration.dm +++ b/code/controllers/configuration.dm @@ -103,6 +103,8 @@ var/continuous_round_wiz = 0 var/continuous_round_malf = 0 var/continuous_round_blob = 0 + var/midround_antag_time_check = 60 // How late (in minutes) you want the midround antag system to stay on, setting this to 0 will disable the system + var/midround_antag_life_check = 0.7 // A ratio of how many people need to be alive in order for the round not to immediately end in midround antagonist var/shuttle_refuel_delay = 12000 var/show_game_type_odds = 0 //if set this allows players to see the odds of each roundtype on the get revision screen var/mutant_races = 0 //players can choose their mutant race before joining the game @@ -401,6 +403,10 @@ config.continuous_round_malf = 1 if("continuous_round_blob") config.continuous_round_blob = 1 + if("midround_antag_time_check") + config.midround_antag_time_check = text2num(value) + if("midround_antag_life_check") + config.midround_antag_life_check = text2num(value) if("shuttle_refuel_delay") config.shuttle_refuel_delay = text2num(value) if("show_game_type_odds") diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm index da53d767a22..9f9ecf422a8 100644 --- a/code/controllers/subsystem/ticker.dm +++ b/code/controllers/subsystem/ticker.dm @@ -9,6 +9,7 @@ var/datum/subsystem/ticker/ticker var/restart_timeout = 250 //delay when restarting server var/current_state = GAME_STATE_STARTUP //state of current round (used by process()) Use the defines GAME_STATE_* ! + var/force_ending = 0 //Round was ended by admin intervention var/hide_mode = 0 var/datum/game_mode/mode = null @@ -91,7 +92,7 @@ var/datum/subsystem/ticker/ticker if(GAME_STATE_PLAYING) mode.process(wait * 0.1) - if(!mode.explosion_in_progress && mode.check_finished()) + if(!mode.explosion_in_progress && mode.check_finished() || force_ending) current_state = GAME_STATE_FINISHED auto_toggle_ooc(1) // Turn it on declare_completion() diff --git a/code/datums/goon_mutations_disabilities.dm b/code/datums/goon_mutations_disabilities.dm index 44555ce8c4b..5dfa25597c0 100644 --- a/code/datums/goon_mutations_disabilities.dm +++ b/code/datums/goon_mutations_disabilities.dm @@ -12,8 +12,8 @@ /datum/mutation/human/mute name = "Mute" quality = NEGATIVE - text_gain_indication = "You feel unable to express yourself at all." - text_lose_indication = "You feel able to speak freely again." + text_gain_indication = "You feel unable to express yourself at all." + text_lose_indication = "You feel able to speak freely again." /datum/mutation/human/mute/on_acquiring(mob/living/carbon/human/owner) if(..()) return @@ -81,8 +81,8 @@ /datum/mutation/human/unintelligable name = "Unintelligable" quality = NEGATIVE - text_gain_indication = "You can't seem to form any coherent thoughts!" - text_lose_indication = "Your mind feels more clear." + text_gain_indication = "You can't seem to form any coherent thoughts!" + text_lose_indication = "Your mind feels more clear." /datum/mutation/human/unintelligable/say_mod(var/message) if(message) diff --git a/code/datums/mutations.dm b/code/datums/mutations.dm index 566adcedc03..8e3b2a80fe6 100644 --- a/code/datums/mutations.dm +++ b/code/datums/mutations.dm @@ -215,6 +215,7 @@ text_gain_indication = "You feel strange." /datum/mutation/human/bad_dna/on_acquiring(var/mob/living/carbon/human/owner) + owner << text_gain_indication var/mob/new_mob if(prob(95)) if(prob(50)) diff --git a/code/datums/spells/barnyard.dm b/code/datums/spells/barnyard.dm new file mode 100644 index 00000000000..7b62eb90a81 --- /dev/null +++ b/code/datums/spells/barnyard.dm @@ -0,0 +1,42 @@ +/obj/effect/proc_holder/spell/targeted/barnyardcurse + name = "Curse of the Barnyard" + desc = "This spell dooms the fate of any unlucky soul to the speech and facial attributes of a barnyard animal" + school = "transmutation" + charge_type = "recharge" + charge_max = 150 + charge_counter = 0 + clothes_req = 0 + stat_allowed = 0 + invocation = "KN'A FTAGHU, PUCK 'BTHNK!" + invocation_type = "shout" + range = 7 + cooldown_min = 30 + selection_type = "range" + var/list/compatible_mobs = list(/mob/living/carbon/human,/mob/living/carbon/monkey) + +/obj/effect/proc_holder/spell/targeted/barnyardcurse/cast(list/targets, mob/user = usr) + if(!targets.len) + user << "No target found in range." + return + + var/mob/living/carbon/target = targets[1] + + if(!(target.type in compatible_mobs)) + user << "You are unable to curse [target]'s head!" + return + + if(!(target in oview(range))) + user << "They are too far away!" + return + + var/choice = pick(/obj/item/clothing/mask/spig, /obj/item/clothing/mask/cowmask, /obj/item/clothing/mask/horsehead) + var/obj/item/clothing/mask/magichead = new choice + magichead.flags |=NODROP + magichead.flags_inv = null + target.visible_message("[target]'s face lights up in fire, and after the event a barnyard animal's head takes it's place!", \ + "Your face burns up, and shortly after the fire you realise you have the face of a barnyard animal!") + if(!target.unEquip(target.wear_mask)) + qdel(target.wear_mask) + target.equip_to_slot_if_possible(magichead, slot_wear_mask, 1, 1) + + flick("e_flash", target.flash) diff --git a/code/datums/spells/horsemask.dm b/code/datums/spells/horsemask.dm deleted file mode 100644 index 8be107d4d40..00000000000 --- a/code/datums/spells/horsemask.dm +++ /dev/null @@ -1,42 +0,0 @@ -/obj/effect/proc_holder/spell/targeted/horsemask - name = "Curse of the Horseman" - desc = "This spell triggers a curse on a target, causing them to wield an unremovable horse head mask. They will speak like a horse! Any masks they are wearing will be disintegrated. This spell does not require robes." - school = "transmutation" - charge_type = "recharge" - charge_max = 150 - charge_counter = 0 - clothes_req = 0 - stat_allowed = 0 - invocation = "KN'A FTAGHU, PUCK 'BTHNK!" - invocation_type = "shout" - range = 7 - cooldown_min = 30 //30 deciseconds reduction per rank - selection_type = "range" - var/list/compatible_mobs = list(/mob/living/carbon/human, /mob/living/carbon/monkey) - -/obj/effect/proc_holder/spell/targeted/horsemask/cast(list/targets, mob/user = usr) - if(!targets.len) - user << "No target found in range." - return - - var/mob/living/carbon/target = targets[1] - - if(!(target.type in compatible_mobs)) - user << "It'd be stupid to curse [target] with a horse's head!" - return - - if(!(target in oview(range)))//If they are not in overview after selection. - user << "They are too far away!" - return - - var/obj/item/clothing/mask/horsehead/magichead = new /obj/item/clothing/mask/horsehead - magichead.flags |= NODROP //curses! - magichead.flags_inv = null //so you can still see their face - magichead.voicechange = 1 //NEEEEIIGHH - target.visible_message( "[target]'s face lights up in fire, and after the event a horse's head takes its place!", \ - "Your face burns up, and shortly after the fire you realise you have the face of a horse!") - if(!target.unEquip(target.wear_mask)) - qdel(target.wear_mask) - target.equip_to_slot_if_possible(magichead, slot_wear_mask, 1, 1) - - flick("e_flash", target.flash) diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index 45baa224943..b50eebcb180 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -117,7 +117,7 @@ if(pulledby) return 1 - if(locate(/obj/structure/lattice) in orange(1, get_turf(src))) //Not realistic but makes pushing things in space easier + if(locate(/obj/structure/lattice) in range(1, get_turf(src))) //Not realistic but makes pushing things in space easier return 1 return 0 diff --git a/code/game/gamemodes/blob/blob_finish.dm b/code/game/gamemodes/blob/blob_finish.dm index d3e0d49933e..32073430a46 100644 --- a/code/game/gamemodes/blob/blob_finish.dm +++ b/code/game/gamemodes/blob/blob_finish.dm @@ -22,6 +22,8 @@ /datum/game_mode/blob/declare_completion() + if(round_converted) //So badmin blobs later don't step on the dead natural blobs metaphorical toes + ..() if(blobwincount <= blobs.len) feedback_set_details("round_end_result","win - blob took over") world << "The blob has taken over the station!" diff --git a/code/game/gamemodes/changeling/powers/fleshmend.dm b/code/game/gamemodes/changeling/powers/fleshmend.dm index d450fd61899..c19fbc6dbbe 100644 --- a/code/game/gamemodes/changeling/powers/fleshmend.dm +++ b/code/game/gamemodes/changeling/powers/fleshmend.dm @@ -13,6 +13,8 @@ if(ishuman(user)) var/mob/living/carbon/human/H = user H.restore_blood() + H.remove_all_embedded_objects() + for(var/i = 0, i<10,i++) user.adjustBruteLoss(-10) user.adjustOxyLoss(-10) diff --git a/code/game/gamemodes/changeling/powers/mutations.dm b/code/game/gamemodes/changeling/powers/mutations.dm index 98d0a0f18c6..eb77d14ef3d 100644 --- a/code/game/gamemodes/changeling/powers/mutations.dm +++ b/code/game/gamemodes/changeling/powers/mutations.dm @@ -224,9 +224,6 @@ remaining_uses-- return 1 -/obj/item/weapon/shield/changeling/IsReflect() - return 0 - /***************************************\ |*********SPACE SUIT + HELMET***********| diff --git a/code/game/gamemodes/changeling/powers/revive.dm b/code/game/gamemodes/changeling/powers/revive.dm index 35fa9f3463b..0acb082e057 100644 --- a/code/game/gamemodes/changeling/powers/revive.dm +++ b/code/game/gamemodes/changeling/powers/revive.dm @@ -23,6 +23,7 @@ if(ishuman(user)) var/mob/living/carbon/human/H = user H.restore_blood() + H.remove_all_embedded_objects() user << "We have regenerated." user.status_flags &= ~(FAKEDEATH) diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm index 04fa08b5a57..795beb6fdf2 100644 --- a/code/game/gamemodes/game_mode.dm +++ b/code/game/gamemodes/game_mode.dm @@ -29,7 +29,8 @@ var/pre_setup_before_jobs = 0 var/antag_flag = null //preferences flag such as BE_WIZARD that need to be turned on for players to be antag var/datum/mind/sacrifice_target = null - var/round_converted = 0 + var/list/datum/game_mode/replacementmode = null + var/round_converted = 0 //0: round not converted, 1: round going to convert, 2: round converted var/reroll_friendly //During mode conversion only these are in the running var/enemy_minimum_age = 7 //How many days must players have been playing before they can play this antagonist @@ -89,6 +90,8 @@ ///make_antag_chance() ///Handles late-join antag assignments /datum/game_mode/proc/make_antag_chance(var/mob/living/carbon/human/character) + if(replacementmode && round_converted == 2) + replacementmode.make_antag_chance(character) return ///convert_roundtype() @@ -102,7 +105,7 @@ if(!runnable_modes) return 0 - var/list/datum/game_mode/replacementmode = pickweight(runnable_modes) + replacementmode = pickweight(runnable_modes) switch(SSshuttle.emergency.mode) //Rounds on the verge of ending don't get new antags, they just run out if(SHUTTLE_STRANDED, SHUTTLE_ESCAPE) @@ -111,12 +114,15 @@ if(SSshuttle.emergency.timeLeft(1) < initial(SSshuttle.emergencyCallTime)*0.5) return 1 + if(world.time >= (config.midround_antag_time_check * 600)) + return 0 + var/living_crew = 0 for(var/mob/Player in mob_list) if(Player.mind && Player.stat != DEAD && !isnewplayer(Player) &&!isbrain(Player)) living_crew++ - if(living_crew / joined_player_list.len <= 0.7) //If a lot of the player base died, we start fresh + if(living_crew / joined_player_list.len <= config.midround_antag_life_check) //If a lot of the player base died, we start fresh return 0 var/list/antag_canadates = list() @@ -126,8 +132,7 @@ antag_canadates += H if(!antag_canadates) - message_admins("The roundtype has been converted, antagonists may have been created") - return 1 + return 0 antag_canadates = shuffle(antag_canadates) @@ -136,10 +141,12 @@ if(config.protect_assistant_from_antagonist) replacementmode.restricted_jobs += "Assistant" + message_admins("The roundtype will be converted. If you feel that the round should not continue, end the round now.") + spawn(rand(1800,4200)) //somewhere between 3 and 7 minutes from now for(var/mob/living/carbon/human/H in antag_canadates) replacementmode.make_antag_chance(H) - + round_converted = 2 message_admins("The roundtype has been converted, antagonists may have been created") return 1 diff --git a/code/game/gamemodes/malfunction/malfunction.dm b/code/game/gamemodes/malfunction/malfunction.dm index 1e2e53f7661..8c6a2ef27eb 100644 --- a/code/game/gamemodes/malfunction/malfunction.dm +++ b/code/game/gamemodes/malfunction/malfunction.dm @@ -144,6 +144,8 @@ /datum/game_mode/malfunction/check_finished() + if(round_converted) + return ..() if (station_captured && !to_nuke_or_not_to_nuke) return 1 if (is_malf_ai_dead()) diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm index 730462ddfff..23d485f84a2 100644 --- a/code/game/gamemodes/objective.dm +++ b/code/game/gamemodes/objective.dm @@ -426,21 +426,30 @@ datum/objective/download/proc/gen_amount_goal() explanation_text = "Download [target_amount] research level\s." return target_amount -datum/objective/download/check_completion() +datum/objective/download/check_completion()//NINJACODE if(!ishuman(owner.current)) return 0 - if(!owner.current || owner.current.stat == 2) + + var/mob/living/carbon/human/H = owner.current + if(!H || H.stat == DEAD) return 0 - if(!(istype(owner.current:wear_suit, /obj/item/clothing/suit/space/space_ninja)&&owner.current:wear_suit:s_initialized)) + + if(!istype(H.wear_suit, /obj/item/clothing/suit/space/space_ninja)) return 0 + + var/obj/item/clothing/suit/space/space_ninja/SN = H.wear_suit + if(!SN.s_initialized) + return 0 + var/current_amount - var/obj/item/clothing/suit/space/space_ninja/S = owner.current:wear_suit - if(!S.stored_research.len) + if(!SN.stored_research.len) return 0 else - for(var/datum/tech/current_data in S.stored_research) - if(current_data.level>1) current_amount+=(current_data.level-1) - if(current_amountYou're knocked down!" user.Weaken(20) -/obj/item/weapon/spellbook/oneuse/horsemask - spell = /obj/effect/proc_holder/spell/targeted/horsemask - spellname = "horses" +/obj/item/weapon/spellbook/oneuse/barnyard + spell = /obj/effect/proc_holder/spell/targeted/barnyardcurse + spellname = "barnyard" icon_state ="bookhorses" desc = "This book is more horse than your mind has room for." -/obj/item/weapon/spellbook/oneuse/horsemask/recoil(mob/living/carbon/user as mob) +/obj/item/weapon/spellbook/oneuse/barnyard/recoil(mob/living/carbon/user as mob) if(istype(user, /mob/living/carbon/human)) user <<"HOR-SIE HAS RISEN" var/obj/item/clothing/mask/horsehead/magichead = new /obj/item/clothing/mask/horsehead @@ -578,7 +578,7 @@ user.equip_to_slot_if_possible(magichead, slot_wear_mask, 1, 1) qdel(src) else - user <<"I say thee neigh" + user <<"I say thee neigh" //It still lives here /obj/item/weapon/spellbook/oneuse/charge spell = /obj/effect/proc_holder/spell/targeted/charge diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm index 8a8b1836eae..30b3f246671 100644 --- a/code/game/machinery/camera/camera.dm +++ b/code/game/machinery/camera/camera.dm @@ -214,15 +214,6 @@ user << "Camera bugged." src.bug = W src.bug.bugged_cameras[src.c_tag] = src - else if(istype(W, /obj/item/weapon/melee/energy/blade))//Putting it here last since it's a special case. I wonder if there is a better way to do these than type casting. - deactivate(user,2)//Here so that you can disconnect anyone viewing the camera, regardless if it's on or off. - var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread() - spark_system.set_up(5, 0, loc) - spark_system.start() - playsound(loc, 'sound/weapons/blade1.ogg', 50, 1) - playsound(loc, "sparks", 50, 1) - visible_message("[user] has sliced the camera apart with an energy blade!") - qdel(src) else if(istype(W, /obj/item/device/laser_pointer)) var/obj/item/device/laser_pointer/L = W L.laser_act(src, user) diff --git a/code/game/machinery/camera/tracking.dm b/code/game/machinery/camera/tracking.dm index d672301e750..3e0dac86a35 100644 --- a/code/game/machinery/camera/tracking.dm +++ b/code/game/machinery/camera/tracking.dm @@ -73,8 +73,11 @@ //Cameras can't track people wearing an agent card or a ninja hood. if(H.wear_id && istype(H.wear_id.GetID(), /obj/item/weapon/card/id/syndicate)) continue - if(istype(H.head, /obj/item/clothing/head/helmet/space/space_ninja) && (H.head.flags & NODROP)) - continue + //Generic variable who's existance is to blame on shitty old ninja code + if(istype(H.head, /obj/item/clothing/head)) + var/obj/item/clothing/head/hat = H.head + if(hat.blockTracking) + continue // Now, are they viewable by a camera? (This is last because it's the most intensive check) if(!near_camera(M)) @@ -127,10 +130,12 @@ U << "Follow camera mode terminated." U.cameraFollow = null return - if(istype(H.head, /obj/item/clothing/head/helmet/space/space_ninja) && (H.head.flags & NODROP)) - U << "Follow camera mode terminated." - U.cameraFollow = null - return + if(istype(H.head, /obj/item/clothing/head)) + var/obj/item/clothing/head/hat = H.head + if(hat.blockTracking) + U << "Follow camera mode terminated." + U.cameraFollow = null + return if(H.digitalcamo) U << "Follow camera mode terminated." U.cameraFollow = null diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index ade7ad34aa9..aa7e40ee737 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -1028,11 +1028,11 @@ About the new airlock wires panel: if( !hasPower() || isWireCut(AIRLOCK_WIRE_DOOR_BOLTS) ) return if(safe) - if(locate(/mob/living) in get_turf(src)) - // playsound(src.loc, 'sound/machines/buzz-two.ogg', 50, 0) //THE BUZZING IT NEVER STOPS -Pete - spawn (60) - autoclose() - return + for(var/atom/movable/M in get_turf(src)) + if(M.density && M != src) //something is blocking the door + spawn (60) + autoclose() + return if(forced < 2) if(emagged) diff --git a/code/game/machinery/doors/brigdoors.dm b/code/game/machinery/doors/brigdoors.dm index f3bee16d85f..f91fb5a6ddf 100644 --- a/code/game/machinery/doors/brigdoors.dm +++ b/code/game/machinery/doors/brigdoors.dm @@ -251,48 +251,6 @@ if(maptext != new_text) maptext = new_text - -/obj/machinery/door_timer/cell_1 - name = "Cell 1" - id = "Cell 1" - dir = 2 - pixel_y = -32 - - -/obj/machinery/door_timer/cell_2 - name = "Cell 2" - id = "Cell 2" - dir = 2 - pixel_y = -32 - - -/obj/machinery/door_timer/cell_3 - name = "Cell 3" - id = "Cell 3" - dir = 2 - pixel_y = -32 - - -/obj/machinery/door_timer/cell_4 - name = "Cell 4" - id = "Cell 4" - dir = 2 - pixel_y = -32 - - -/obj/machinery/door_timer/cell_5 - name = "Cell 5" - id = "Cell 5" - dir = 2 - pixel_y = -32 - - -/obj/machinery/door_timer/cell_6 - name = "Cell 6" - id = "Cell 6" - dir = 4 - pixel_x = 32 - #undef FONT_SIZE #undef FONT_COLOR #undef FONT_STYLE diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm index 6bfaf23190a..86434159b81 100644 --- a/code/game/machinery/doors/door.dm +++ b/code/game/machinery/doors/door.dm @@ -265,6 +265,8 @@ var/turf/location = src.loc if(istype(location, /turf/simulated)) //add_blood doesn't work for borgs/xenos, but add_blood_floor does. location.add_blood_floor(L) + for(var/obj/mecha/M in get_turf(src)) + M.take_damage(DOOR_CRUSH_DAMAGE) /obj/machinery/door/proc/requiresID() return 1 diff --git a/code/game/machinery/doors/unpowered.dm b/code/game/machinery/doors/unpowered.dm index c0da7ec0dba..df94284c2c5 100644 --- a/code/game/machinery/doors/unpowered.dm +++ b/code/game/machinery/doors/unpowered.dm @@ -9,7 +9,6 @@ /obj/machinery/door/unpowered/attackby(obj/item/I as obj, mob/user as mob, params) - if(istype(I, /obj/item/weapon/melee/energy/blade)) return if(src.locked) return ..() return diff --git a/code/game/machinery/doors/windowdoor.dm b/code/game/machinery/doors/windowdoor.dm index d9a02cecbfa..88c3cad51e1 100644 --- a/code/game/machinery/doors/windowdoor.dm +++ b/code/game/machinery/doors/windowdoor.dm @@ -262,22 +262,6 @@ add_fingerprint(user) - //ninja sword garbage - if (src.density && istype(I, /obj/item/weapon/melee/energy/blade)) - src.operating = -1 - flick("[src.base_state]spark", src) - sleep(6) - desc += "
Its access panel is smoking slightly." - var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread() - spark_system.set_up(5, 0, src.loc) - spark_system.start() - playsound(src.loc, "sparks", 50, 1) - playsound(src.loc, 'sound/weapons/blade1.ogg', 50, 1) - visible_message(" The glass door was sliced open by [user]!") - open(2) - emagged = 1 - return 1 - if(istype(I, /obj/item/weapon/screwdriver)) if(src.density || src.operating) user << "You need to open the door to access the maintenance panel." diff --git a/code/game/machinery/portable_turret.dm b/code/game/machinery/portable_turret.dm index 948e11e1eff..61fb96edcb0 100644 --- a/code/game/machinery/portable_turret.dm +++ b/code/game/machinery/portable_turret.dm @@ -51,6 +51,8 @@ var/shot_sound //what sound should play when the turret fires var/eshot_sound //what sound should play when the emagged turret fires + var/faction = "neutral" + var/datum/effect/effect/system/spark_spread/spark_system //the spark system, used for generating... sparks? /obj/machinery/porta_turret/New() @@ -410,62 +412,49 @@ return var/list/targets = list() //list of primary targets - var/list/secondarytargets = list() //targets that are least important + var/turretview = view(7, src) - if(check_anomalies) //if its set to check for xenos/carps, check for non-mob "crittersssss"(And simple_animals) - for(var/mob/living/simple_animal/C in view(7, src)) - if(!C.stat) + if(check_anomalies) //if it's set to check for xenos/simpleanimals + for(var/mob/living/simple_animal/SA in turretview) + if(!SA.stat && (!SA.has_unlimited_silicon_privilege || !(faction in SA.faction)) ) //don't target dead animals or NT maint drones. + targets += SA + + for(var/mob/living/carbon/C in turretview) //loops through all carbon-based lifeforms in view(7) + if(emagged && C.stat != DEAD) //if emagged, every living carbon is a target. + targets += C + continue + + if(C.stat || C.handcuffed || C.lying) //if the perp is handcuffed or lying or dead/dying, no need to bother really + continue + + if(ai) //If it's set to attack all nonsilicons, target them! + targets += C + continue + + if(istype(C, /mob/living/carbon/human)) //if the target is a human, analyze threat level + if(assess_perp(C) >= 4) targets += C - for(var/mob/living/carbon/C in view(7,src)) //loops through all living carbon-based lifeforms in view(12) - if(istype(C, /mob/living/carbon/alien) && check_anomalies) //git those fukken xenos - if(!C.stat) //if it's dead/dying, there's no need to keep shooting at it. - targets += C - - else - if(emagged) //if emagged, HOLY SHIT EVERYONE IS DANGEROUS beep boop beep - targets += C - else - if(C.stat || C.handcuffed) //if the perp is handcuffed or dead/dying, no need to bother really - continue //move onto next potential victim! - - var/dst = get_dist(src, C) //if it's too far away, why bother? - if(dst > 7) - continue - - if(ai) //If it's set to attack all nonsilicons, target them! - if(C.lying) - if(lasercolor) - continue - else - secondarytargets += C - continue - else + else if(check_anomalies) + if(!(faction in C.faction)) + for(var/F in C.faction) //We target carbons without the portaturret's faction and who also have alien or slime faction. + if(F == "alien" || F == "slime") targets += C - continue + break - if(istype(C, /mob/living/carbon/human)) //if the target is a human, analyze threat level - if(assess_perp(C) < 4) - continue //if threat level < 4, keep going - - else if(istype(C, /mob/living/carbon/monkey)) - continue //Don't target monkeys or borgs/AIs you dumb shit - - if(C.lying) //if the perp is lying down, it's still a target but a less-important target - secondarytargets += C - continue - - targets += C //if the perp has passed all previous tests, congrats, it is now a "shoot-me!" nominee + for(var/obj/mecha/M in turretview) + if(M.occupant) + if(ai || emagged) // we target all occupied mechs if we're emagged or set to attack all non silicons. + targets += M if(!tryToShootAt(targets)) - if(!tryToShootAt(secondarytargets)) // if no valid targets, go for secondary targets - spawn() - popDown() // no valid targets, close the cover + spawn() + popDown() // no valid targets, close the cover -/obj/machinery/porta_turret/proc/tryToShootAt(var/list/mob/living/targets) +/obj/machinery/porta_turret/proc/tryToShootAt(var/list/atom/movable/targets) while(targets.len > 0) - var/mob/living/M = pick(targets) + var/atom/movable/M = pick(targets) targets -= M if(target(M)) return 1 @@ -558,10 +547,10 @@ return threatcount -/obj/machinery/porta_turret/proc/target(var/mob/living/target) +/obj/machinery/porta_turret/proc/target(var/atom/movable/target) if(disabled) return - if(target && (target.stat != DEAD) && (!(target.lying) || emagged)) + if(target) spawn() popUp() //pop the turret up if it's not already up. dir = get_dir(src, target) //even if you can't shoot, follow the target @@ -570,7 +559,7 @@ return 1 return -/obj/machinery/porta_turret/proc/shootAt(var/mob/living/target) +/obj/machinery/porta_turret/proc/shootAt(var/atom/movable/target) if(!emagged) //if it hasn't been emagged, it has to obey a cooldown rate if(last_fired || !raised) //prevents rapid-fire shooting, unless it's been emagged return diff --git a/code/game/machinery/telecomms/broadcaster.dm b/code/game/machinery/telecomms/broadcaster.dm index add0390729f..692d9c8951b 100644 --- a/code/game/machinery/telecomms/broadcaster.dm +++ b/code/game/machinery/telecomms/broadcaster.dm @@ -258,9 +258,13 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept var/list/receive = get_mobs_in_radio_ranges(radios) //this includes all hearers. for(var/mob/R in receive) //Filter receiver list. - if (R.client && !(R.client.prefs.toggles & CHAT_RADIO)) //Adminning with 80 people on can be fun when you're trying to talk and all you can hear is radios. + if (R.client && !(R.client.prefs.chat_toggles & CHAT_RADIO)) //Adminning with 80 people on can be fun when you're trying to talk and all you can hear is radios. receive -= R + for(var/mob/M in player_list) + if(isobserver(M) && M.client && (M.client.prefs.chat_toggles & CHAT_GHOSTRADIO)) + receive |= M + var/rendered = virt.compose_message(virt, virt.languages, message, freq) //Always call this on the virtualspeaker to advoid issues. for(var/atom/movable/hearer in receive) hearer.Hear(rendered, virt, AM.languages, message, freq) @@ -366,7 +370,7 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept /* --- Loop through the receivers and categorize them --- */ - if (R.client && !(R.client.prefs.toggles & CHAT_RADIO)) //Adminning with 80 people on can be fun when you're trying to talk and all you can hear is radios. + if (R.client && !(R.client.prefs.chat_toggles & CHAT_RADIO)) //Adminning with 80 people on can be fun when you're trying to talk and all you can hear is radios. continue diff --git a/code/game/machinery/vending.dm b/code/game/machinery/vending.dm index eb35481a9bc..baba1af6680 100644 --- a/code/game/machinery/vending.dm +++ b/code/game/machinery/vending.dm @@ -727,6 +727,20 @@ /obj/item/weapon/cartridge/janitor = 10,/obj/item/weapon/cartridge/signal/toxins = 10,/obj/item/device/pda/heads = 10, /obj/item/weapon/cartridge/captain = 3,/obj/item/weapon/cartridge/quartermaster = 10) +/obj/machinery/vending/liberationstation + name = "\improper Liberation Station" + desc = "An overwhelming amount of ancient patriotism washes over you just by looking at the machine." + icon_state = "liberationstation" + req_access_txt = "1" + product_slogans = "Liberation Station: Your one-stop shop for all things second ammendment!;Be a patriot today, pick up a gun!;Quality weapons for cheap prices!;Better dead than red!" + product_ads = "Float like an astronaut, sting like a bullet!;Express your second ammendment today!;Guns don't kill people, but you can!;Who needs responsibilities when you have guns?" + vend_reply = "Remember the name: Liberation Station!" + products = list(/obj/item/weapon/gun/projectile/automatic/pistol/deagle/gold = 2,/obj/item/weapon/gun/projectile/automatic/pistol/deagle/camo = 2, + /obj/item/weapon/gun/projectile/automatic/pistol/m1911 = 2,/obj/item/weapon/gun/projectile/automatic/proto = 2, + /obj/item/weapon/gun/projectile/shotgun/combat = 2,/obj/item/weapon/gun/projectile/automatic/gyropistol = 1, + /obj/item/weapon/gun/projectile/shotgun = 2) + premium = list(/obj/item/ammo_box/magazine/smgm9mm = 2,/obj/item/ammo_box/magazine/m50 = 4,/obj/item/ammo_box/magazine/m45 = 2,/obj/item/ammo_box/magazine/m75 = 2) + contraband = list(/obj/item/clothing/under/patriotsuit = 1,/obj/item/weapon/bedsheet/patriot = 3) /obj/machinery/vending/cigarette name = "\improper ShadyCigs Deluxe" diff --git a/code/game/objects/explosion.dm b/code/game/objects/explosion.dm index 3a68df046f1..902fccd1660 100644 --- a/code/game/objects/explosion.dm +++ b/code/game/objects/explosion.dm @@ -113,7 +113,9 @@ proc/explosion(turf/epicenter, devastation_range, heavy_impact_range, light_impa spawn(0) //Simultaneously not one at a time var/throw_range = rand(throw_dist, max_range) var/turf/throw_at = get_ranged_target_turf(I, throw_dir, throw_range) - I.throw_at(throw_at, throw_range,1) + I.throw_speed = 4 //Temporarily change their throw_speed for embedding purposes (Reset when it finishes throwing, regardless of hitting anything) + I.throw_at(throw_at, throw_range, 2)//Throw it at 2 speed, this is purely visual anyway. + var/took = (world.timeofday-start)/10 //You need to press the DebugGame verb to see these now....they were getting annoying and we've collected a fair bit of data. Just -test- changes to explosion code using this please so we can compare diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index cf8461e8b75..6786b641c53 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -4,6 +4,10 @@ var/item_state = null var/lefthand_file = 'icons/mob/inhands/items_lefthand.dmi' var/righthand_file = 'icons/mob/inhands/items_righthand.dmi' + + //Not on /clothing because for some reason any /obj/item can technically be "worn" with enough fuckery. + var/icon/alternate_worn_icon = null//If this is set, update_icons() will find on mob (WORN, NOT INHANDS) states in this file instead, primary use: badminnery/events + var/hitsound = null var/throwhitsound = null var/w_class = 3.0 @@ -33,7 +37,6 @@ var/list/armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0) var/list/allowed = null //suit storage stuff. var/obj/item/device/uplink/hidden/hidden_uplink = null // All items can have an uplink hidden inside, just remember to add the triggers. - var/reflect_chance = 0 //This var dictates what % of a time an object will reflect an energy based weapon's shot var/strip_delay = 40 var/put_on_delay = 20 var/m_amt = 0 // metal @@ -48,9 +51,15 @@ var/hooded = 0 //So items can have custom embedd values + //Because customisation is king var/embed_chance = EMBED_CHANCE var/embedded_fall_chance = EMBEDDED_ITEM_FALLOUT var/embedded_pain_chance = EMBEDDED_PAIN_CHANCE + var/embedded_pain_multiplier = EMBEDDED_PAIN_MULTIPLIER //The coefficient of multiplication for the damage this item does while embedded (this*w_class) + var/embedded_fall_pain_multiplier = EMBEDDED_FALL_PAIN_MULTIPLIER //The coefficient of multiplication for the damage this item does when falling out of a limb (this*w_class) + var/embedded_impact_pain_multiplier = EMBEDDED_IMPACT_PAIN_MULTIPLIER //The coefficient of multiplication for the damage this item does when first embedded (this*w_class) + var/embedded_unsafe_removal_pain_multiplier = EMBEDDED_UNSAFE_REMOVAL_PAIN_MULTIPLIER //The coefficient of multiplication for the damage removing this without surgery causes (this*w_class) + var/embedded_unsafe_removal_time = EMBEDDED_UNSAFE_REMOVAL_TIME //A time in ticks, multiplied by the w_class. var/list/can_be_placed_into = list( /obj/structure/table, @@ -305,8 +314,7 @@ return 0 /obj/item/proc/IsReflect(var/def_zone) //This proc determines if and at what% an object will reflect energy projectiles if it's in l_hand,r_hand or wear_suit - if(prob(reflect_chance)) - return 1 + return 0 /obj/item/proc/eyestab(mob/living/carbon/M as mob, mob/living/carbon/user as mob) @@ -417,16 +425,19 @@ /obj/item/throw_impact(A) - if(istype(A, /mob/living/carbon/human)) - var/mob/living/carbon/human/H = A - if(can_embed(src)) - if(prob(embed_chance)) - var/obj/item/organ/limb/L = pick(H.organs) - L.embedded_objects |= src - add_blood(H)//it embedded itself in you, of course it's bloody! - loc = H - L.take_damage(w_class*5) - H.visible_message("\the [name] embeds itself in [H]'s [L.getDisplayName()]!","\the [name] embeds itself in your [L.getDisplayName()]!") - return + if(throw_speed >= EMBED_THROWSPEED_THRESHOLD) + if(istype(A, /mob/living/carbon/human)) + var/mob/living/carbon/human/H = A + if(can_embed(src)) + if(prob(embed_chance)) + var/obj/item/organ/limb/L = pick(H.organs) + L.embedded_objects |= src + add_blood(H)//it embedded itself in you, of course it's bloody! + loc = H + L.take_damage(w_class*embedded_impact_pain_multiplier) + H.visible_message("\the [name] embeds itself in [H]'s [L.getDisplayName()]!","\the [name] embeds itself in your [L.getDisplayName()]!") + return + //Reset regardless of if we hit a human. + throw_speed = initial(throw_speed) //explosions change this. ..() diff --git a/code/game/objects/items/devices/PDA/PDA.dm b/code/game/objects/items/devices/PDA/PDA.dm index 846d42b7b3e..5bd70bf4391 100644 --- a/code/game/objects/items/devices/PDA/PDA.dm +++ b/code/game/objects/items/devices/PDA/PDA.dm @@ -809,15 +809,15 @@ var/global/list/obj/item/device/pda/PDAs = list() t = Gibberish(t, signal.data["compression"] + 50) if(useMS && useTC) // only send the message if it's stable - if(useTC != 2) // Does our recepient have a broadcaster on their level? - U << "ERROR: Cannot reach recepient." + if(useTC != 2) // Does our recipient have a broadcaster on their level? + U << "ERROR: Cannot reach recipient." return useMS.send_pda_message("[P.owner]","[owner]","[t]") tnote += "→ To [P.owner]:
[t]
" P.tnote += "← From [owner] ([ownjob]):
[t]
" for(var/mob/M in player_list) - if(isobserver(M) && M.client && (M.client.prefs.toggles & CHAT_GHOSTPDA)) + if(isobserver(M) && M.client && (M.client.prefs.chat_toggles & CHAT_GHOSTPDA)) M.show_message("PDA Message - [owner] -> [P.owner]: [t]") if (!P.silent) diff --git a/code/game/objects/items/weapons/flamethrower.dm b/code/game/objects/items/weapons/flamethrower.dm index 558844c688c..3a3e29af17d 100644 --- a/code/game/objects/items/weapons/flamethrower.dm +++ b/code/game/objects/items/weapons/flamethrower.dm @@ -157,6 +157,10 @@ update_icon() return +/obj/item/weapon/flamethrower/CheckParts() + weldtool = locate(/obj/item/weapon/weldingtool) in contents + igniter = locate(/obj/item/device/assembly/igniter) in contents + update_icon() //Called from turf.dm turf/dblclick /obj/item/weapon/flamethrower/proc/flame_turf(turflist) @@ -195,9 +199,11 @@ /obj/item/weapon/flamethrower/full/New(var/loc) ..() - weldtool = new /obj/item/weapon/weldingtool(src) + if(!weldtool) + weldtool = new /obj/item/weapon/weldingtool(src) weldtool.status = 0 - igniter = new /obj/item/device/assembly/igniter(src) + if(!igniter) + igniter = new /obj/item/device/assembly/igniter(src) igniter.secured = 0 status = 1 update_icon() @@ -205,4 +211,4 @@ /obj/item/weapon/flamethrower/full/tank/New(var/loc) ..() ptank = new /obj/item/weapon/tank/internals/plasma/full(src) - update_icon() \ No newline at end of file + update_icon() diff --git a/code/game/objects/items/weapons/manuals.dm b/code/game/objects/items/weapons/manuals.dm index b7d25927991..94a1afa043c 100644 --- a/code/game/objects/items/weapons/manuals.dm +++ b/code/game/objects/items/weapons/manuals.dm @@ -680,7 +680,10 @@

Basic ingredients preparation:

- Dough: Add an egg to 15 flour. Dough can be transformed by using your knife and rolling pin or by adding milk. All doughs can be microwaved.
+ Dough: 10u water + 15u flour for simple dough.
+ 15u egg yolk + 15u flour + 5u sugar for cake batter.
+ Doughs can be transformed by using a knife and rolling pin.
+ All doughs can be microwaved.
Bowl: Add water to it for soup preparation.
Meat: Microwave it, process it, slice it into microwavable cutlets with your knife, or use it raw.
Cheese: Add 5u universal enzyme (catalyst) to milk and soy milk to prepare cheese (sliceable) and tofu. diff --git a/code/game/objects/items/weapons/shields.dm b/code/game/objects/items/weapons/shields.dm index 2a9a15c156c..a8875117ade 100644 --- a/code/game/objects/items/weapons/shields.dm +++ b/code/game/objects/items/weapons/shields.dm @@ -70,7 +70,6 @@ w_class = 4 playsound(user, 'sound/weapons/saberon.ogg', 35, 1) user << "[src] is now active." - reflect_chance = 40 else force = 3 throwforce = 3 @@ -78,7 +77,6 @@ w_class = 1 playsound(user, 'sound/weapons/saberoff.ogg', 35, 1) user << "[src] can now be concealed." - reflect_chance = 0 add_fingerprint(user) /obj/item/weapon/shield/riot/tele diff --git a/code/game/objects/items/weapons/storage/bags.dm b/code/game/objects/items/weapons/storage/bags.dm index fa45ef40477..04f6af6e312 100644 --- a/code/game/objects/items/weapons/storage/bags.dm +++ b/code/game/objects/items/weapons/storage/bags.dm @@ -277,7 +277,7 @@ max_combined_w_class = 21 max_w_class = 3 w_class = 4 //Bigger than a book because physics - can_hold = list(/obj/item/weapon/book, /obj/item/weapon/spellbook) //No bibles, consistent with bookcase + can_hold = list(/obj/item/weapon/book, /obj/item/weapon/storage/book, /obj/item/weapon/spellbook) /* * Trays - Agouri diff --git a/code/game/objects/items/weapons/storage/lockbox.dm b/code/game/objects/items/weapons/storage/lockbox.dm index a8cbcbcb282..9b7d8f19952 100644 --- a/code/game/objects/items/weapons/storage/lockbox.dm +++ b/code/game/objects/items/weapons/storage/lockbox.dm @@ -35,18 +35,6 @@ else user << "Access Denied." return - else if(istype(W, /obj/item/weapon/melee/energy/blade) && !src.broken) - broken = 1 - locked = 0 - desc = "It appears to be broken." - icon_state = src.icon_broken - var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread() - spark_system.set_up(5, 0, src.loc) - spark_system.start() - playsound(src.loc, 'sound/weapons/blade1.ogg', 50, 1) - playsound(src.loc, "sparks", 50, 1) - visible_message("[user] has sliced open \the [src] with an energy blade!", "You hear metal being sliced and sparks flying.") - return if(!locked) ..() else diff --git a/code/game/objects/items/weapons/storage/secure.dm b/code/game/objects/items/weapons/storage/secure.dm index f39e702b365..a92d674a6e9 100644 --- a/code/game/objects/items/weapons/storage/secure.dm +++ b/code/game/objects/items/weapons/storage/secure.dm @@ -33,21 +33,6 @@ /obj/item/weapon/storage/secure/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(locked) - if (istype(W, /obj/item/weapon/melee/energy/blade) && !emagged) - emagged = 1 - src.overlays += image('icons/obj/storage.dmi', icon_sparking) - sleep(6) - src.overlays = null - overlays += image('icons/obj/storage.dmi', icon_locking) - locked = 0 - var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread() - spark_system.set_up(5, 0, src.loc) - spark_system.start() - playsound(src.loc, 'sound/weapons/blade1.ogg', 50, 1) - playsound(src.loc, "sparks", 50, 1) - user << "You slice through the lock on [src]." - return - if (istype(W, /obj/item/weapon/screwdriver)) if (do_after(user, 20)) src.open =! src.open diff --git a/code/game/objects/items/weapons/tanks/tank_types.dm b/code/game/objects/items/weapons/tanks/tank_types.dm index 870e0115d75..d8934a1372f 100644 --- a/code/game/objects/items/weapons/tanks/tank_types.dm +++ b/code/game/objects/items/weapons/tanks/tank_types.dm @@ -96,6 +96,7 @@ F.ptank = src user.unEquip(src) src.loc = F + F.update_icon() return /obj/item/weapon/tank/internals/plasma/full/New() diff --git a/code/game/objects/items/weapons/tools.dm b/code/game/objects/items/weapons/tools.dm index fe4713a37c5..e4266c752f0 100644 --- a/code/game/objects/items/weapons/tools.dm +++ b/code/game/objects/items/weapons/tools.dm @@ -308,6 +308,7 @@ //Toggles the welder off and on /obj/item/weapon/weldingtool/proc/toggle(mob/user, message = 0) if(!status) + user << "[src] can't be turned on while unsecured." return welding = !welding if(welding) diff --git a/code/game/objects/items/weapons/twohanded.dm b/code/game/objects/items/weapons/twohanded.dm index 67acf259eae..32349ddb581 100644 --- a/code/game/objects/items/weapons/twohanded.dm +++ b/code/game/objects/items/weapons/twohanded.dm @@ -192,7 +192,6 @@ obj/item/weapon/twohanded/ item_color = "green" attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") var/hacked = 0 - reflect_chance = 0 /obj/item/weapon/twohanded/dualsaber/New() item_color = pick("red", "blue", "green", "purple") @@ -234,7 +233,7 @@ obj/item/weapon/twohanded/ user << "You cant pick up such dangerous item with your meaty hands without losing fingers, better not to." return 1 -/obj/item/weapon/twohanded/dualsaber/wield(mob/living/carbon/M) //Specific wield () hulk checks due to reflect_chance var for balance issues and switches hitsounds. +/obj/item/weapon/twohanded/dualsaber/wield(mob/living/carbon/M) //Specific wield () hulk checks due to reflection chance for balance issues and switches hitsounds. if(istype(M)) if(M.dna.check_mutation(HULK)) M << "You lack the grace to wield this." @@ -279,9 +278,10 @@ obj/item/weapon/twohanded/ w_class = 4.0 slot_flags = SLOT_BACK force_unwielded = 10 - force_wielded = 18 // Was 13, Buffed - RR + force_wielded = 18 throwforce = 20 - throw_speed = 3 + throw_speed = 4 + embedded_impact_pain_multiplier = 3 flags = NOSHIELD hitsound = 'sound/weapons/bladeslice.ogg' attack_verb = list("attacked", "poked", "jabbed", "torn", "gored") diff --git a/code/game/objects/items/weapons/weaponry.dm b/code/game/objects/items/weapons/weaponry.dm index ce19b97d11a..3d9068d8b53 100644 --- a/code/game/objects/items/weapons/weaponry.dm +++ b/code/game/objects/items/weapons/weaponry.dm @@ -138,11 +138,15 @@ obj/item/weapon/wirerod/attackby(var/obj/item/I, mob/user as mob, params) icon_state = "throwingstar" item_state = "eshield0" force = 2 - throwforce = 20 + throwforce = 0 //This is never used since this has a 100% embed chance. + throw_speed = 4 + embedded_pain_multiplier = 4 w_class = 2 embed_chance = 100 embedded_fall_chance = 0 //Hahaha! +//5*(2*4) = 5*8 = 45, 45 damage if you hit one person with all 5 stars. +//Not counting the damage it will do while embedded (2*4 = 8, at 15% chance) /obj/item/weapon/storage/box/throwing_stars/New() ..() contents = list() @@ -150,4 +154,8 @@ obj/item/weapon/wirerod/attackby(var/obj/item/I, mob/user as mob, params) new /obj/item/weapon/throwing_star(src) new /obj/item/weapon/throwing_star(src) new /obj/item/weapon/throwing_star(src) - new /obj/item/weapon/throwing_star(src) + new /obj/item/weapon/throwing_star(src) + + + + diff --git a/code/game/objects/structures/bedsheet_bin.dm b/code/game/objects/structures/bedsheet_bin.dm index 390b29acc5b..a671823fdf2 100644 --- a/code/game/objects/structures/bedsheet_bin.dm +++ b/code/game/objects/structures/bedsheet_bin.dm @@ -55,6 +55,12 @@ LINEN BINS icon_state = "sheetpurple" item_color = "purple" +/obj/item/weapon/bedsheet/patriot + name = "patriotic bedsheet" + desc = "You've never felt more free than when sleeping on this." + icon_state = "sheetUSA" + item_color = "sheetUSA" + /obj/item/weapon/bedsheet/rainbow name = "rainbow bedsheet" desc = "A multicolored blanket. It's actually several different sheets cut up and sewn together." diff --git a/code/game/objects/structures/crates_lockers/closets/secure/secure_closets.dm b/code/game/objects/structures/crates_lockers/closets/secure/secure_closets.dm index c117504b4ea..4c9095fb4df 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/secure_closets.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/secure_closets.dm @@ -65,18 +65,6 @@ if(!src.opened && src.broken) user << "The locker appears to be broken." return - else if(istype(W, /obj/item/weapon/melee/energy/blade) && !broken) - broken = 1 - locked = 0 - desc = "It appears to be broken." - icon_state = icon_off - flick(icon_broken, src) - var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread() - spark_system.set_up(5, 0, src.loc) - spark_system.start() - playsound(src.loc, 'sound/weapons/blade1.ogg', 50, 1) - playsound(src.loc, "sparks", 50, 1) - visible_message("[user] has sliced the locker open with an energy blade!", "You hear metal being sliced and sparks flying.") else ..(W, user) diff --git a/code/game/objects/structures/crates_lockers/crates.dm b/code/game/objects/structures/crates_lockers/crates.dm index f6aa7b779b2..f64395b7f24 100644 --- a/code/game/objects/structures/crates_lockers/crates.dm +++ b/code/game/objects/structures/crates_lockers/crates.dm @@ -307,17 +307,6 @@ overlays += redlight add_fingerprint(user) return - else if (istype(W, /obj/item/weapon/melee/energy/blade) && locked && !broken) - overlays.Cut() - overlays += emag - overlays += sparks - spawn(6) overlays -= sparks //Tried lots of stuff but nothing works right. so i have to use this *sadface* - playsound(src.loc, "sparks", 60, 1) - src.locked = 0 - src.broken = 1 - user << "You unlock \the [src]." - add_fingerprint(user) - return return ..() diff --git a/code/game/objects/structures/false_walls.dm b/code/game/objects/structures/false_walls.dm index a1ff1406751..ee5684c24c6 100644 --- a/code/game/objects/structures/false_walls.dm +++ b/code/game/objects/structures/false_walls.dm @@ -118,16 +118,15 @@ else user << "You can't reach, close it first!" - if(istype(W, /obj/item/weapon/pickaxe/plasmacutter) || istype(W, /obj/item/weapon/melee/energy/blade)) + if(istype(W, /obj/item/weapon/pickaxe/plasmacutter)) dismantle(user) if(istype(W, /obj/item/weapon/pickaxe/drill/jackhammer)) var/obj/item/weapon/pickaxe/drill/jackhammer/D = W if(!D.bcell.use(300)) - user << "Your jackhammer doesn't have enough power to break through that wall." - D.update_charge() + user << "Your [D.name] doesn't have enough power to break through the [name]." return - D.update_charge() + D.update_icon() D.playDigSound() dismantle(user) diff --git a/code/game/objects/structures/girders.dm b/code/game/objects/structures/girders.dm index e674b20fad5..1b26e4e5410 100644 --- a/code/game/objects/structures/girders.dm +++ b/code/game/objects/structures/girders.dm @@ -45,9 +45,9 @@ else if(istype(W, /obj/item/weapon/pickaxe/drill/jackhammer)) var/obj/item/weapon/pickaxe/drill/jackhammer/D = W if(!D.bcell.use(D.drillcost)) - D.update_charge() + user << "Your [D.name] doesn't have enough power to break through the [name]." return - D.update_charge() + D.update_icon() user << "You smash through the girder!" new /obj/item/stack/sheet/metal(get_turf(src)) D.playDigSound() @@ -292,9 +292,8 @@ else if(istype(W, /obj/item/weapon/pickaxe/drill/jackhammer)) var/obj/item/weapon/pickaxe/drill/jackhammer/D = W if(!D.bcell.use(D.drillcost)) - D.update_charge() return - D.update_charge() + D.update_icon() user << "Your jackhammer smashes through the girder!" var/obj/effect/decal/remains/human/R = new (get_turf(src)) transfer_fingerprints_to(R) diff --git a/code/game/objects/structures/janicart.dm b/code/game/objects/structures/janicart.dm index 34a68cee94c..3de876924ca 100644 --- a/code/game/objects/structures/janicart.dm +++ b/code/game/objects/structures/janicart.dm @@ -250,9 +250,14 @@ else user << "You'll need the keys in one of your hands to drive this [callme]." - /obj/structure/stool/bed/chair/janicart/user_buckle_mob(mob/living/M, mob/user) - M.loc = loc + if(user.incapacitated()) //user can't move the mob on the janicart's turf if incapacitated + return + for(var/atom/movable/A in get_turf(src)) //we check for obstacles on the turf. + if(A.density) + if(A != src && A != M) + return + M.loc = loc //we move the mob on the janicart's turf before checking if we can buckle. ..() update_mob() diff --git a/code/game/objects/structures/mirror.dm b/code/game/objects/structures/mirror.dm index 87809a71d38..050f225a6b4 100644 --- a/code/game/objects/structures/mirror.dm +++ b/code/game/objects/structures/mirror.dm @@ -100,4 +100,96 @@ playsound(src.loc, 'sound/effects/hit_on_shattered_glass.ogg', 70, 1) return user.visible_message("[user] smashes [src]!") - shatter() \ No newline at end of file + shatter() + +/obj/structure/mirror/magic + name = "magic mirror" + desc = "Turn and face the strange... face." + icon_state = "magic_mirror" + + +/obj/structure/mirror/magic/attack_hand(mob/user as mob) + if(!ishuman(user)) + return + + var/mob/living/carbon/human/H = user + + var/choice = input(user, "Something to change?", "Magical Grooming") as null|anything in list("name", "race", "gender", "hair", "eyes") + + switch(choice) + if("name") + var/newname = copytext(sanitize(input(H, "Who are we again?", "Name change", H.name) as null|text),1,MAX_NAME_LEN) + + if(!newname) + return + + H.real_name = newname + H.name = newname + if(H.mind) + H.mind.name = newname + + if("race") + var/newrace + var/racechoice = input(H, "What are we again?", "Race change") as null|anything in species_list + newrace = species_list[racechoice] + + if(!newrace || !H.dna) + return + + H.dna.species = new newrace + + if(H.dna.species.use_skintones) + var/new_s_tone = input(user, "What are we again?", "Race change") as null|anything in skin_tones + + if(new_s_tone) + H.skin_tone = new_s_tone + + if(MUTCOLORS in H.dna.species.specflags) + var/new_mutantcolor = input(user, "Choose your skin color:", "Race change") as color|null + if(new_mutantcolor) + var/temp_hsv = RGBtoHSV(new_mutantcolor) + + if(ReadHSV(temp_hsv)[3] >= ReadHSV("#7F7F7F")[3]) // mutantcolors must be bright + H.dna.mutant_color = sanitize_hexcolor(new_mutantcolor) + + else + H << "Invalid color. Your color is not bright enough." + + H.regenerate_icons() + + if("gender") + if(!(H.gender in list("male", "female"))) //blame the patriarchy + return + + if(H.gender == "male") + if(alert(H, "Become a Witch?", "Confirmation", "Yes", "No") == "Yes") + H.gender = "female" + H << "Man, you feel like a woman!" + H.regenerate_icons() + else + if(alert(H, "Become a Warlock?", "Confirmation", "Yes", "No") == "Yes") + H.gender = "male" + H << "Whoa man, you feel like a man!" + H.regenerate_icons() + + if("hair") + var/hairchoice = alert(H, "Hair style or hair color?", "Change Hair", "Style", "Color") + + if(hairchoice == "Style") //So you just want to use a mirror then? + ..() + else + var/new_hair_color = input(H, "Choose your hair color", "Hair Color") as null|color + if(new_hair_color) + H.hair_color = sanitize_hexcolor(new_hair_color) + if(H.gender == "male") + var/new_face_color = input(H, "Choose your facial hair color", "Hair Color") as null|color + if(new_face_color) + H.facial_hair_color = sanitize_hexcolor(new_face_color) + + H.update_hair() + + if("eyes") + var/new_eye_color = input(H, "Choose your eye color", "Eye Color") as null|color + if(new_eye_color) + H.eye_color = sanitize_hexcolor(new_eye_color) + H.update_body() \ No newline at end of file diff --git a/code/game/objects/structures/statues.dm b/code/game/objects/structures/statues.dm index 43a5a3d4639..888af8a09ac 100644 --- a/code/game/objects/structures/statues.dm +++ b/code/game/objects/structures/statues.dm @@ -57,9 +57,9 @@ else if(istype(W, /obj/item/weapon/pickaxe/drill/jackhammer)) var/obj/item/weapon/pickaxe/drill/jackhammer/D = W if(!D.bcell.use(D.drillcost)) - D.update_charge() + user << "Your [D.name] doesn't have enough power to break through the [name]." return - D.update_charge() + D.update_icon() if(!src.loc) return user.visible_message("[user] destroys the [name]!", \ diff --git a/code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm b/code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm index 974a5a9af5e..594ce58d2d4 100644 --- a/code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm +++ b/code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm @@ -26,7 +26,7 @@ */ /obj/structure/stool/bed/nest/user_buckle_mob(mob/M as mob, mob/user as mob) - if ( !ismob(M) || (get_dist(src, user) > 1) || (M.loc != src.loc) || user.restrained() || usr.stat || M.buckled || istype(user, /mob/living/silicon/pai) ) + if ( !ismob(M) || (get_dist(src, user) > 1) || (M.loc != src.loc) || user.restrained() || user.stat || M.buckled || istype(user, /mob/living/silicon/pai) ) return if(istype(M,/mob/living/carbon/alien)) @@ -36,27 +36,22 @@ unbuckle_mob() - if(M == usr) - return - else + if(buckle_mob(M)) M.visible_message(\ "[user.name] secretes a thick vile goo, securing [M.name] into [src]!",\ "[user.name] drenches you in a foul-smelling resin, trapping you in [src]!",\ "You hear squelching...") - return /obj/structure/stool/bed/nest/post_buckle_mob(mob/living/M) if(M == buckled_mob) - M.pixel_y += 1 + M.pixel_y += 6 M.pixel_x += 2 overlays += image('icons/mob/alien.dmi', "nestoverlay", layer=6) else - buckled_mob.pixel_y -= 1 - buckled_mob.pixel_x -= 2 + M.pixel_x -= 2 + M.pixel_y = initial(M.pixel_y) overlays.Cut() - - /obj/structure/stool/bed/nest/attackby(obj/item/weapon/W as obj, mob/user as mob, params) var/aforce = W.force health = max(0, health - aforce) diff --git a/code/game/objects/structures/tables_racks.dm b/code/game/objects/structures/tables_racks.dm index 196ce0cbb0b..da22c57e321 100644 --- a/code/game/objects/structures/tables_racks.dm +++ b/code/game/objects/structures/tables_racks.dm @@ -314,16 +314,6 @@ if(isrobot(user)) return - if(istype(I, /obj/item/weapon/melee/energy/blade)) - var/datum/effect/effect/system/spark_spread/SS = new /datum/effect/effect/system/spark_spread() - SS.set_up(5, 0, src.loc) - SS.start() - playsound(src.loc, 'sound/weapons/blade1.ogg', 50, 1) - playsound(src.loc, "sparks", 50, 1) - user.visible_message("The [src.name] was sliced apart by [user]!") - table_destroy(1) - return - if(!(I.flags & ABSTRACT)) //rip more parems rip in peace ;_; if(user.drop_item()) I.Move(loc) diff --git a/code/game/turfs/simulated/floor/light_floor.dm b/code/game/turfs/simulated/floor/light_floor.dm index f9d8e5a111b..85755fc867d 100644 --- a/code/game/turfs/simulated/floor/light_floor.dm +++ b/code/game/turfs/simulated/floor/light_floor.dm @@ -24,7 +24,7 @@ if(on) switch(state) if(0) - icon_state = "light_on_[coloredlights[currentcolor]]" + icon_state = "light_on-[coloredlights[currentcolor]]" SetLuminosity(1) if(1) var/num = pick("1","2","3","4") diff --git a/code/game/turfs/simulated/walls.dm b/code/game/turfs/simulated/walls.dm index bb0b9d7b701..2c88719d4b9 100644 --- a/code/game/turfs/simulated/walls.dm +++ b/code/game/turfs/simulated/walls.dm @@ -136,13 +136,6 @@ if( thermite ) if(is_hot(W)) thermitemelt(user) - - if( istype(W, /obj/item/weapon/melee/energy/blade) ) - var/obj/item/weapon/melee/energy/blade/EB = W - EB.spark_system.start() - user << "You slash \the [src] with \the [EB]; the thermite ignites!" - playsound(src, "sparks", 50, 1) - playsound(src, 'sound/weapons/blade1.ogg', 50, 1) return var/turf/T = user.loc //get user's location for delay checks @@ -215,32 +208,16 @@ if(istype(W, /obj/item/weapon/pickaxe/drill/jackhammer)) var/obj/item/weapon/pickaxe/drill/jackhammer/D = W if(!D.bcell.use(400)) - D.update_charge() - user << "Your jackhammer doesn't have enough power to break through that wall." + user << "Your [D.name] doesn't have enough power to break through the [name]." return - D.update_charge() + D.update_icon() if( !istype(src, /turf/simulated/wall) || !user || !W || !T ) return 1 if( user.loc == T && user.get_active_hand() == W ) D.playDigSound() dismantle_wall() - visible_message("[user] smashes through the wall with [W]!", "You hear the grinding of metal.") + visible_message("[user] smashes through the [name] with the [W.name]!", "You hear the grinding of metal.") return 1 - else if( istype(W, /obj/item/weapon/melee/energy/blade) ) - var/obj/item/weapon/melee/energy/blade/EB = W - EB.spark_system.start() - user << "You stab \the [EB] into the wall and begin to slice it apart." - playsound(src, "sparks", 50, 1) - if(do_after(user, slicing_duration*0.7)) //energy blade slicing is faster than welding tool slicing - if( !istype(src, /turf/simulated/wall) || !user || !EB || !T ) - return 1 - if( user.loc == T && user.get_active_hand() == W ) - EB.spark_system.start() - playsound(src, "sparks", 50, 1) - playsound(src, 'sound/weapons/blade1.ogg', 50, 1) - dismantle_wall(1) - visible_message("The wall was sliced apart by [user]!", "You hear metal being sliced apart and sparks flying.") - return 1 return 0 diff --git a/code/game/turfs/simulated/walls_reinforced.dm b/code/game/turfs/simulated/walls_reinforced.dm index aeb3c507dfa..b7e71d69e0b 100644 --- a/code/game/turfs/simulated/walls_reinforced.dm +++ b/code/game/turfs/simulated/walls_reinforced.dm @@ -29,25 +29,19 @@ M << "This wall is far too strong for you to destroy." /turf/simulated/wall/r_wall/try_destroy(obj/item/weapon/W as obj, mob/user as mob, turf/T as turf) - if(istype(W, /obj/item/weapon/melee/energy/blade)) - user << "This wall is too thick to slice through. You will need to find a different path." - return 1 - else if(istype(W, /obj/item/weapon/pickaxe/drill/jackhammer)) + if(istype(W, /obj/item/weapon/pickaxe/drill/jackhammer)) var/obj/item/weapon/pickaxe/drill/jackhammer/D = W - if(!D.powered) + if(!D.bcell.use(800)) + user << "Your [D.name] doesn't have enough power to break through the [name]." return 1 - user << "You begin to smash though the reinforced wall." + user << "You begin to smash though the [name]." if(do_after(user, 50)) if( !istype(src, /turf/simulated/wall/r_wall) || !user || !W || !T ) return 1 if( user.loc == T && user.get_active_hand() == W ) - if(!D.bcell.use(800)) - user << "Your jackhammer doesn't have enough power to break through that wall." - D.update_charge() - return 1 - D.update_charge() + D.update_icon() D.playDigSound() - user << "Your jackhammer smashes though the last of the reinforced plating." + visible_message("[user] smashes through the [name] with the [D.name]!", "You hear the grinding of metal.") dismantle_wall() return 1 else if(istype(W, /obj/item/stack/sheet/metal) && d_state) diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index e2f23e70f0b..70ec86b079b 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -193,7 +193,7 @@ src.cancable = 1//so cables can be laid new /obj/structure/lattice/catwalk(locate(src.x, src.y, src.z) ) -/turf/proc/phase_damage_creatures(damage,mob/U = null)//>Ninja Code. Hurts and knocks out creatures on this turf +/turf/proc/phase_damage_creatures(damage,mob/U = null)//>Ninja Code. Hurts and knocks out creatures on this turf //NINJACODE for(var/mob/living/M in src) if(M==U) continue//Will not harm U. Since null != M, can be excluded to kill everyone. diff --git a/code/game/verbs/ooc.dm b/code/game/verbs/ooc.dm index 77a5b65105e..790021ee0d5 100644 --- a/code/game/verbs/ooc.dm +++ b/code/game/verbs/ooc.dm @@ -14,7 +14,7 @@ msg = copytext(sanitize(msg), 1, MAX_MESSAGE_LEN) if(!msg) return - if(!(prefs.toggles & CHAT_OOC)) + if(!(prefs.chat_toggles & CHAT_OOC)) src << "You have OOC muted." return @@ -46,7 +46,7 @@ msg = emoji_parse(msg) for(var/client/C in clients) - if(C.prefs.toggles & CHAT_OOC) + if(C.prefs.chat_toggles & CHAT_OOC) if(holder) if(!holder.fakekey || C.holder) if(check_rights_for(src, R_ADMIN)) diff --git a/code/modules/admin/IsBanned.dm b/code/modules/admin/IsBanned.dm index 4abe574216a..a89aea9f725 100644 --- a/code/modules/admin/IsBanned.dm +++ b/code/modules/admin/IsBanned.dm @@ -1,6 +1,9 @@ //Blocks an attempt to connect before even creating our client datum thing. world/IsBanned(key,address,computer_id) + if (!key || !address || !computer_id) + log_access("Failed Login (invalid data): [key] [address]-[computer_id]") + return list("reason"="invalid login data", "desc"="Your computer provided invalid or blank information to the server on connection (byond username, IP, and Computer ID.) Provided information for reference: Username:'[key]' IP:'[address]' Computer ID:'[computer_id]' If you continue to get this error, please restart byond or contact byond support.") if(ckey(key) in admin_datums) //It has proven to be a bad idea to make admins completely immune to bans, making them have to wait for someone with daemon access //to add a daemon ban to finally stop them. Admin tempbans and admin permabans are special, high-level ban types, which are there to help @@ -76,18 +79,13 @@ world/IsBanned(key,address,computer_id) world.log << "Ban database connection failure. Key [ckeytext] not checked" diary << "Ban database connection failure. Key [ckeytext] not checked" return - - var/failedcid = 1 - var/failedip = 1 - + var/ipquery = "" var/cidquery = "" if(address) - failedip = 0 ipquery = " OR ip = '[address]' " if(computer_id) - failedcid = 0 cidquery = " OR computerid = '[computer_id]' " var/DBQuery/query = dbcon.NewQuery("SELECT ckey, ip, computerid, a_ckey, reason, expiration_time, duration, bantime, bantype FROM [format_table_name("ban")] WHERE (ckey = '[ckeytext]' [ipquery] [cidquery]) AND (bantype = 'PERMABAN' OR (bantype = 'TEMPBAN' AND expiration_time > Now())) AND isnull(unbanned)") @@ -112,9 +110,4 @@ world/IsBanned(key,address,computer_id) var/desc = "\nReason: You, or another user of this computer or connection ([pckey]) is banned from playing here. The ban reason is:\n[reason]\nThis ban was applied by [ackey] on [bantime], [expires]" return list("reason"="[bantype]", "desc"="[desc]") - - if (failedcid) - message_admins("[key] has logged in with a blank computer id in the ban check.") - if (failedip) - message_admins("[key] has logged in with a blank ip in the ban check.") return ..() //default pager ban stuff diff --git a/code/modules/admin/player_panel.dm b/code/modules/admin/player_panel.dm index 2e13a806984..10af3669fc4 100644 --- a/code/modules/admin/player_panel.dm +++ b/code/modules/admin/player_panel.dm @@ -368,6 +368,8 @@ if (ticker && ticker.current_state >= GAME_STATE_PLAYING) var/dat = "Round Status

Round Status

" dat += "Current Game Mode: [ticker.mode.name]
" + if(ticker.mode.replacementmode) + dat += "Replacement Game Mode: [ticker.mode.replacementmode.name]
" dat += "Round Duration: [round(world.time / 36000)]:[add_zero("[world.time / 600 % 60]", 2)]:[world.time / 100 % 6][world.time / 100 % 10]
" dat += "Emergency shuttle
" if(SSshuttle.emergency.mode < SHUTTLE_CALL) @@ -379,6 +381,7 @@ dat += "Send Back
" else dat += "ETA: [(timeleft / 60) % 60]:[add_zero(num2text(timeleft % 60), 2)]
" + dat += "End Round Now
" dat += "[ticker.delay_end ? "End Round Normally" : "Delay Round End"]
" if(ticker.mode.syndicates.len) dat += "
" diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index ddb5f5c3868..43aa60f2f6b 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -226,6 +226,21 @@ message_admins("[key_name(usr)] [ticker.delay_end ? "delayed the round end" : "has made the round end normally"].") href_list["secretsadmin"] = "check_antagonist" + else if(href_list["end_round"]) + if(!check_rights(R_ADMIN)) return + + message_admins("[key_name_admin(usr)] is considering ending the round.") + if(alert(usr, "This will end the round, are you SURE you want to do this?", "Confirmation", "Yes", "No") == "Yes") + spawn(200) //I wish you would step back from that ledge my friend + if(alert(usr, "Final Confirmation: End the round NOW?", "Confirmation", "Yes", "No") == "Yes") + message_admins("[key_name_admin(usr)] has ended the round.") + ticker.force_ending = 1 //Yeah there we go APC destroyed mission accomplished + return + else + message_admins("[key_name_admin(usr)] decided against ending the round.") + else + message_admins("[key_name_admin(usr)] decided against ending the round.") + else if(href_list["simplemake"]) if(!check_rights(R_SPAWN)) return diff --git a/code/modules/admin/verbs/deadsay.dm b/code/modules/admin/verbs/deadsay.dm index 213e618d82d..19cc6dd5667 100644 --- a/code/modules/admin/verbs/deadsay.dm +++ b/code/modules/admin/verbs/deadsay.dm @@ -26,7 +26,7 @@ for (var/mob/M in player_list) if (istype(M, /mob/new_player)) continue - if (M.stat == DEAD || (M.client && M.client.holder && (M.client.prefs.toggles & CHAT_DEAD))) //admins can toggle deadchat on and off. This is a proc in admin.dm and is only give to Administrators and above + if (M.stat == DEAD || (M.client && M.client.holder && (M.client.prefs.chat_toggles & CHAT_DEAD))) //admins can toggle deadchat on and off. This is a proc in admin.dm and is only give to Administrators and above M.show_message(rendered, 2) feedback_add_details("admin_verb","D") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! \ No newline at end of file diff --git a/code/modules/admin/verbs/modifyvariables.dm b/code/modules/admin/verbs/modifyvariables.dm index 79ce1fb1f6a..f14df6a3fc9 100644 --- a/code/modules/admin/verbs/modifyvariables.dm +++ b/code/modules/admin/verbs/modifyvariables.dm @@ -5,7 +5,7 @@ var/list/forbidden_varedit_object_types = list( /datum/admin_rank //editing my own rank? it's more likely than you think ) -var/list/VVlocked = list("vars", "client", "virus", "viruses", "cuffed", "last_eaten", "unlock_content", "step_x", "step_y") +var/list/VVlocked = list("vars", "client", "virus", "viruses", "cuffed", "last_eaten", "unlock_content", "step_x", "step_y", "force_ending") var/list/VVicon_edit_lock = list("icon", "icon_state", "overlays", "underlays") var/list/VVckey_edit = list("key", "ckey") diff --git a/code/modules/admin/verbs/pray.dm b/code/modules/admin/verbs/pray.dm index 2ab5df2bb8d..85fb049bd4d 100644 --- a/code/modules/admin/verbs/pray.dm +++ b/code/modules/admin/verbs/pray.dm @@ -20,7 +20,7 @@ msg = "\icon[cross] PRAY: [key_name(src, 1)] (?) (PP) (VV) (SM) (JMP) (TP) (SC): [msg]" for(var/client/C in admins) - if(C.prefs.toggles & CHAT_PRAYER) + if(C.prefs.chat_toggles & CHAT_PRAYER) C << msg usr << "Your prayers have been received by the gods." diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm index d3275f9cf76..64e70411bff 100644 --- a/code/modules/admin/verbs/randomverbs.dm +++ b/code/modules/admin/verbs/randomverbs.dm @@ -327,7 +327,7 @@ Traitors and the like can also be revived with the previous role mostly intact. new_character.loc = get_turf(synd_spawn) call(/datum/game_mode/proc/equip_syndicate)(new_character) if("Space Ninja") - var/ninja_spawn[] = list() + var/list/ninja_spawn = list() for(var/obj/effect/landmark/L in landmarks_list) if(L.name=="carpspawn") ninja_spawn += L diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index 876723c9d0a..51bab7dc9ba 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -36,6 +36,7 @@ datum/preferences var/be_special = 0 //Special role selection var/UI_style = "Midnight" var/toggles = TOGGLES_DEFAULT + var/chat_toggles = TOGGLES_DEFAULT_CHAT var/ghost_form = "ghost" var/allow_midround_antag = 1 @@ -240,11 +241,12 @@ datum/preferences dat += "UI Style:[UI_style]
" dat += "Play admin midis:[(toggles & SOUND_MIDI) ? "Yes" : "No"]
" dat += "Play lobby music:[(toggles & SOUND_LOBBY) ? "Yes" : "No"]
" - dat += "Ghost ears:[(toggles & CHAT_GHOSTEARS) ? "Nearest Creatures" : "All Speech"]
" - dat += "Ghost sight:[(toggles & CHAT_GHOSTSIGHT) ? "Nearest Creatures" : "All Emotes"]
" - dat += "Ghost whispers:[(toggles & CHAT_GHOSTWHISPER) ? "Nearest Creatures" : "All Speech"]
" - dat += "Ghost pda:[(toggles & CHAT_GHOSTPDA) ? "Nearest Creatures" : "All Messages"]
" - dat += "Pull requests:[(toggles & CHAT_PULLR) ? "Yes" : "No"]
" + dat += "Ghost ears:[(chat_toggles & CHAT_GHOSTEARS) ? "Nearest Creatures" : "All Speech"]
" + dat += "Ghost sight:[(chat_toggles & CHAT_GHOSTSIGHT) ? "Nearest Creatures" : "All Emotes"]
" + dat += "Ghost whispers:[(chat_toggles & CHAT_GHOSTWHISPER) ? "Nearest Creatures" : "All Speech"]
" + dat += "Ghost radio:[(chat_toggles & CHAT_GHOSTRADIO) ? "Yes" : "No"]
" + dat += "Ghost pda:[(chat_toggles & CHAT_GHOSTPDA) ? "Nearest Creatures" : "All Messages"]
" + dat += "Pull requests:[(chat_toggles & CHAT_PULLR) ? "Yes" : "No"]
" dat += "Midround Antagonist:[(toggles & MIDROUND_ANTAG) ? "Yes" : "No"]
" if(config.allow_Metadata) dat += "OOC Notes: Edit
" @@ -799,19 +801,22 @@ datum/preferences user << sound(null, repeat = 0, wait = 0, volume = 85, channel = 1) if("ghost_ears") - toggles ^= CHAT_GHOSTEARS + chat_toggles ^= CHAT_GHOSTEARS if("ghost_sight") - toggles ^= CHAT_GHOSTSIGHT + chat_toggles ^= CHAT_GHOSTSIGHT if("ghost_whispers") - toggles ^= CHAT_GHOSTWHISPER + chat_toggles ^= CHAT_GHOSTWHISPER + + if("ghost_radio") + chat_toggles ^= CHAT_GHOSTRADIO if("ghost_pda") - toggles ^= CHAT_GHOSTPDA + chat_toggles ^= CHAT_GHOSTPDA if("pull_requests") - toggles ^= CHAT_PULLR + chat_toggles ^= CHAT_PULLR if("allow_midround_antag") toggles ^= MIDROUND_ANTAG diff --git a/code/modules/client/preferences_toggles.dm b/code/modules/client/preferences_toggles.dm index 3f41b53cdfd..52b9329094d 100644 --- a/code/modules/client/preferences_toggles.dm +++ b/code/modules/client/preferences_toggles.dm @@ -3,8 +3,8 @@ set name = "Show/Hide GhostEars" set category = "Preferences" set desc = ".Toggle Between seeing all mob speech, and only speech of nearby mobs" - prefs.toggles ^= CHAT_GHOSTEARS - src << "As a ghost, you will now [(prefs.toggles & CHAT_GHOSTEARS) ? "see all speech in the world" : "only see speech from nearby mobs"]." + prefs.chat_toggles ^= CHAT_GHOSTEARS + src << "As a ghost, you will now [(prefs.chat_toggles & CHAT_GHOSTEARS) ? "see all speech in the world" : "only see speech from nearby mobs"]." prefs.save_preferences() feedback_add_details("admin_verb","TGE") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! @@ -12,8 +12,8 @@ set name = "Show/Hide GhostSight" set category = "Preferences" set desc = ".Toggle Between seeing all mob emotes, and only emotes of nearby mobs" - prefs.toggles ^= CHAT_GHOSTSIGHT - src << "As a ghost, you will now [(prefs.toggles & CHAT_GHOSTSIGHT) ? "see all emotes in the world" : "only see emotes from nearby mobs"]." + prefs.chat_toggles ^= CHAT_GHOSTSIGHT + src << "As a ghost, you will now [(prefs.chat_toggles & CHAT_GHOSTSIGHT) ? "see all emotes in the world" : "only see emotes from nearby mobs"]." prefs.save_preferences() feedback_add_details("admin_verb","TGS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! @@ -21,17 +21,26 @@ set name = "Show/Hide GhostWhispers" set category = "Preferences" set desc = ".Toggle between hearing all whispers, and only whispers of nearby mobs" - prefs.toggles ^= CHAT_GHOSTWHISPER - src << "As a ghost, you will now [(prefs.toggles & CHAT_GHOSTWHISPER) ? "see all whispers in the world" : "only see whispers from nearby mobs"]." + prefs.chat_toggles ^= CHAT_GHOSTWHISPER + src << "As a ghost, you will now [(prefs.chat_toggles & CHAT_GHOSTWHISPER) ? "see all whispers in the world" : "only see whispers from nearby mobs"]." prefs.save_preferences() feedback_add_details("admin_verb","TGW") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! +/client/verb/toggle_ghost_radio() + set name = "Show/Hide GhostRadio" + set category = "Preferences" + set desc = ".Enable or disable hearing radio chatter as a ghost" + prefs.chat_toggles ^= CHAT_GHOSTRADIO + src << "As a ghost, you will now [(prefs.chat_toggles & CHAT_GHOSTRADIO) ? "see radio chatter" : "not see radio chatter"]." + prefs.save_preferences() + feedback_add_details("admin_verb","TGR") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! //social experiment, increase the generation whenever you copypaste this shamelessly GENERATION 1 + /client/verb/toggle_ghost_pda() set name = "Show/Hide GhostPDA" set category = "Preferences" set desc = ".Toggle Between seeing all mob pda messages, and only pda messages of nearby mobs" - prefs.toggles ^= CHAT_GHOSTPDA - src << "As a ghost, you will now [(prefs.toggles & CHAT_GHOSTPDA) ? "see all pda messages in the world" : "only see pda messages from nearby mobs"]." + prefs.chat_toggles ^= CHAT_GHOSTPDA + src << "As a ghost, you will now [(prefs.chat_toggles & CHAT_GHOSTPDA) ? "see all pda messages in the world" : "only see pda messages from nearby mobs"]." prefs.save_preferences() feedback_add_details("admin_verb","TGP") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! @@ -40,9 +49,9 @@ set category = "Preferences" set desc = "Toggle seeing radiochatter from nearby radios and speakers" if(!holder) return - prefs.toggles ^= CHAT_RADIO + prefs.chat_toggles ^= CHAT_RADIO prefs.save_preferences() - usr << "You will [(prefs.toggles & CHAT_RADIO) ? "now" : "no longer"] see radio chatter from nearby radios or speakers" + usr << "You will [(prefs.chat_toggles & CHAT_RADIO) ? "now" : "no longer"] see radio chatter from nearby radios or speakers" feedback_add_details("admin_verb","THR") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /client/proc/toggleadminhelpsound() @@ -59,27 +68,27 @@ set name = "Show/Hide Deadchat" set category = "Preferences" set desc ="Toggles seeing deadchat" - prefs.toggles ^= CHAT_DEAD + prefs.chat_toggles ^= CHAT_DEAD prefs.save_preferences() - src << "You will [(prefs.toggles & CHAT_DEAD) ? "now" : "no longer"] see deadchat." + src << "You will [(prefs.chat_toggles & CHAT_DEAD) ? "now" : "no longer"] see deadchat." feedback_add_details("admin_verb","TDV") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /client/proc/toggleprayers() set name = "Show/Hide Prayers" set category = "Preferences" set desc = "Toggles seeing prayers" - prefs.toggles ^= CHAT_PRAYER + prefs.chat_toggles ^= CHAT_PRAYER prefs.save_preferences() - src << "You will [(prefs.toggles & CHAT_PRAYER) ? "now" : "no longer"] see prayerchat." + src << "You will [(prefs.chat_toggles & CHAT_PRAYER) ? "now" : "no longer"] see prayerchat." feedback_add_details("admin_verb","TP") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /client/verb/togglePRs() set name = "Show/Hide Pull Request Announcements" set category = "Preferences" set desc = "Toggles receiving a notification when new pull requests are created." - prefs.toggles ^= CHAT_PULLR + prefs.chat_toggles ^= CHAT_PULLR prefs.save_preferences() - src << "You will [(prefs.toggles & CHAT_PULLR) ? "now" : "no longer"] see new pull request announcements." + src << "You will [(prefs.chat_toggles & CHAT_PULLR) ? "now" : "no longer"] see new pull request announcements." feedback_add_details("admin_verb","TPullR") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /client/verb/togglemidroundantag() @@ -129,9 +138,9 @@ set name = "Show/Hide OOC" set category = "Preferences" set desc = "Toggles seeing OutOfCharacter chat" - prefs.toggles ^= CHAT_OOC + prefs.chat_toggles ^= CHAT_OOC prefs.save_preferences() - src << "You will [(prefs.toggles & CHAT_OOC) ? "now" : "no longer"] see messages on the OOC channel." + src << "You will [(prefs.chat_toggles & CHAT_OOC) ? "now" : "no longer"] see messages on the OOC channel." feedback_add_details("admin_verb","TOOC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /client/verb/Toggle_Soundscape() //All new ambience should be added here so it works with this verb until someone better at things comes up with a fix that isn't awful diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm index c84fd4b7916..02f9bcfe7b4 100644 --- a/code/modules/clothing/clothing.dm +++ b/code/modules/clothing/clothing.dm @@ -76,6 +76,7 @@ BLIND // can't see anything icon = 'icons/obj/clothing/hats.dmi' body_parts_covered = HEAD slot_flags = SLOT_HEAD + var/blockTracking = 0 //For AI tracking //Mask /obj/item/clothing/mask @@ -266,7 +267,7 @@ atom/proc/generate_female_clothing(index,t_color,icon,type) female_clothing_icons[index] = female_clothing_icon /obj/item/clothing/under/verb/toggle() - set name = "Toggle Suit Sensors" + set name = "Adjust Suit Sensors" set category = "Object" set src in usr var/mob/M = usr diff --git a/code/modules/clothing/gloves/ninja.dm b/code/modules/clothing/gloves/ninja.dm deleted file mode 100644 index 0b05f32fb8d..00000000000 --- a/code/modules/clothing/gloves/ninja.dm +++ /dev/null @@ -1,104 +0,0 @@ -/* - Dear ninja gloves - - This isn't because I like you - this is because your father is a bastard - - ... - I guess you're a little cool. - -Sayu -*/ - -/obj/item/clothing/gloves/space_ninja - desc = "These nano-enhanced gloves insulate from electricity and provide fire resistance." - name = "ninja gloves" - icon_state = "s-ninja" - item_state = "s-ninja" - siemens_coefficient = 0 - cold_protection = HANDS - min_cold_protection_temperature = GLOVES_MIN_TEMP_PROTECT - heat_protection = HANDS - max_heat_protection_temperature = GLOVES_MAX_TEMP_PROTECT - strip_delay = 120 - var/draining = 0 - var/candrain = 0 - var/mindrain = 200 - var/maxdrain = 400 - -/* - This runs the gamut of what ninja gloves can do - The other option would be a dedicated ninja touch bullshit proc on everything - which would probably more efficient, but ninjas are pretty rare. - This was mostly introduced to keep ninja code from contaminating other code; - with this in place it would be easier to untangle the rest of it. - - For the drain proc, see events/ninja.dm -*/ -/obj/item/clothing/gloves/space_ninja/Touch(var/atom/A,var/proximity) - if(!candrain || draining) return 0 - - var/mob/living/carbon/human/H = loc - if(!istype(H)) return 0 // what - var/obj/item/clothing/suit/space/space_ninja/suit = H.wear_suit - if(!istype(suit)) return 0 - if(isturf(A)) return 0 - - if(!proximity) // todo: you could add ninja stars or computer hacking here - return 0 - - A.add_fingerprint(H) - - // steal energy from powered things - if(istype(A,/mob/living/silicon/robot)) - drain("CYBORG",A,suit) - return 1 - - if(istype(A,/obj/machinery/power/apc)) - drain("APC",A,suit) - return 1 - - if(istype(A,/obj/structure/cable)) - drain("WIRE",A,suit) - return 1 - - if(istype(A,/obj/structure/grille)) - var/obj/structure/cable/C = locate() in A.loc - if(C) - drain("WIRE",C,suit) - return 1 - - if(istype(A,/obj/machinery/power/smes)) - drain("SMES",A,suit) - return 1 - - if(istype(A,/obj/mecha)) - drain("MECHA",A,suit) - return 1 - - if(istype(A,/obj/machinery/computer/rdconsole)) // download research - drain("RESEARCH",A,suit) - return 1 - - if(istype(A,/obj/machinery/r_n_d/server)) - A.add_fingerprint(H) - var/obj/machinery/r_n_d/server/S = A - if(S.disabled) - return 1 - if(S.shocked) - S.shock(H,50) - return 1 - drain("RESEARCH",A,suit) - return 1 - - //do AI transfers - if(istype(A,/mob/living/silicon/ai)) - suit.NAI.transfer_ai("AICORE", "AICARD", A, H) - return 1 - - if(istype(A,/obj/structure/AIcore/deactivated)) - suit.NAI.transfer_ai("INACTIVE","AICARD",A, H) - return 1 - - if(istype(A,/obj/machinery/computer/aifixer)) - suit.NAI.transfer_ai("AIFIXER","AICARD",A, H) - return 1 diff --git a/code/modules/clothing/masks/gasmask.dm b/code/modules/clothing/masks/gasmask.dm index 2366d9f3877..c38e52f1736 100644 --- a/code/modules/clothing/masks/gasmask.dm +++ b/code/modules/clothing/masks/gasmask.dm @@ -219,35 +219,6 @@ vchange = !vchange user << "The voice changer is now [vchange ? "on" : "off"]!" -/obj/item/clothing/mask/gas/voice/space_ninja - name = "ninja mask" - desc = "A close-fitting mask that acts both as an air filter and a post-modern fashion statement." - icon_state = "s-ninja" - item_state = "s-ninja_mask" - vchange = 1 - strip_delay = 120 - -/obj/item/clothing/mask/gas/voice/space_ninja/speechModification(message) - if(voice == "Unknown") - if(copytext(message, 1, 2) != "*") - var/list/temp_message = text2list(message, " ") - var/list/pick_list = list() - for(var/i = 1, i <= temp_message.len, i++) - pick_list += i - for(var/i=1, i <= abs(temp_message.len/3), i++) - var/H = pick(pick_list) - if(findtext(temp_message[H], "*") || findtext(temp_message[H], ";") || findtext(temp_message[H], ":")) continue - temp_message[H] = ninjaspeak(temp_message[H]) - pick_list -= H - message = list2text(temp_message, " ") - message = replacetext(message, "o", "?") - message = replacetext(message, "p", "?") - message = replacetext(message, "l", "?") - message = replacetext(message, "s", "?") - message = replacetext(message, "u", "?") - message = replacetext(message, "b", "?") - return message - /obj/item/clothing/mask/gas/clown_hat name = "clown wig and mask" diff --git a/code/modules/clothing/masks/miscellaneous.dm b/code/modules/clothing/masks/miscellaneous.dm index 479b461b02a..4ce903e2bf8 100644 --- a/code/modules/clothing/masks/miscellaneous.dm +++ b/code/modules/clothing/masks/miscellaneous.dm @@ -49,6 +49,48 @@ flags = BLOCKHAIR flags_inv = HIDEFACE w_class = 2 + action_button_name = "Toggle Voice Box" + var/voicechange = 0 + +/obj/item/clothing/mask/pig/attack_self(mob/user) + voicechange = !voicechange + user << "You turn the voice box [voicechange ? "on" : "off"]!" + +/obj/item/clothing/mask/pig/speechModification(message) + if(voicechange) + message = pick("Oink!","Squeeeeeeee!","Oink Oink!") + return message + +/obj/item/clothing/mask/spig //needs to be different otherwise you could turn the speedmodification off and on + name = "Pig face" + desc = "It looks like a mask, but closer inspection reveals it's melded onto this persons face!" //It's only ever going to be attached to your face. + icon_state = "pig" + item_state = "pig" + flags = BLOCKHAIR + flags_inv = HIDEFACE + w_class = 2 + var/voicechange = 1 + +/obj/item/clothing/mask/spig/speechModification(message) + if(voicechange) + message = pick("Oink!","Squeeeeeeee!","Oink Oink!") + return message + +/obj/item/clothing/mask/cowmask + name = "Cowface" + desc = "It looks like a mask, but closer inspection reveals it's melded onto this persons face!" + icon = 'icons/mob/mask.dmi' + icon_state = "cowmask" + item_state = "cowmask" + flags = BLOCKHAIR + flags_inv = HIDEFACE + w_class = 2 + var/voicechange = 1 + +/obj/item/clothing/mask/cowmask/speechModification(message) + if(voicechange) + message = pick("Moooooooo!","Moo!","Moooo!") + return message /obj/item/clothing/mask/horsehead name = "horse head mask" @@ -58,7 +100,7 @@ flags = BLOCKHAIR flags_inv = HIDEFACE w_class = 2 - var/voicechange = 0 + var/voicechange = 1 /obj/item/clothing/mask/horsehead/speechModification(message) if(voicechange) diff --git a/code/modules/clothing/shoes/miscellaneous.dm b/code/modules/clothing/shoes/miscellaneous.dm index a1f83e984d2..cd9c96ae388 100644 --- a/code/modules/clothing/shoes/miscellaneous.dm +++ b/code/modules/clothing/shoes/miscellaneous.dm @@ -29,20 +29,6 @@ flags = NOSLIP armor = list(melee = 80, bullet = 60, laser = 50, energy = 50, bomb = 50, bio = 30, rad = 30) -/obj/item/clothing/shoes/space_ninja - name = "ninja shoes" - desc = "A pair of running shoes. Excellent for running and even better for smashing skulls." - icon_state = "s-ninja" - item_state = "secshoes" - permeability_coefficient = 0.01 - flags = NOSLIP - armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 30, rad = 30) - strip_delay = 120 - cold_protection = FEET - min_cold_protection_temperature = SHOES_MIN_TEMP_PROTECT - heat_protection = FEET - max_heat_protection_temperature = SHOES_MAX_TEMP_PROTECT - /obj/item/clothing/shoes/sandal desc = "A pair of rather plain, wooden sandals." name = "sandals" diff --git a/code/modules/clothing/spacesuits/miscellaneous.dm b/code/modules/clothing/spacesuits/miscellaneous.dm index c9ef68af849..03bf0279300 100644 --- a/code/modules/clothing/spacesuits/miscellaneous.dm +++ b/code/modules/clothing/spacesuits/miscellaneous.dm @@ -186,4 +186,26 @@ desc = "A lightweight space helmet with the basic ability to protect the wearer from the vacuum of space during emergencies." flash_protect = 0 flags_inv = HIDEMASK|HIDEEARS|HIDEEYES - armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 100, rad = 20) \ No newline at end of file + armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 100, rad = 20) + +/obj/item/clothing/head/helmet/space/freedom + name = "eagle helmet" + desc = "An advanced, space-proof helmet. It appears to be modeled after an old-world eagle." + icon_state = "griffinhat" + item_state = "griffinhat" + armor = list(melee = 40, bullet = 40, laser = 30, energy = 25, bomb = 100, bio = 100, rad = 100) + strip_delay = 130 + max_heat_protection_temperature = FIRE_IMMUNITY_HELM_MAX_TEMP_PROTECT + unacidable = 1 + +/obj/item/clothing/suit/space/freedom + name = "eagle suit" + desc = "An advanced, light suit, fabricated from a mixture of synthetic feathers and space-resistant material. A gun holster appears to be intergrated into the suit and the wings appear to be stuck in 'freedom' mode." + icon_state = "freedom" + item_state = "freedom" + allowed = list(/obj/item/weapon/gun,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/restraints/handcuffs,/obj/item/weapon/tank/internals) + armor = list(melee = 40, bullet = 40, laser = 30,energy = 25, bomb = 100, bio = 100, rad = 100) + slowdown = 1 + strip_delay = 130 + max_heat_protection_temperature = FIRE_IMMUNITY_HELM_MAX_TEMP_PROTECT + unacidable = 1 diff --git a/code/modules/clothing/spacesuits/ninja.dm b/code/modules/clothing/spacesuits/ninja.dm deleted file mode 100644 index 9c6c98d6396..00000000000 --- a/code/modules/clothing/spacesuits/ninja.dm +++ /dev/null @@ -1,65 +0,0 @@ -/obj/item/clothing/head/helmet/space/space_ninja - desc = "What may appear to be a simple black garment is in fact a highly sophisticated nano-weave helmet. Standard issue ninja gear." - name = "ninja hood" - icon_state = "s-ninja" - item_state = "s-ninja_mask" - armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 30, rad = 25) - strip_delay = 12 - unacidable = 1 - - -/obj/item/clothing/suit/space/space_ninja - name = "ninja suit" - desc = "A unique, vaccum-proof suit of nano-enhanced armor designed specifically for Spider Clan assassins." - icon_state = "s-ninja" - item_state = "s-ninja_suit" - allowed = list(/obj/item/weapon/gun,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/restraints/handcuffs,/obj/item/weapon/tank/internals,/obj/item/weapon/stock_parts/cell) - slowdown = 0 - unacidable = 1 - armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 30, rad = 30) - strip_delay = 12 - - //Important parts of the suit. - var/mob/living/carbon/affecting = null//The wearer. - var/obj/item/weapon/stock_parts/cell/cell//Starts out with a high-capacity cell using New(). - var/datum/effect/effect/system/spark_spread/spark_system//To create sparks. - var/reagent_list[] = list("omnizine","salbutamol","spaceacillin","charcoal","nutriment","radium","potass_iodide")//The reagents ids which are added to the suit at New(). - var/stored_research[]//For stealing station research. - var/obj/item/weapon/disk/tech_disk/t_disk//To copy design onto disk. - - //Other articles of ninja gear worn together, used to easily reference them after initializing. - var/obj/item/clothing/head/helmet/space/space_ninja/n_hood - var/obj/item/clothing/shoes/space_ninja/n_shoes - var/obj/item/clothing/gloves/space_ninja/n_gloves - - //Main function variables. - var/s_initialized = 0//Suit starts off. - var/s_coold = 0//If the suit is on cooldown. Can be used to attach different cooldowns to abilities. Ticks down every second based on suit ntick(). - var/s_cost = 5.0//Base energy cost each ntick. - var/s_acost = 25.0//Additional cost for additional powers active. - var/k_cost = 200.0//Kamikaze energy cost each ntick. - var/k_damage = 1.0//Brute damage potentially done by Kamikaze each ntick. - var/s_delay = 40.0//How fast the suit does certain things, lower is faster. Can be overridden in specific procs. Also determines adverse probability. - var/a_transfer = 20.0//How much reagent is transferred when injecting. - var/r_maxamount = 80.0//How much reagent in total there is. - - //Support function variables. - var/spideros = 0//Mode of SpiderOS. This can change so I won't bother listing the modes here (0 is hub). Check ninja_equipment.dm for how it all works. - var/s_active = 0//Stealth off. - var/s_busy = 0//Is the suit busy with a process? Like AI hacking. Used for safety functions. - var/kamikaze = 0//Kamikaze on or off. - var/k_unlock = 0//To unlock Kamikaze. - - //Ability function variables. - var/s_bombs = 10.0//Number of starting ninja smoke bombs. - var/a_boost = 3.0//Number of adrenaline boosters. - - //Onboard AI related variables. - - var/obj/item/device/aicard/NAI //Integrated intellicard. - - var/obj/item/device/paicard/pai//A slot for a pAI device - - var/obj/effect/overlay/hologram//Is the AI hologram on or off? Visible only to the wearer of the suit. This works by attaching an image to a blank overlay. - - var/s_control = 1//If user in control of the suit. diff --git a/code/modules/clothing/suits/armor.dm b/code/modules/clothing/suits/armor.dm index ff4daf648d0..d5ee7e59bcc 100644 --- a/code/modules/clothing/suits/armor.dm +++ b/code/modules/clothing/suits/armor.dm @@ -91,10 +91,9 @@ item_state = "armor_reflec" blood_overlay_type = "armor" armor = list(melee = 10, bullet = 10, laser = 80, energy = 50, bomb = 0, bio = 0, rad = 0) - reflect_chance = 40 + var/hit_reflect_chance = 40 /obj/item/clothing/suit/armor/laserproof/IsReflect(var/def_zone) - var/hit_reflect_chance = reflect_chance if(!(def_zone in list("chest", "groin"))) //If not shot where ablative is covering you, you don't get the reflection bonus! hit_reflect_chance = 0 if (prob(hit_reflect_chance)) diff --git a/code/modules/clothing/under/miscellaneous.dm b/code/modules/clothing/under/miscellaneous.dm index 72e8be76e3f..bec82edc7fe 100644 --- a/code/modules/clothing/under/miscellaneous.dm +++ b/code/modules/clothing/under/miscellaneous.dm @@ -14,6 +14,14 @@ item_state = "w_suit" can_adjust = 0 +/obj/item/clothing/under/patriotsuit + name = "Patriotic Suit" + desc = "Motorcycle not included." + icon_state = "ek" + item_state = "ek" + item_color = "ek" + can_adjust = 0 + /obj/item/clothing/under/sl_suit desc = "It's a very amish looking suit." name = "amish suit" diff --git a/code/modules/crafting/recipes.dm b/code/modules/crafting/recipes.dm index dfc441d15e2..ef5c30fd07c 100644 --- a/code/modules/crafting/recipes.dm +++ b/code/modules/crafting/recipes.dm @@ -5,7 +5,7 @@ var/tools[] = list() //type paths of items needed but not consumed var/time = 30 //time in deciseconds var/parts[] = list() //type paths of items that will be placed in the result - var/chem_catalists[] = list() //like tools but for reagents + var/chem_catalysts[] = list() //like tools but for reagents /datum/table_recipe/IED @@ -87,7 +87,9 @@ result = /obj/item/weapon/flamethrower reqs = list(/obj/item/weapon/weldingtool = 1, /obj/item/device/assembly/igniter = 1, - /obj/item/stack/rods = 2) + /obj/item/stack/rods = 1) + parts = list(/obj/item/device/assembly/igniter = 1, + /obj/item/weapon/weldingtool = 1) tools = list(/obj/item/weapon/screwdriver) time = 20 diff --git a/code/modules/crafting/table.dm b/code/modules/crafting/table.dm index 1d4bfa561e9..749648f43fd 100644 --- a/code/modules/crafting/table.dm +++ b/code/modules/crafting/table.dm @@ -17,11 +17,22 @@ if(table_contents[B] >= R.reqs[A]) continue main_loop return 0 - for(var/A in R.chem_catalists) - if(table_contents[A] < R.chem_catalists[A]) + for(var/A in R.chem_catalysts) + if(table_contents[A] < R.chem_catalysts[A]) return 0 return 1 +/obj/structure/table/proc/partial_check_contents(datum/table_recipe/R) + check_table() + var/required_amount = max(round(R.reqs.len/2), 1) + var/amount = 0 + for(var/A in R.reqs) + for(var/B in table_contents) + if(ispath(B, A)) + amount += 1 + if(amount >= required_amount) + return 1 + /obj/structure/table/proc/check_table() table_contents = list() for(var/obj/item/I in loc) @@ -164,11 +175,46 @@ dat += "Crafting in progress..." else for(var/datum/table_recipe/R in table_recipes) + var/name_text = "" + var/req_text = "" + var/tool_text = "" + var/catalist_text = "" if(check_contents(R)) - dat += "[R.name]
" + name_text ="[R.name]" + + else if(partial_check_contents(R)) + name_text = "[R.name]" + + if(name_text) + for(var/A in R.reqs) + if(ispath(A, /obj)) + var/obj/O = new A + req_text += " [R.reqs[A]] [O.name]" + qdel(O) + if(ispath(A, /datum/reagent)) + var/datum/reagent/RE = new A + req_text += " [R.reqs[A]] [RE.name]" + qdel(RE) + + if(R.chem_catalysts.len) + catalist_text += ", Catalysts:" + for(var/C in R.chem_catalysts) + if(ispath(C, /datum/reagent)) + var/datum/reagent/RE = new C + catalist_text += " [R.chem_catalysts[C]] [RE.name]" + qdel(RE) + if(R.tools.len) + tool_text += ", Tools:" + for(var/O in R.tools) + if(ispath(O, /obj)) + var/obj/T = new O + tool_text += " [R.tools[O]] [T.name]" + qdel(T) + + dat += "[name_text][req_text][tool_text][catalist_text]
" dat += "" - var/datum/browser/popup = new(user, "table", "Table", 300, 300) + var/datum/browser/popup = new(user, "table", "Table", 500, 500) popup.set_content(dat) popup.open() return diff --git a/code/modules/events/ninja.dm b/code/modules/events/ninja.dm deleted file mode 100644 index fba9d8a692c..00000000000 --- a/code/modules/events/ninja.dm +++ /dev/null @@ -1,2436 +0,0 @@ -//Note to future generations: I didn't write this god-awful code I just ported it to the event system and tried to make it less moon-speaky. -//Don't judge me D; ~Carn - -/datum/round_event_control/ninja - name = "Space Ninja" - typepath = /datum/round_event/ninja - max_occurrences = 1 - earliest_start = 30000 // 1 hour - -/datum/round_event/ninja - var/success_spawn = 0 - - var/helping_station - var/key - var/spawn_loc - var/mission - - var/mob/living/carbon/human/Ninja - -/datum/round_event/ninja/setup() - helping_station = rand(0,1) - -/datum/round_event/ninja/kill() - if(!success_spawn && control) - control.occurrences-- - return ..() - -/datum/round_event/ninja/start() - //selecting a spawn_loc - if(!spawn_loc) - var/list/spawn_locs = list() - for(var/obj/effect/landmark/L in landmarks_list) - if(isturf(L.loc)) - switch(L.name) - if("ninjaspawn","carpspawn") - spawn_locs += L.loc - if(!spawn_locs.len) - return kill() - spawn_loc = pick(spawn_locs) - if(!spawn_loc) - return kill() - - //selecting a candidate player - if(!key) - var/list/candidates = get_candidates(BE_NINJA) - if(!candidates.len) - return kill() - var/client/C = pick(candidates) - key = C.key - if(!key) - return kill() - - //We prepare the mind before we spawn the ninja mob, so we cannot simply do mob.key = key then modify the mind. - //instead we make the mind and modify it, then make sure it is active and mind.transfer_to(mob) - //alternatively we could do mob.mind = mind;mob.key=key - var/datum/mind/Mind = create_ninja_mind(key) - Mind.active = 1 - - //generate objectives - You'll generally get 6 objectives (Ninja is meant to be hardmode!) - if(mission) - var/datum/objective/O = new /datum/objective(mission) - O.owner = Mind - Mind.objectives += O - else - if(helping_station) //DS are the highest priority (if we're a helpful ninja) - for(var/datum/mind/M in ticker.minds) - if(M.current && M.current.stat != DEAD) - if(M.special_role == "Death Commando") - var/datum/objective/assassinate/O = new /datum/objective/assassinate() - O.owner = Mind - O.target = M - O.explanation_text = "Slay \the [M.current.real_name], the Death Commando." - Mind.objectives += O - - else //Xenos are the highest priority (if we're not so helpful) Although this makes zero sense at all... - for(var/mob/living/carbon/alien/humanoid/queen/Q in player_list) - if(Q.mind && Q.stat != DEAD) - var/datum/objective/assassinate/O = new /datum/objective/assassinate() - O.owner = Mind - O.target = Q.mind - O.explanation_text = "Slay \the [Q.real_name]." - Mind.objectives += O - - if(Mind.objectives.len < 4) //not enough objectives still! - var/list/possible_targets = list() - for(var/datum/mind/M in ticker.minds) - if(M.current && M.current.stat != DEAD) - if(istype(M.current,/mob/living/carbon/human)) - if(M.special_role) - possible_targets[M] = 0 //bad-guy - else if(M.assigned_role in command_positions) - possible_targets[M] = 1 //good-guy - - var/list/objectives = list(1,2,3,4) - while(Mind.objectives.len < 4) //still not enough objectives! - switch(pick_n_take(objectives)) - if(1) //research - var/datum/objective/download/O = new /datum/objective/download() - O.owner = Mind - O.gen_amount_goal() - Mind.objectives += O - - if(2) //steal - var/datum/objective/steal/special/O = new /datum/objective/steal/special() - O.owner = Mind - Mind.objectives += O - - if(3) //protect/kill - if(!possible_targets.len) continue - var/selected = rand(1,possible_targets.len) - var/datum/mind/M = possible_targets[selected] - var/is_bad_guy = possible_targets[M] - possible_targets.Cut(selected,selected+1) - - if(is_bad_guy ^ helping_station) //kill (good-ninja + bad-guy or bad-ninja + good-guy) - var/datum/objective/assassinate/O = new /datum/objective/assassinate() - O.owner = Mind - O.target = M - O.explanation_text = "Slay \the [M.current.real_name], the [M.assigned_role]." - Mind.objectives += O - else //protect - var/datum/objective/protect/O = new /datum/objective/protect() - O.owner = Mind - O.target = M - O.explanation_text = "Protect \the [M.current.real_name], the [M.assigned_role], from harm." - Mind.objectives += O - if(4) //debrain/capture - if(!possible_targets.len) continue - var/selected = rand(1,possible_targets.len) - var/datum/mind/M = possible_targets[selected] - var/is_bad_guy = possible_targets[M] - possible_targets.Cut(selected,selected+1) - - if(is_bad_guy ^ helping_station) //debrain (good-ninja + bad-guy or bad-ninja + good-guy) - var/datum/objective/debrain/O = new /datum/objective/debrain() - O.owner = Mind - O.target = M - O.explanation_text = "Steal the brain of [M.current.real_name]." - Mind.objectives += O - else //capture - var/datum/objective/capture/O = new /datum/objective/capture() - O.owner = Mind - O.gen_amount_goal() - Mind.objectives += O - else - break - - //Add a survival objective since it's usually broad enough for any round type. - var/datum/objective/O = new /datum/objective/survive() - O.owner = Mind - Mind.objectives += O - - //Finally, add their RP-directive - var/directive = generate_ninja_directive() - O = new /datum/objective(directive) //making it an objective so admins can reward the for completion - O.owner = Mind - Mind.objectives += O - - //add some RP-fluff - Mind.store_memory("I am an elite mercenary assassin of the mighty Spider Clan. A SPACE NINJA!") - Mind.store_memory("Suprise is my weapon. Shadows are my armor. Without them, I am nothing. (//initialize your suit by right clicking on it, to use abilities like stealth)!") - Mind.store_memory("Officially, [helping_station?"Nanotrasen":"The Syndicate"] are my employer.") - - //spawn the ninja and assign the candidate - Ninja = create_space_ninja(spawn_loc) - Mind.transfer_to(Ninja) - - //initialise equipment - Ninja.wear_suit:randomize_param() - Ninja.internal = Ninja.s_store - if(Ninja.internals) - Ninja.internals.icon_state = "internal1" - - if(Ninja.mind != Mind) //something has gone wrong! - ERROR("The ninja wasn't assigned the right mind. ;ç;") - - Ninja << sound('sound/effects/ninja_greeting.ogg') //so ninja you probably wouldn't even know if you were made one - - success_spawn = 1 - -/* -This proc will give the ninja a directive to follow. They are not obligated to do so but it's a fun roleplay reminder. -Making this random or semi-random will probably not work without it also being incredibly silly. -As such, it's hard-coded for now. No reason for it not to be, really. -*/ -/datum/round_event/ninja/proc/generate_ninja_directive() - switch(rand(1,13)) - if(1) return "The Spider Clan must not be linked to this operation. Remain as hidden and covert as possible." - if(2) return "[station_name] is financed by an enemy of the Spider Clan. Cause as much structural damage as possible." - if(3) return "A wealthy animal rights activist has made a request we cannot refuse. Prioritize saving animal lives whenever possible." - if(4) return "The Spider Clan absolutely cannot be linked to this operation. Eliminate all witnesses using most extreme prejudice." - if(5) return "We are currently negotiating with Nanotrasen command. Prioritize saving human lives over ending them." - if(6) return "We are engaged in a legal dispute over [station_name]. If a laywer is present on board, force their cooperation in the matter." - if(7) return "A financial backer has made an offer we cannot refuse. Implicate Syndicate involvement in the operation." - if(8) return "Let no one question the mercy of the Spider Clan. Ensure the safety of all non-essential personnel you encounter." - if(9) return "A free agent has proposed a lucrative business deal. Implicate Nanotrasen involvement in the operation." - if(10) return "Our reputation is on the line. Harm as few civilians or innocents as possible." - if(11) return "Our honor is on the line. Utilize only honorable tactics when dealing with opponents." - if(12) return "We are currently negotiating with a Syndicate leader. Disguise assassinations as suicide or another natural cause." - else return "There are no special supplemental instructions at this time." - -/* -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -+++++++++++++++++++++++++++++++++++++// //++++++++++++++++++++++++++++++++++ -======================================SPACE NINJA SETUP==================================== -___________________________________________________________________________________________ -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -*/ - -/* - README: - - Data: - - >> space_ninja.dm << is this file. It contains a variety of procs related to either spawning space ninjas, - modifying their verbs, various help procs, testing debug-related content, or storing unused procs for later. - Similar functions should go into this file, along with anything else that may not have an explicit category. - IMPORTANT: actual ninja suit, gloves, etc, are stored under the appropriate clothing files. If you need to change - variables or look them up, look there. Easiest way is through the map file browser. - - >> ninja_abilities.dm << contains all the ninja-related powers. Spawning energy swords, teleporting, and the like. - If more powers are added, or perhaps something related to powers, it should go there. Make sure to describe - what an ability/power does so it's easier to reference later without looking at the code. - IMPORTANT: verbs are still somewhat funky to work with. If an argument is specified but is not referenced in a way - BYOND likes, in the code content, the verb will fail to trigger. Nothing will happen, literally, when clicked. - This can be bypassed by either referencing the argument properly, or linking to another proc with the argument - attached. The latter is what I like to do for certain cases--sometimes it's necessary to do that regardless. - - >> ninja_equipment.dm << deals with all the equipment-related procs for a ninja. Primarily it has the suit, gloves, - and mask. The suit is by far the largest section of code out of the three and includes a lot of code that ties in - to other functions. This file has gotten kind of large so breaking it up may be in order. I use section hearders. - IMPORTANT: not much to say here. Follow along with the comments and adding new functions should be a breeze. Also - know that certain equipment pieces are linked in other files. The energy blade, for example, has special - functions defined in the appropriate files (airlock, securestorage, etc). - - General Notes: - - I created space ninjas with the expressed purpose of spicing up boring rounds. That is, ninjas are to xenos as marauders are to - death squads. Ninjas are stealthy, tech-savvy, and powerful. Not to say marauders are all of those things, but a clever ninja - should have little problem murderampaging their way through just about anything. Short of admin wizards maybe. - HOWEVER! - Ninjas also have a fairly great weakness as they require energy to use abilities. If, theoretically, there is a game - mode based around space ninjas, make sure to account for their energy needs. - - Admin Notes: - - Ninjas are not admin PCs--please do not use them for that purpose. They are another way to participate in the game post-death, - like pais, xenos, death squads, and cyborgs. - I'm currently looking for feedback from regular players since beta testing is largely done. I would appreciate if - you spawned regular players as ninjas when rounds are boring. Or exciting, it's all good as long as there is feedback. - You can also spawn ninja gear manually if you want to. - - How to do that: - Make sure your character has a mind. - Change their assigned_role to "MODE", no quotes. Otherwise, the suit won't initialize. - Change their special_role to "Space Ninja", no quotes. Otherwise, the character will be gibbed. - Spawn ninja gear, put it on, hit initialize. Let the suit do the rest. You are now a space ninja. - I don't recommend messing with suit variables unless you really know what you're doing. - - Miscellaneous Notes: - - Potential Upgrade Tree: - Energy Shield: - Extra Ability - Syndicate Shield device? - Works like the force wall spell, except can be kept indefinitely as long as energy remains. Toggled on or off. - Would block bullets and the like. - Phase Shift - Extra Ability - Advanced Sensors? - Instead of being unlocked at the start, Phase Shieft would become available once requirements are met. - Uranium-based Recharger: - Suit Upgrade - Unsure - Instead of losing energy each second, the suit would regain the same amount of energy. - This would not count in activating stealth and similar. - Extended Battery Life: - Suit Upgrade - Battery of higher capacity - Already implemented. Replace current battery with one of higher capacity. - Advanced Cloak-Tech device. - Suit Upgrade - Syndicate Cloaking Device? - Remove cloak failure rate. -*/ - - -//=======//CURRENT PLAYER VERB//=======// - -/client/proc/cmd_admin_ninjafy(var/mob/living/carbon/human/H in player_list) - set category = null - set name = "Make Space Ninja" - - if(!ticker) - alert("Wait until the game starts") - return - - if(!istype(H)) - return - - if(alert(src, "You sure?", "Confirm", "Yes", "No") != "Yes") - return - - log_admin("[key_name(src)] turned [H.key] into a Space Ninja.") - H.mind = create_ninja_mind(H.key) - H.mind_initialize() - H.equip_space_ninja(1) - if(istype(H.wear_suit, /obj/item/clothing/suit/space/space_ninja)) - H.wear_suit:randomize_param() - spawn(0) - H.wear_suit:ninitialize(10,H) - -//=======//CURRENT GHOST VERB//=======// - -/client/proc/send_space_ninja() - set category = "Fun" - set name = "Spawn Space Ninja" - set desc = "Spawns a space ninja for when you need a teenager with attitude." - set popup_menu = 0 - - if(!holder) - src << "Only administrators may use this command." - return - if(!ticker.mode) - alert("The game hasn't started yet!") - return - if(alert("Are you sure you want to send in a space ninja?",,"Yes","No")=="No") - return - - var/mission = copytext(sanitize(input(src, "Please specify which mission the space ninja shall undertake.", "Specify Mission", null) as text|null),1,MAX_MESSAGE_LEN) - - var/client/C = input("Pick character to spawn as the Space Ninja", "Key", "") as null|anything in clients - if(!C) - return - - var/datum/round_event/ninja/E = new /datum/round_event/ninja() - E.key=C.key - E.mission=mission - - message_admins("[key_name_admin(key)] has spawned [key_name_admin(C.key)] as a Space Ninja.") - log_admin("[key] used Spawn Space Ninja.") - - return - -//=======//NINJA CREATION PROCS//=======// - -/proc/create_space_ninja(spawn_loc) - var/mob/living/carbon/human/new_ninja = new(spawn_loc) - if(prob(50)) new_ninja.gender = "female" - var/datum/preferences/A = new()//Randomize appearance for the ninja. - A.real_name = "[pick(ninja_titles)] [pick(ninja_names)]" - A.copy_to(new_ninja) - ready_dna(new_ninja) - new_ninja.equip_space_ninja() - return new_ninja - -/mob/living/carbon/human/proc/equip_space_ninja(safety=0)//Safety in case you need to unequip stuff for existing characters. - if(safety) - qdel(w_uniform) - qdel(wear_suit) - qdel(wear_mask) - qdel(head) - qdel(shoes) - qdel(gloves) - - var/obj/item/device/radio/R = new /obj/item/device/radio/headset(src) - equip_to_slot_or_del(R, slot_ears) - equip_to_slot_or_del(new /obj/item/clothing/under/color/black(src), slot_w_uniform) - equip_to_slot_or_del(new /obj/item/clothing/shoes/space_ninja(src), slot_shoes) - equip_to_slot_or_del(new /obj/item/clothing/suit/space/space_ninja(src), slot_wear_suit) - equip_to_slot_or_del(new /obj/item/clothing/gloves/space_ninja(src), slot_gloves) - equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/space_ninja(src), slot_head) - equip_to_slot_or_del(new /obj/item/clothing/mask/gas/voice/space_ninja(src), slot_wear_mask) - equip_to_slot_or_del(new /obj/item/clothing/glasses/night(src), slot_glasses) - equip_to_slot_or_del(new /obj/item/device/flashlight(src), slot_belt) - equip_to_slot_or_del(new /obj/item/weapon/c4(src), slot_r_store) - equip_to_slot_or_del(new /obj/item/weapon/c4(src), slot_l_store) - equip_to_slot_or_del(new /obj/item/weapon/tank/internals/emergency_oxygen(src), slot_s_store) - equip_to_slot_or_del(new /obj/item/weapon/tank/jetpack/carbondioxide(src), slot_back) - - var/obj/item/weapon/implant/explosive/E = new/obj/item/weapon/implant/explosive(src) - E.imp_in = src - E.implanted = 1 - E.implanted(src) - return 1 - -//=======//HELPER PROCS//=======// - -//Randomizes suit parameters. -/obj/item/clothing/suit/space/space_ninja/proc/randomize_param() - s_cost = rand(1,20) - s_acost = rand(20,100) - k_cost = rand(100,500) - k_damage = rand(1,20) - s_delay = rand(10,100) - s_bombs = rand(5,20) - a_boost = rand(1,7) - -//This proc prevents the suit from being taken off. -/obj/item/clothing/suit/space/space_ninja/proc/lock_suit(mob/living/carbon/U, X = 0) - if(X)//If you want to check for icons. - icon_state = U.gender==FEMALE ? "s-ninjanf" : "s-ninjan" - U:gloves.icon_state = "s-ninjan" - U:gloves.item_state = "s-ninjan" - else - if(U.mind.special_role!="Space Ninja") - U << "\red fÄTaL ÈÈRRoR: 382200-*#00CÖDE RED\nUNAU†HORIZED USÈ DETÈC†††eD\nCoMMÈNCING SUB-R0U†IN3 13...\nTÈRMInATING U-U-USÈR..." - U.gib() - return 0 - if(!istype(U:head, /obj/item/clothing/head/helmet/space/space_ninja)) - U << "ERROR: 100113 UNABLE TO LOCATE HEAD GEAR\nABORTING..." - return 0 - if(!istype(U:shoes, /obj/item/clothing/shoes/space_ninja)) - U << "ERROR: 122011 UNABLE TO LOCATE FOOT GEAR\nABORTING..." - return 0 - if(!istype(U:gloves, /obj/item/clothing/gloves/space_ninja)) - U << "ERROR: 110223 UNABLE TO LOCATE HAND GEAR\nABORTING..." - return 0 - - affecting = U - flags |= NODROP //colons make me go all |= - slowdown = 0 - n_hood = U:head - n_hood.flags |= NODROP - n_shoes = U:shoes - n_shoes.flags |= NODROP - n_shoes.slowdown-- - n_gloves = U:gloves - n_gloves.flags |= NODROP - - return 1 - -//This proc allows the suit to be taken off. -/obj/item/clothing/suit/space/space_ninja/proc/unlock_suit() - affecting = null - flags &= ~NODROP - slowdown = 1 - icon_state = "s-ninja" - if(n_hood)//Should be attached, might not be attached. - n_hood.flags &= ~NODROP - if(n_shoes) - n_shoes.flags &= ~NODROP - n_shoes.slowdown++ - if(n_gloves) - n_gloves.icon_state = "s-ninja" - n_gloves.item_state = "s-ninja" - n_gloves.flags &= ~NODROP - n_gloves.candrain=0 - n_gloves.draining=0 - -//Allows the mob to grab a stealth icon. -/mob/proc/NinjaStealthActive(atom/A)//A is the atom which we are using as the overlay. - invisibility = INVISIBILITY_LEVEL_TWO//Set ninja invis to 2. - var/icon/opacity_icon = new(A.icon, A.icon_state) - var/icon/alpha_mask = getIconMask(src) - var/icon/alpha_mask_2 = new('icons/effects/effects.dmi', "at_shield1") - alpha_mask.AddAlphaMask(alpha_mask_2) - opacity_icon.AddAlphaMask(alpha_mask) - for(var/i=0,i<5,i++)//And now we add it as overlays. It's faster than creating an icon and then merging it. - var/image/I = image("icon" = opacity_icon, "icon_state" = A.icon_state, "layer" = layer+0.8)//So it's above other stuff but below weapons and the like. - switch(i)//Now to determine offset so the result is somewhat blurred. - if(1) - I.pixel_x -= 1 - if(2) - I.pixel_x += 1 - if(3) - I.pixel_y -= 1 - if(4) - I.pixel_y += 1 - - overlays += I//And finally add the overlay. - overlays += image("icon"='icons/effects/effects.dmi',"icon_state" ="electricity","layer" = layer+0.9) - -//When ninja steal malfunctions. -/mob/proc/NinjaStealthMalf() - invisibility = 0//Set ninja invis to 0. - overlays += image("icon"='icons/effects/effects.dmi',"icon_state" ="electricity","layer" = layer+0.9) - playsound(loc, 'sound/effects/stealthoff.ogg', 75, 1) - -//=======//GENERIC VERB MODIFIERS//=======// - -/obj/item/clothing/suit/space/space_ninja/proc/grant_equip_verbs() - verbs -= /obj/item/clothing/suit/space/space_ninja/proc/init - verbs += /obj/item/clothing/suit/space/space_ninja/proc/deinit - verbs += /obj/item/clothing/suit/space/space_ninja/proc/spideros - verbs += /obj/item/clothing/suit/space/space_ninja/proc/stealth - n_gloves.verbs += /obj/item/clothing/gloves/space_ninja/proc/toggled - - s_initialized = 1 - -/obj/item/clothing/suit/space/space_ninja/proc/remove_equip_verbs() - verbs += /obj/item/clothing/suit/space/space_ninja/proc/init - verbs -= /obj/item/clothing/suit/space/space_ninja/proc/deinit - verbs -= /obj/item/clothing/suit/space/space_ninja/proc/spideros - verbs -= /obj/item/clothing/suit/space/space_ninja/proc/stealth - if(n_gloves) - n_gloves.verbs -= /obj/item/clothing/gloves/space_ninja/proc/toggled - - s_initialized = 0 - -/obj/item/clothing/suit/space/space_ninja/proc/grant_ninja_verbs() - verbs += /obj/item/clothing/suit/space/space_ninja/proc/ninjashift - verbs += /obj/item/clothing/suit/space/space_ninja/proc/ninjajaunt - verbs += /obj/item/clothing/suit/space/space_ninja/proc/ninjasmoke - verbs += /obj/item/clothing/suit/space/space_ninja/proc/ninjaboost - verbs += /obj/item/clothing/suit/space/space_ninja/proc/ninjapulse - verbs += /obj/item/clothing/suit/space/space_ninja/proc/ninjablade - verbs += /obj/item/clothing/suit/space/space_ninja/proc/ninjastar - verbs += /obj/item/clothing/suit/space/space_ninja/proc/ninjanet - - s_initialized=1 - slowdown=0 - -/obj/item/clothing/suit/space/space_ninja/proc/remove_ninja_verbs() - verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjashift - verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjajaunt - verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjasmoke - verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjaboost - verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjapulse - verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjablade - verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjastar - verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjanet - -//=======//KAMIKAZE VERBS//=======// - -/obj/item/clothing/suit/space/space_ninja/proc/grant_kamikaze(mob/living/carbon/U) - verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjashift - verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjajaunt - verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjapulse - verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjastar - verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjanet - - verbs += /obj/item/clothing/suit/space/space_ninja/proc/ninjaslayer - verbs += /obj/item/clothing/suit/space/space_ninja/proc/ninjawalk - verbs += /obj/item/clothing/suit/space/space_ninja/proc/ninjamirage - - verbs -= /obj/item/clothing/suit/space/space_ninja/proc/stealth - - kamikaze = 1 - - icon_state = U.gender==FEMALE ? "s-ninjakf" : "s-ninjak" - if(n_gloves) - n_gloves.icon_state = "s-ninjak" - n_gloves.item_state = "s-ninjak" - n_gloves.candrain = 0 - n_gloves.draining = 0 - n_gloves.verbs -= /obj/item/clothing/gloves/space_ninja/proc/toggled - - cancel_stealth() - - U << browse(null, "window=spideros") - U << "Do or Die, LET'S ROCK!!" - -/obj/item/clothing/suit/space/space_ninja/proc/remove_kamikaze(mob/living/carbon/U) - if(kamikaze) - verbs += /obj/item/clothing/suit/space/space_ninja/proc/ninjashift - verbs += /obj/item/clothing/suit/space/space_ninja/proc/ninjajaunt - verbs += /obj/item/clothing/suit/space/space_ninja/proc/ninjapulse - verbs += /obj/item/clothing/suit/space/space_ninja/proc/ninjastar - verbs += /obj/item/clothing/suit/space/space_ninja/proc/ninjanet - - verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjaslayer - verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjawalk - verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjamirage - - verbs += /obj/item/clothing/suit/space/space_ninja/proc/stealth - if(n_gloves) - n_gloves.verbs -= /obj/item/clothing/gloves/space_ninja/proc/toggled - - U.incorporeal_move = 0 - kamikaze = 0 - k_unlock = 0 - U << "Disengaging mode...\nCODE NAME: KAMIKAZE" - -//=======//AI VERBS//=======// - -/obj/item/clothing/suit/space/space_ninja/proc/grant_AI_verbs() - verbs += /obj/item/clothing/suit/space/space_ninja/proc/ai_hack_ninja - verbs += /obj/item/clothing/suit/space/space_ninja/proc/ai_return_control - - s_busy = 0 - s_control = 0 - -/obj/item/clothing/suit/space/space_ninja/proc/remove_AI_verbs() - verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ai_hack_ninja - verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ai_return_control - - s_control = 1 - - -//Alternate ninja speech replacement. -/*This text is hilarious but also absolutely retarded. -message = replacetext(message, "l", "r") -message = replacetext(message, "rr", "ru") -message = replacetext(message, "v", "b") -message = replacetext(message, "f", "hu") -message = replacetext(message, "'t", "") -message = replacetext(message, "t ", "to ") -message = replacetext(message, " I ", " ai ") -message = replacetext(message, "th", "z") -message = replacetext(message, "ish", "isu") -message = replacetext(message, "is", "izu") -message = replacetext(message, "ziz", "zis") -message = replacetext(message, "se", "su") -message = replacetext(message, "br", "bur") -message = replacetext(message, "ry", "ri") -message = replacetext(message, "you", "yuu") -message = replacetext(message, "ck", "cku") -message = replacetext(message, "eu", "uu") -message = replacetext(message, "ow", "au") -message = replacetext(message, "are", "aa") -message = replacetext(message, "ay", "ayu") -message = replacetext(message, "ea", "ii") -message = replacetext(message, "ch", "chi") -message = replacetext(message, "than", "sen") -message = replacetext(message, ".", "") -message = lowertext(message) -*/ - - -/* -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -+++++++++++++++++++++++++++++++++// //++++++++++++++++++++++++++++++++++ -==================================SPACE NINJA ABILITIES==================================== -___________________________________________________________________________________________ -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -*/ - -//=======//SAFETY CHECK//=======// -/* -X is optional, tells the proc to check for specific stuff. C is also optional. -All the procs here assume that the character is wearing the ninja suit if they are using the procs. -They should, as I have made every effort for that to be the case. -In the case that they are not, I imagine the game will run-time error like crazy. -s_cooldown ticks off each second based on the suit recharge proc, in seconds. Default of 1 seconds. Some abilities have no cool down. -*/ -/obj/item/clothing/suit/space/space_ninja/proc/ninjacost(C = 0,X = 0) - var/mob/living/carbon/human/U = affecting - if( (U.stat||U.incorporeal_move)&&X!=3 )//Will not return if user is using an adrenaline booster since you can use them when stat==1. - U << "You must be conscious and solid to do this."//It's not a problem of stat==2 since the ninja will explode anyway if they die. - return 1 - else if(C&&cell.chargeNot enough energy." - return 1 - switch(X) - if(1) - cancel_stealth()//Get rid of it. - if(2) - if(s_bombs<=0) - U << "There are no more smoke bombs remaining." - return 1 - if(3) - if(a_boost<=0) - U << "You do not have any more adrenaline boosters." - return 1 - return (s_coold)//Returns the value of the variable which counts down to zero. - -//=======//TELEPORT GRAB CHECK//=======// -/obj/item/clothing/suit/space/space_ninja/proc/handle_teleport_grab(turf/T, mob/living/U) - if(istype(U.get_active_hand(),/obj/item/weapon/grab))//Handles grabbed persons. - var/obj/item/weapon/grab/G = U.get_active_hand() - G.affecting.loc = locate(T.x+rand(-1,1),T.y+rand(-1,1),T.z)//variation of position. - if(istype(U.get_inactive_hand(),/obj/item/weapon/grab)) - var/obj/item/weapon/grab/G = U.get_inactive_hand() - G.affecting.loc = locate(T.x+rand(-1,1),T.y+rand(-1,1),T.z)//variation of position. - return - -//=======//SMOKE//=======// -/*Summons smoke in radius of user. -Not sure why this would be useful (it's not) but whatever. Ninjas need their smoke bombs.*/ -/obj/item/clothing/suit/space/space_ninja/proc/ninjasmoke() - set name = "Smoke Bomb" - set desc = "Blind your enemies momentarily with a well-placed smoke bomb." - set category = "Ninja Ability" - set popup_menu = 0//Will not see it when right clicking. - - if(!ninjacost(,2)) - var/mob/living/carbon/human/U = affecting - U << "There are [s_bombs] smoke bombs remaining." - var/datum/effect/effect/system/bad_smoke_spread/smoke = new /datum/effect/effect/system/bad_smoke_spread() - smoke.set_up(10, 0, U.loc) - smoke.start() - playsound(U.loc, 'sound/effects/bamf.ogg', 50, 2) - s_bombs-- - s_coold = 1 - return - -//=======//9-8 TILE TELEPORT//=======// -//Click to to teleport 9-10 tiles in direction facing. -/obj/item/clothing/suit/space/space_ninja/proc/ninjajaunt() - set name = "Phase Jaunt (10E)" - set desc = "Utilizes the internal VOID-shift device to rapidly transit in direction facing." - set category = "Ninja Ability" - set popup_menu = 0 - - var/C = 100 - if(!ninjacost(C,1)) - var/mob/living/carbon/human/U = affecting - var/turf/destination = get_teleport_loc(U.loc,U,9,1,3,1,0,1) - var/turf/mobloc = get_turf(U.loc)//To make sure that certain things work properly below. - if(destination&&istype(mobloc, /turf))//The turf check prevents unusual behavior. Like teleporting out of cryo pods, cloners, mechs, etc. - spawn(0) - playsound(U.loc, "sparks", 50, 1) - anim(mobloc,src,'icons/mob/mob.dmi',,"phaseout",,U.dir) - - handle_teleport_grab(destination, U) - U.loc = destination - - spawn(0) - spark_system.start() - playsound(U.loc, 'sound/effects/phasein.ogg', 25, 1) - playsound(U.loc, "sparks", 50, 1) - anim(U.loc,U,'icons/mob/mob.dmi',,"phasein",,U.dir) - - spawn(0) - destination.phase_damage_creatures(20,U)//Paralyse and damage mobs and mechas on the turf - s_coold = 1 - cell.charge-=(C*10) - else - U << "The VOID-shift device is malfunctioning, teleportation failed." - return - -//=======//RIGHT CLICK TELEPORT//=======// -//Right click to teleport somewhere, almost exactly like admin jump to turf. -/obj/item/clothing/suit/space/space_ninja/proc/ninjashift(turf/T in oview()) - set name = "Phase Shift (20E)" - set desc = "Utilizes the internal VOID-shift device to rapidly transit to a destination in view." - set category = null//So it does not show up on the panel but can still be right-clicked. - set src = usr.contents//Fixes verbs not attaching properly for objects. Praise the DM reference guide! - - var/C = 200 - if(!ninjacost(C,1)) - var/mob/living/carbon/human/U = affecting - var/turf/mobloc = get_turf(U.loc)//To make sure that certain things work properly below. - if((!T.density)&&istype(mobloc, /turf)) - spawn(0) - playsound(U.loc, 'sound/effects/sparks4.ogg', 50, 1) - anim(mobloc,src,'icons/mob/mob.dmi',,"phaseout",,U.dir) - - handle_teleport_grab(T, U) - U.loc = T - - spawn(0) - spark_system.start() - playsound(U.loc, 'sound/effects/phasein.ogg', 25, 1) - playsound(U.loc, 'sound/effects/sparks2.ogg', 50, 1) - anim(U.loc,U,'icons/mob/mob.dmi',,"phasein",,U.dir) - - spawn(0)//Any living mobs in teleport area are gibbed. - T.phase_damage_creatures(20,U)//Paralyse and damage mobs and mechas on the turf - s_coold = 1 - cell.charge-=(C*10) - else - U << "You cannot teleport into solid walls or from solid matter" - return - -//=======//EM PULSE//=======// -//Disables nearby tech equipment. -/obj/item/clothing/suit/space/space_ninja/proc/ninjapulse() - set name = "EM Burst (25E)" - set desc = "Disable any nearby technology with a electro-magnetic pulse." - set category = "Ninja Ability" - set popup_menu = 0 - - var/C = 250 - if(!ninjacost(C,1)) - var/mob/living/carbon/human/U = affecting - playsound(U.loc, 'sound/effects/EMPulse.ogg', 60, 2) - empulse(U, 4, 6) //Procs sure are nice. Slightly weaker than wizard's disable tch. - s_coold = 2 - cell.charge-=(C*10) - return - -//=======//ENERGY BLADE//=======// -//Summons a blade of energy in active hand. -/obj/item/clothing/suit/space/space_ninja/proc/ninjablade() - set name = "Energy Blade (5E)" - set desc = "Create a focused beam of energy in your active hand." - set category = "Ninja Ability" - set popup_menu = 0 - - var/C = 50 - if(!ninjacost(C)) - var/mob/living/carbon/human/U = affecting - if(!kamikaze) - if(!U.get_active_hand()&&!istype(U.get_inactive_hand(), /obj/item/weapon/melee/energy/blade)) - var/obj/item/weapon/melee/energy/blade/W = new() - spark_system.start() - playsound(U.loc, "sparks", 50, 1) - U.put_in_hands(W) - cell.charge-=(C*10) - else - U << "You can only summon one blade. Try dropping an item first." - else//Else you can run around with TWO energy blades. I don't know why you'd want to but cool factor remains. - if(!U.get_active_hand()) - var/obj/item/weapon/melee/energy/blade/W = new() - U.put_in_hands(W) - if(!U.get_inactive_hand()) - var/obj/item/weapon/melee/energy/blade/W = new() - U.put_in_inactive_hand(W) - spark_system.start() - playsound(U.loc, "sparks", 50, 1) - s_coold = 1 - return - -//=======//NINJA STARS//=======// -/*Shoots ninja stars at random people. -This could be a lot better but I'm too tired atm.*/ -/obj/item/clothing/suit/space/space_ninja/proc/ninjastar() - set name = "Energy Star (5E)" - set desc = "Launches an energy star at a random living target." - set category = "Ninja Ability" - set popup_menu = 0 - - var/C = 50 - if(!ninjacost(C)) - var/mob/living/carbon/human/U = affecting - var/targets[] = list()//So yo can shoot while yo throw dawg - for(var/mob/living/M in oview(loc)) - if(M.stat) continue//Doesn't target corpses or paralyzed persons. - targets.Add(M) - if(targets.len) - var/mob/living/target=pick(targets)//The point here is to pick a random, living mob in oview to shoot stuff at. - - var/turf/curloc = U.loc - var/atom/targloc = get_turf(target) - if (!targloc || !istype(targloc, /turf) || !curloc) - return - if (targloc == curloc) - return - var/obj/item/projectile/energy/dart/A = new /obj/item/projectile/energy/dart(U.loc) - A.current = curloc - A.yo = targloc.y - curloc.y - A.xo = targloc.x - curloc.x - cell.charge-=(C*10) - A.fire() - else - U << "There are no targets in view." - return - -//=======//ENERGY NET//=======// -/*Allows the ninja to capture people, I guess. -Must right click on a mob to activate.*/ -/obj/item/clothing/suit/space/space_ninja/proc/ninjanet(mob/living/carbon/M in oview())//Only living carbon mobs. - set name = "Energy Net (20E)" - set desc = "Captures a fallen opponent in a net of energy. Will teleport them to a holding facility after 30 seconds." - set category = null - set src = usr.contents - - var/C = 200 - if(!ninjacost(C,1)&&iscarbon(M)) - var/mob/living/carbon/human/U = affecting - if(M.client)//Monkeys without a client can still step_to() and bypass the net. Also, netting inactive people is lame. - //if(M)//DEBUG - if(!locate(/obj/effect/energy_net) in M.loc)//Check if they are already being affected by an energy net. - for(var/turf/T in getline(U.loc, M.loc)) - if(T.density)//Don't want them shooting nets through walls. It's kind of cheesy. - U << "You may not use an energy net through solid obstacles!" - return - spawn(0) - U.Beam(M,"n_beam",,15) - M.anchored = 1//Anchors them so they can't move. - U.say("Get over here!") - var/obj/effect/energy_net/E = new /obj/effect/energy_net(M.loc) - E.layer = M.layer+1//To have it appear one layer above the mob. - for(var/mob/O in viewers(U, 3)) - O.show_message(text("[] caught [] with an energy net!", U, M), 1) - E.affecting = M - E.master = U - spawn(0)//Parallel processing. - E.process(M) - cell.charge-=(C*10) - else - U << "They are already trapped inside an energy net." - else - U << "They will bring no honor to your Clan!" - return - -//=======//ADRENALINE BOOST//=======// -/*Wakes the user so they are able to do their thing. Also injects a decent dose of radium. -Movement impairing would indicate drugs and the like.*/ -/obj/item/clothing/suit/space/space_ninja/proc/ninjaboost() - set name = "Adrenaline Boost" - set desc = "Inject a secret chemical that will counteract all movement-impairing effect." - set category = "Ninja Ability" - set popup_menu = 0 - - if(!ninjacost(,3))//Have to make sure stat is not counted for this ability. - var/mob/living/carbon/human/U = affecting - //Wouldn't need to track adrenaline boosters if there was a miracle injection to get rid of paralysis and the like instantly. - //For now, adrenaline boosters ARE the miracle injection. Well, radium, really. - U.SetParalysis(0) - U.SetStunned(0) - U.SetWeakened(0) - /* - Due to lag, it was possible to adrenaline boost but remain helpless while life.dm resets player stat. - This lead to me and others spamming adrenaline boosters because they failed to kick in on time. - It's technically possible to come back from crit with this but it is very temporary. - Life.dm will kick the player back into unconsciosness the next process loop. - */ - U.stat = 0//At least now you should be able to teleport away or shoot ninja stars. - spawn(30)//Slight delay so the enemy does not immedietly know the ability was used. Due to lag, this often came before waking up. - U.say(pick("A CORNERED FOX IS MORE DANGEROUS THAN A JACKAL!","HURT ME MOOORRREEE!","IMPRESSIVE!")) - spawn(70) - reagents.reaction(U, 2) - reagents.trans_id_to(U, "radium", a_transfer) - U << "You are beginning to feel the after-effect of the injection." - a_boost-- - s_coold = 3 - return - -/* -=================================================================================== -<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -=================================================================================== -Or otherwise known as anime mode. Which also happens to be ridiculously powerful. -*/ - -//=======//NINJA MOVEMENT//=======// -//Also makes you move like you're on crack. -/obj/item/clothing/suit/space/space_ninja/proc/ninjawalk() - set name = "Shadow Walk" - set desc = "Combines the VOID-shift and CLOAK-tech devices to freely move between solid matter. Toggle on or off." - set category = "Ninja Ability" - set popup_menu = 0 - - var/mob/living/carbon/human/U = affecting - if(!U.incorporeal_move) - U.incorporeal_move = 2 - U << "You will now phase through solid matter." - else - U.incorporeal_move = 0 - U << "You will no-longer phase through solid matter." - return - -//=======//5 TILE TELEPORT/GIB//=======// -//Allows to kill up to five squares in a straight line. Seriously. -/obj/item/clothing/suit/space/space_ninja/proc/ninjaslayer() - set name = "Phase Slayer" - set desc = "Utilizes the internal VOID-shift device to kill all creatures in a straight line." - set category = "Ninja Ability" - set popup_menu = 0 - - if(!ninjacost()) - var/mob/living/carbon/human/U = affecting - var/turf/destination = get_teleport_loc(U.loc,U,5) - var/turf/mobloc = get_turf(U.loc)//To make sure that certain things work properly below. - if(destination&&istype(mobloc, /turf)) - U.say("Ai Satsugai!") - spawn(0) - playsound(U.loc, "sparks", 50, 1) - anim(mobloc,U,'icons/mob/mob.dmi',,"phaseout",,U.dir) - - spawn(0) - for(var/turf/T in getline(mobloc, destination)) - spawn(0) - T.phase_damage_creatures(190,U) - if(T==mobloc||T==destination) continue - spawn(0) - anim(T,U,'icons/mob/mob.dmi',,"phasein",,U.dir) - - handle_teleport_grab(destination, U) - U.loc = destination - - spawn(0) - spark_system.start() - playsound(U.loc, 'sound/effects/phasein.ogg', 25, 1) - playsound(U.loc, "sparks", 50, 1) - anim(U.loc,U,'icons/mob/mob.dmi',,"phasein",,U.dir) - s_coold = 1 - else - U << "The VOID-shift device is malfunctioning, teleportation failed." - return - -//=======//TELEPORT BEHIND MOB//=======// -/*Appear behind a randomly chosen mob while a few decoy teleports appear. -This is so anime it hurts. But that's the point.*/ -/obj/item/clothing/suit/space/space_ninja/proc/ninjamirage() - set name = "Spider Mirage" - set desc = "Utilizes the internal VOID-shift device to create decoys and teleport behind a random target." - set category = "Ninja Ability" - set popup_menu = 0 - - if(!ninjacost())//Simply checks for stat. - var/mob/living/carbon/human/U = affecting - var/targets[] - targets = new() - for(var/mob/living/M in oview(6)) - if(M.stat) continue//Doesn't target corpses or paralyzed people. - targets.Add(M) - if(targets.len) - var/mob/living/target=pick(targets) - var/locx - var/locy - var/turf/mobloc = get_turf(target.loc) - var/safety = 0 - switch(target.dir) - if(NORTH) - locx = mobloc.x - locy = (mobloc.y-1) - if(locy<1) - safety = 1 - if(SOUTH) - locx = mobloc.x - locy = (mobloc.y+1) - if(locy>world.maxy) - safety = 1 - if(EAST) - locy = mobloc.y - locx = (mobloc.x-1) - if(locx<1) - safety = 1 - if(WEST) - locy = mobloc.y - locx = (mobloc.x+1) - if(locx>world.maxx) - safety = 1 - else safety=1 - if(!safety&&istype(mobloc, /turf)) - U.say("Kumo no Shinkiro!") - var/turf/picked = locate(locx,locy,mobloc.z) - spawn(0) - playsound(U.loc, "sparks", 50, 1) - anim(mobloc,U,'icons/mob/mob.dmi',,"phaseout",,U.dir) - - spawn(0) - var/limit = 4 - for(var/turf/T in oview(5)) - if(prob(20)) - spawn(0) - anim(T,U,'icons/mob/mob.dmi',,"phasein",,U.dir) - limit-- - if(limit<=0) break - - handle_teleport_grab(picked, U) - U.loc = picked - U.dir = target.dir - - spawn(0) - spark_system.start() - playsound(U.loc, 'sound/effects/phasein.ogg', 25, 1) - playsound(U.loc, "sparks", 50, 1) - anim(U.loc,U,'icons/mob/mob.dmi',,"phasein",,U.dir) - s_coold = 1 - else - U << "The VOID-shift device is malfunctioning, teleportation failed." - else - U << "There are no targets in view." - return - - -//For the love of god,space out your code! This is a nightmare to read. - -/* -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -+++++++++++++++++++++++++++++++++// //++++++++++++++++++++++++++++++++++ -===================================SPACE NINJA EQUIPMENT=================================== -___________________________________________________________________________________________ -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -*/ - -/* -=================================================================================== -<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -=================================================================================== -*/ - -//=======//NEW AND DEL//=======// - -/obj/item/clothing/suit/space/space_ninja/New() - ..() - verbs += /obj/item/clothing/suit/space/space_ninja/proc/init//suit initialize verb - verbs += /obj/item/clothing/suit/space/space_ninja/proc/ai_instruction//for AIs - verbs += /obj/item/clothing/suit/space/space_ninja/proc/ai_holo - //verbs += /obj/item/clothing/suit/space/space_ninja/proc/display_verb_procs//DEBUG. Doesn't work. - spark_system = new()//spark initialize - spark_system.set_up(5, 0, src) - spark_system.attach(src) - stored_research = new()//Stolen research initialize. - for(var/T in typesof(/datum/tech) - /datum/tech)//Store up on research. - stored_research += new T(src) - var/reagent_amount//reagent initialize - for(var/reagent_id in reagent_list) - reagent_amount += reagent_id == "radium" ? r_maxamount+(a_boost*a_transfer) : r_maxamount//AI can inject radium directly. - reagents = new(reagent_amount) - reagents.my_atom = src - for(var/reagent_id in reagent_list) - reagent_id == "radium" ? reagents.add_reagent(reagent_id, r_maxamount+(a_boost*a_transfer)) : reagents.add_reagent(reagent_id, r_maxamount)//It will take into account radium used for adrenaline boosting. - cell = new/obj/item/weapon/stock_parts/cell/high//The suit should *always* have a battery because so many things rely on it. - cell.charge = 9000//Starting charge should not be higher than maximum charge. It leads to problems with recharging. - NAI = new(src) //ninja intellicard - -/obj/item/clothing/suit/space/space_ninja/Destroy() - if(affecting)//To make sure the window is closed. - affecting << browse(null, "window=hack spideros") - if(AI)//If there are AIs present when the ninja kicks the bucket. - killai(NAI) - if(hologram)//If there is a hologram - qdel(hologram.i_attached)//Delete it and the attached image. - qdel(hologram) - ..() - -//Simply deletes all the attachments and self, killing all related procs. -/obj/item/clothing/suit/space/space_ninja/proc/terminate() - qdel(n_hood) - qdel(n_gloves) - qdel(n_shoes) - qdel(src) - - - -/obj/item/clothing/suit/space/space_ninja/proc/killai(var/obj/item/device/aicard/NAI) - for(var/mob/living/silicon/ai/A in src) - if(A.client) - A << "Self-erase protocol dete-- *bzzzzz*" - A << browse(null, "window=hack spideros") - NAI.flush = 1 - return - - - -//=======//SUIT VERBS//=======// -//Verbs link to procs because verb-like procs have a bug which prevents their use if the arguments are not readily referenced. - -/obj/item/clothing/suit/space/space_ninja/proc/init() - set name = "Initialize Suit" - set desc = "Initializes the suit for field operation." - set category = "Ninja Equip" - - ninitialize() - return - -/obj/item/clothing/suit/space/space_ninja/proc/deinit() - set name = "De-Initialize Suit" - set desc = "Begins procedure to remove the suit." - set category = "Ninja Equip" - - if(s_control&&!s_busy) - deinitialize() - else - affecting << "The function did not trigger!" - return - -/obj/item/clothing/suit/space/space_ninja/proc/spideros() - set name = "Display SpiderOS" - set desc = "Utilize built-in computer system." - set category = "Ninja Equip" - - if(s_control&&!s_busy&&!kamikaze) - display_spideros() - else - affecting << "The interface is locked!" - return - -/obj/item/clothing/suit/space/space_ninja/proc/stealth() - set name = "Toggle Stealth" - set desc = "Utilize the internal CLOAK-tech device to activate or deactivate stealth-camo." - set category = "Ninja Equip" - - if(s_control&&!s_busy) - toggle_stealth() - else - affecting << "Stealth does not appear to work!" - return - -//=======//PROCESS PROCS//=======// - -/obj/item/clothing/suit/space/space_ninja/proc/ntick(mob/living/carbon/human/U = affecting) - set background = BACKGROUND_ENABLED - - //Runs in the background while the suit is initialized. - spawn while(cell.charge>=0) - - //Let's check for some safeties. - if(s_initialized&&!affecting) terminate()//Kills the suit and attached objects. - if(!s_initialized) return//When turned off the proc stops. - for(var/mob/living/silicon/ai/A in NAI) - if(A&&A.stat==2)//If there is an AI and it's ded. Shouldn't happen without purging, could happen. - if(!s_control) - ai_return_control()//Return control to ninja if the AI was previously in control. - - //Now let's do the normal processing. - if(s_coold) s_coold--//Checks for ability s_cooldown first. - var/A = s_cost//s_cost is the default energy cost each ntick, usually 5. - if(!kamikaze) - if(blade_check(U))//If there is a blade held in hand. - A += s_acost - if(s_active)//If stealth is active. - A += s_acost - else - if(prob(s_delay))//Suit delay is used as probability. May change later. - U.adjustBruteLoss(k_damage)//Default damage done, usually 1. - A = k_cost//kamikaze cost. - cell.charge-=A - if(cell.charge<=0) - if(kamikaze) - U.say("I DIE TO LIVE AGAIN!") - U << browse(null, "window=spideros")//Just in case. - U.death() - return - cell.charge=0 - cancel_stealth() - sleep(10)//Checks every second. - -//=======//INITIALIZE//=======// - -/obj/item/clothing/suit/space/space_ninja/proc/ninitialize(delay = s_delay, mob/living/carbon/human/U = loc) - if(U.mind && U.mind.assigned_role=="MODE" && !s_initialized && !s_busy)//Shouldn't be busy... but anything is possible I guess. - s_busy = 1 - for(var/i,i<7,i++) - switch(i) - if(0) - U << "Now initializing..." - if(1) - if(!lock_suit(U))//To lock the suit onto wearer. - break - U << "Securing external locking mechanism...\nNeural-net established." - if(2) - U << "Extending neural-net interface...\nNow monitoring brain wave pattern..." - if(3) - if(U.stat==2||U.health<=0) - U << "FĆAL �Rr�R: 344--93#�&&21 BR��N |/|/aV� PATT$RN RED\nA-A-aB�rT�NG..." - unlock_suit() - break - lock_suit(U,1)//Check for icons. - U.regenerate_icons() - U << " Linking neural-net interface...\nPattern\green GREEN, continuing operation." - if(4) - U << "VOID-shift device status: ONLINE.\nCLOAK-tech device status: ONLINE." - if(5) - U << "Primary system status: ONLINE.\nBackup system status: ONLINE.\nCurrent energy capacity: [cell.charge]." - if(6) - U << "All systems operational. Welcome to SpiderOS, [U.real_name]." - grant_ninja_verbs() - grant_equip_verbs() - ntick() - sleep(delay) - s_busy = 0 - else - if(!U.mind||U.mind.assigned_role!="MODE")//Your run of the mill persons shouldn't know what it is. Or how to turn it on. - U << "You do not understand how this suit functions. Where the heck did it even come from?" - else if(s_initialized) - U << "The suit is already functioning. Please report this bug." - else - U << "ERROR: You cannot use this function at this time." - return - -//=======//DEINITIALIZE//=======// - -/obj/item/clothing/suit/space/space_ninja/proc/deinitialize(delay = s_delay) - if(affecting==loc&&!s_busy) - var/mob/living/carbon/human/U = affecting - if(!s_initialized) - U << "The suit is not initialized. Please report this bug." - return - if(alert("Are you certain you wish to remove the suit? This will take time and remove all abilities.",,"Yes","No")=="No") - return - if(s_busy || NAI.flush) - U << "ERROR: You cannot use this function at this time." - return - s_busy = 1 - for(var/i = 0,i<7,i++) - switch(i) - if(0) - U << "Now de-initializing..." - remove_kamikaze(U)//Shutdowns kamikaze. - spideros = 0//Spideros resets. - if(1) - U << "Logging off, [U:real_name]. Shutting down SpiderOS." - remove_ninja_verbs() - if(2) - U << "Primary system status: OFFLINE.\nBackup system status: OFFLINE." - if(3) - U << "VOID-shift device status: OFFLINE.\nCLOAK-tech device status: OFFLINE." - cancel_stealth()//Shutdowns stealth. - if(4) - U << "Disconnecting neural-net interface...\greenSuccess." - if(5) - U << "Disengaging neural-net interface...\greenSuccess." - if(6) - U << "Unsecuring external locking mechanism...\nNeural-net abolished.\nOperation status: FINISHED." - blade_check(U,2) - remove_equip_verbs() - unlock_suit() - U.regenerate_icons() - sleep(delay) - s_busy = 0 - return - -//=======//SPIDEROS PROC//=======// - -/obj/item/clothing/suit/space/space_ninja/proc/display_spideros() - if(!affecting) return//If no mob is wearing the suit. I almost forgot about this variable. - var/mob/living/carbon/human/U = affecting - var/mob/living/silicon/ai/A = AI - var/display_to = s_control ? U : A//Who do we want to display certain messages to? - - var/dat = "SpiderOS" - dat += " Refresh" - if(spideros) - dat += " | Return" - dat += " | Close" - dat += "
" - if(s_control) - dat += "

SpiderOS v.1.337

" - dat += "Welcome, [U.real_name].
" - else - dat += "

SpiderOS v.ERR-RR00123

" - dat += "
" - dat += " Current Time: [worldtime2text()]
" - dat += " Battery Life: [round(cell.charge/100)]%
" - dat += " Smoke Bombs: \Roman [s_bombs]
" - dat += " pai Device: " - if(pai) - dat += "Configure" - dat += " | " - dat += "Eject" - else - dat += "None Detected" - dat += "

" - - switch(spideros) - if(0) - dat += "

Available Functions:

" - dat += "" - if(3) - dat += "

Medical Report:

" - if(U.dna) - dat += "Fingerprints: [md5(U.dna.uni_identity)]
" - dat += "Unique identity: [U.dna.unique_enzymes]
" - dat += "

Overall Status: [U.stat > 1 ? "dead" : "[U.health]% healthy"]

" - dat += "

Nutrition Status: [U.nutrition]

" - dat += "Oxygen loss: [U.getOxyLoss()]" - dat += " | Toxin levels: [U.getToxLoss()]
" - dat += "Burn severity: [U.getFireLoss()]" - dat += " | Brute trauma: [U.getBruteLoss()]
" - dat += "Radiation Level: [U.radiation] rad
" - dat += "Body Temperature: [U.bodytemperature-T0C]°C ([U.bodytemperature*1.8-459.67]°F)
" - - for(var/datum/disease/D in U.viruses) - dat += "Warning: Virus Detected. Name: [D.name].Type: [D.spread_text]. Stage: [D.stage]/[D.max_stages]. Possible Cure: [D.cure_text].
" - dat += "" - if(1) - dat += "

Atmospheric Scan:

"//Headers don't need breaks. They are automatically placed. - var/turf/T = get_turf(U.loc) - if (isnull(T)) - dat += "Unable to obtain a reading." - else - var/datum/gas_mixture/environment = T.return_air() - - var/pressure = environment.return_pressure() - var/total_moles = environment.total_moles() - - dat += "Air Pressure: [round(pressure,0.1)] kPa" - - if (total_moles) - var/o2_level = environment.oxygen/total_moles - var/n2_level = environment.nitrogen/total_moles - var/co2_level = environment.carbon_dioxide/total_moles - var/plasma_level = environment.toxins/total_moles - var/unknown_level = 1-(o2_level+n2_level+co2_level+plasma_level) - dat += "
    " - dat += "
  • Nitrogen: [round(n2_level*100)]%
  • " - dat += "
  • Oxygen: [round(o2_level*100)]%
  • " - dat += "
  • Carbon Dioxide: [round(co2_level*100)]%
  • " - dat += "
  • Plasma: [round(plasma_level*100)]%
  • " - dat += "
" - if(unknown_level > 0.01) - dat += "OTHER: [round(unknown_level)]%
" - - dat += "Temperature: [round(environment.temperature-T0C)]°C" - if(2) - if(k_unlock==7||!s_control) - dat += " Hidden Menu" - dat += "

Anonymous Messenger:

"//Anonymous because the receiver will not know the sender's identity. - dat += "

Detected PDAs:

" - dat += "
    " - var/count = 0 - for (var/obj/item/device/pda/P in get_viewable_pdas()) - dat += "
  • [P]" - dat += "
  • " - count++ - dat += "
" - if (count == 0) - dat += "None detected.
" - if(32) - dat += "

Hidden Menu:

" - if(s_control) - dat += "Please input password: " - dat += "HERE
" - dat += "
" - dat += "Remember, you will not be able to recharge energy during this function. If energy runs out, the suit will auto self-destruct.
" - dat += "Use with caution. De-initialize the suit when energy is low." - else - //Only leaving this in for funnays. CAN'T LET YOU DO THAT STAR FOX - dat += "WARNING: Hostile runtime intrusion detected: operation locked. The Spider Clan is watching you, INTRUDER." - dat += "ERROR: TARANTULA.v.4.77.12 encryption algorithm detected. Unable to decrypt archive.
" - if(4) - dat += {" -

Ninja Manual:

-
Who they are:
- Space ninjas are a special type of ninja, specifically one of the space-faring type. The vast majority of space ninjas belong to the Spider Clan, a cult-like sect, which has existed for several hundred years. The Spider Clan practice a sort of augmentation of human flesh in order to achieve a more perfect state of being and follow Postmodern Space Bushido. They also kill people for money. Their leaders are chosen from the oldest of the grand-masters, people that have lived a lot longer than any mortal man should.
Being a sect of technology-loving fanatics, the Spider Clan have the very best to choose from in terms of hardware--cybernetic implants, exoskeleton rigs, hyper-capacity batteries, and you get the idea. Some believe that much of the Spider Clan equipment is based on reverse-engineered alien technology while others doubt such claims.
Whatever the case, their technology is absolutely superb. -
How they relate to other SS13 organizations:
-
    -
  • *Nanotrasen and the Syndicate are two sides of the same coin and that coin is valuable.
  • -
  • *The Space Wizard Federation is a problem, mainly because they are an extremely dangerous group of unpredictable individuals--not to mention the wizards hate technology and are in direct opposition of the Spider Clan. Best avoided or left well-enough alone. How to battle: wizards possess several powerful abilities to steer clear off. Blind in particular is a nasty spell--jaunt away if you are blinded and never approach a wizard in melee. Stealth may also work if the wizard is not wearing thermal scanners--don't count on this. Run away if you feel threatened and await a better opportunity.
  • -
  • *Changeling Hivemind: extremely dangerous and to be killed on sight. How to battle: they will likely try to absorb you. Adrenaline boost, then phase shift into them. If you get stung, use SpiderOS to inject counter-agents. Stealth may also work but detecting a changeling is the real battle.
  • -
  • *Xeno Hivemind: their skulls make interesting kitchen decorations and are challenging to best, especially in larger nests. How to battle: they can see through your stealth guise and energy stars will not work on them. Best killed with a Phase Shift or at range. If you happen on a projectile stun weapon, use it and then close in to melee.
  • -
-
The reason they (you) are here:
- Space ninjas are renowned throughout the known controlled space as fearless spies, infiltrators, and assassins. They are sent on missions of varying nature by Nanotrasen, the Syndicate, and other shady organizations and people. To hire a space ninja means serious business. -
Their playstyle:
- A mix of traitor, changeling, and wizard. Ninjas rely on energy, or electricity to be precise, to keep their suits running (when out of energy, a suit hibernates). Suits gain energy from objects or creatures that contain electrical charge. APCs, cell batteries, rechargers, SMES batteries, cyborgs, mechs, and exposed wires are currently supported. Through energy ninjas gain access to special powers--while all powers are tied to the ninja suit, the most useful of them are verb activated--to help them in their mission.
It is a constant struggle for a ninja to remain hidden long enough to recharge the suit and accomplish their objective; despite their arsenal of abilities, ninjas can die like any other. Unlike wizards, ninjas do not possess good crowd control and are typically forced to play more subdued in order to achieve their goals. Some of their abilities are specifically designed to confuse and disorient others.
With that said, it should be perfectly possible to completely flip the fuck out and rampage as a ninja. -
Their powers:
- There are two primary types: Equipment and Abilties. Passive effect are always on. Active effect must be turned on and remain active only when there is energy to do so. Ability costs are listed next to them. - Equipment: cannot be tracked by AI (passive), faster speed (passive), stealth (active), vision switch (passive if toggled), voice masking (passive), SpiderOS (passive if toggled), energy drain (passive if toggled). -
    -
  • Voice masking generates a random name the ninja can use over the radio and in-person. Although, the former use is recommended.
  • -
  • Toggling vision cycles to one of the following: thermal, meson, or darkness vision. The starting mode allows one to scout the identity of those in view, revealing their role. Traitors, revolutionaries, wizards, and other such people will be made known to you.
  • -
  • Stealth, when activated, drains more battery charge and works similarly to a syndicate cloak. The cloak will deactivate when most Abilities are utilized.
  • -
  • On-board AI: The suit is able to download an AI much like an intellicard. Check with SpiderOS for details once downloaded.
  • -
  • SpiderOS is a specialized, PDA-like screen that allows for a small variety of functions, such as injecting healing chemicals directly from the suit. You are using it now, if that was not already obvious. You may also download AI modules directly to the OS.
  • -
- Abilities: -
    -
  • *Phase Shift (2000E) and Phase Jaunt (1000E) are unique powers in that they can both be used for defense and offense. Jaunt launches the ninja forward facing up to 9 squares, somewhat randomly selecting the final destination. Shift can only be used on turf in view but is precise (cannot be used on walls). Any living mob in the area teleported to is instantly gibbed (mechs are damaged, huggers and other similar critters are killed). It is possible to teleport with a target, provided you grab them before teleporting.
  • -
  • *Energy Blade (500E) is a highly effective weapon. It is summoned directly to the ninja's hand and can also function as an EMAG for certain objects (doors/lockers/etc). You may also use it to cut through walls and disabled doors. Experiment! The blade will crit humans in two hits. This item cannot be placed in containers and when dropped or thrown disappears. Having an energy blade drains more power from the battery each tick.
  • -
  • *EM Pulse (2500E) is a highly useful ability that will create an electromagnetic shockwave around the ninja, disabling technology whenever possible. If used properly it can render a security force effectively useless. Of course, getting beat up with a toolbox is not accounted for.
  • -
  • *Energy Star (500E) is a ninja star made of green energy AND coated in poison. It works by picking a random living target within range and can be spammed to great effect in incapacitating foes. Just remember that the poison used is also used by the Xeno Hivemind (and will have no effect on them).
  • -
  • *Energy Net (2000E) is a non-lethal solution to incapacitating humanoids. The net is made of non-harmful phase energy and will halt movement as long as it remains in effect--it can be destroyed. If the net is not destroyed, after a certain time it will teleport the target to a holding facility for the Spider Clan and then vanish. You will be notified if the net fails or succeeds in capturing a target in this manner. Combine with energy stars or stripping to ensure success. Abduction never looked this leet.
  • -
  • *Adrenaline Boost (1 E. Boost/3) recovers the user from stun, weakness, and paralysis. Also injects 20 units of radium into the bloodstream.
  • -
  • *Smoke Bomb (1 Sm.Bomb/10) is a weak but potentially useful ability. It creates harmful smoke and can be used in tandem with other powers to confuse enemies.
  • -
  • *???: unleash the True Ultimate Power!
  • -

    IMPORTANT:

    -
      -
    • *Make sure to toggle Special Interaction from the Ninja Equipment menu to interact differently with certain objects.
    • -
    • *Your starting power cell can be replaced if you find one with higher maximum energy capacity by clicking on your suit with the higher capacity cell.
    • -
    • *Conserve your energy. Without it, you are very vulnerable.
    • -
    - That is all you will need to know. The rest will come with practice and talent. Good luck! -

    Master /N

    - "} - if(5) - dat += "

    AI Control:

    " - if(NAI) - NAI.attack_self(display_to) //Just accesses the integrated Intellicard. If an AI is in control of the suit then I guess it can interact with its own card. How meta. - - if(6) - dat += {" -

    Activate Abilities:

    - - "} - if(7) - dat += "

    Research Stored:

    " - if(t_disk) - dat += "Eject Disk
    " - dat += "
      " - if(istype(stored_research,/list))//If there is stored research. Should be but just in case. - for(var/datum/tech/current_data in stored_research) - dat += "
    • " - dat += "[current_data.name]: [current_data.level]" - if(t_disk)//If there is a disk inserted. We can either write or overwrite. - dat += " *Copy to Disk
      " - dat += "
    • " - dat += "
    " - dat += "" - - //Setting the can>resize etc to 0 remove them from the drag bar but still allows the window to be draggable. - display_to << browse(dat,"window=spideros;size=400x444;border=1;can_resize=1;can_close=0;can_minimize=0") - -//=======//SPIDEROS TOPIC PROC//=======// - -/obj/item/clothing/suit/space/space_ninja/Topic(href, href_list) - ..() - var/mob/living/carbon/human/U = affecting - var/mob/living/silicon/ai/A = AI - var/display_to = s_control ? U : A//Who do we want to display certain messages to? - - if(s_control) - if(!affecting||U.stat||!s_initialized)//Check to make sure the guy is wearing the suit after clicking and it's on. - U << "Your suit must be worn and active to use this function." - U << browse(null, "window=spideros")//Closes the window. - return - - if(k_unlock!=7&&href_list["choice"]!="Return") - var/u1=text2num(href_list["choice"]) - var/u2=(u1?abs(abs(k_unlock-u1)-2):1) - k_unlock=(!u2? k_unlock+1:0) - if(k_unlock==7) - U << "Anonymous Messenger blinks." - else - if(!affecting||A.stat||!s_initialized||A.loc!=src) - A << "This function is not available at this time." - A << browse(null, "window=spideros")//Closes the window. - return - - switch(href_list["choice"]) - if("Close") - display_to << browse(null, "window=spideros") - return - if("Refresh")//Refresh, goes to the end of the proc. - if("Return")//Return - if(spideros<=9) - spideros=0 - else - spideros = round(spideros/10)//Best way to do this, flooring to nearest integer. - - if("Shock") - var/damage = min(cell.charge, rand(50,150))//Uses either the current energy left over or between 50 and 150. - if(damage>1)//So they don't spam it when energy is a factor. - spark_system.start()//SPARKS THERE SHALL BE SPARKS - U.electrocute_act(damage, src,0.1,1)//The last argument is a safety for the human proc that checks for gloves. - cell.charge -= damage - else - A << "ERROR: Not enough energy remaining." - - if("Message") - var/obj/item/device/pda/P = locate(href_list["target"]) - var/t = input(U, "Please enter untraceable message.") as text - t = copytext(sanitize(t), 1, MAX_MESSAGE_LEN) - if(!t||U.stat||U.wear_suit!=src||!s_initialized)//Wow, another one of these. Man... - display_to << browse(null, "window=spideros") - return - if(isnull(P)||P.toff)//So it doesn't freak out if the object no-longer exists. - display_to << "Error: unable to deliver message." - display_spideros() - return - P.tnote += "← From [!s_control?(A):"an unknown source"]:
    [t]
    " - if (!P.silent) - playsound(P.loc, 'sound/machines/twobeep.ogg', 50, 1) - P.audible_message("\icon[P] *[P.ttone]*", null, 3) - P.overlays.Cut() - P.overlays += image('icons/obj/pda.dmi', "pda-r") - - if("Inject") - if( (href_list["tag"]=="radium"? (reagents.get_reagent_amount("radium"))<=(a_boost*a_transfer) : !reagents.get_reagent_amount(href_list["tag"])) )//Special case for radium. If there are only a_boost*a_transfer radium units left. - display_to << "Error: the suit cannot perform this function. Out of [href_list["name"]]." - else - reagents.reaction(U, 2) - reagents.trans_id_to(U, href_list["tag"], href_list["tag"]=="nutriment"?5:a_transfer)//Nutriment is a special case since it's very potent. Shouldn't influence actual refill amounts or anything. - display_to << "Injecting..." - U << "You feel a tiny prick and a sudden rush of substance in to your veins." - - if("Trigger Ability") - var/ability_name = href_list["name"]+href_list["cost"]//Adds the name and cost to create the full proc name. - var/proc_arguments//What arguments to later pass to the proc, if any. - var/targets[] = list()//To later check for. - var/safety = 0//To later make sure we're triggering the proc when needed. - switch(href_list["name"])//Special case. - if("Phase Shift") - safety = 1 - for(var/turf/T in oview(5,loc)) - targets.Add(T) - if("Energy Net") - safety = 1 - for(var/mob/living/carbon/M in oview(5,loc)) - targets.Add(M) - if(targets.len)//Let's create an argument for the proc if needed. - proc_arguments = pick(targets) - safety = 0 - if(!safety) - A << "You trigger [href_list["name"]]." - U << "[href_list["name"]] suddenly triggered!" - call(src,ability_name)(proc_arguments) - else - A << "There are no potential [href_list["name"]=="Phase Shift"?"destinations" : "targets"] in view." - - if("Unlock Kamikaze") - if(input(U)=="Divine Wind") - if( !(U.stat||U.wear_suit!=src||!s_initialized) ) - if( !(cell.charge<=1||s_busy) ) - s_busy = 1 - for(var/i, i<4, i++) - switch(i) - if(0) - U << "Engaging mode...\nCODE NAME: KAMIKAZE" - if(1) - U << "Re-routing power nodes... \nUnlocking limiter..." - if(2) - U << "Power nodes re-routed. \nLimiter unlocked." - if(3) - grant_kamikaze(U)//Give them verbs and change variables as necessary. - U.regenerate_icons()//Update their clothing. - ninjablade()//Summon two energy blades. - message_admins("[key_name_admin(U)] used KAMIKAZE mode.")//Let the admins know. - s_busy = 0 - return - sleep(s_delay) - else - U << "ERROR: Unable to initiate mode." - else - U << browse(null, "window=spideros") - s_busy = 0 - return - else - U << "ERROR: WRONG PASSWORD!" - k_unlock = 0 - spideros = 0 - s_busy = 0 - - if("Eject Disk") - var/turf/T = get_turf(loc) - if(!U.get_active_hand()) - U.put_in_hands(t_disk) - t_disk.add_fingerprint(U) - t_disk = null - else - if(T) - t_disk.loc = T - t_disk = null - else - U << "ERROR: Could not eject disk." - - if("Copy to Disk") - var/datum/tech/current_data = locate(href_list["target"]) - U << "[current_data.name] successfully [(!t_disk.stored) ? "copied" : "overwritten"] to disk." - t_disk.stored = current_data - - if("Configure pAI") - pai.attack_self(U) - - if("Eject pAI") - var/turf/T = get_turf(loc) - if(!U.get_active_hand()) - U.put_in_hands(pai) - pai.add_fingerprint(U) - pai = null - else - if(T) - pai.loc = T - pai = null - else - U << "ERROR: Could not eject pAI card." - - if("Override AI Laws") - var/law_zero = A.laws.zeroth//Remembers law zero, if there is one. - A.laws = new /datum/ai_laws/ninja_override - A.set_zeroth_law(law_zero)//Adds back law zero if there was one. - A.show_laws() - U << "Law Override: SUCCESS." - - if("Purge AI") - var/confirm = alert("Are you sure you want to purge the AI? This cannot be undone once started.", "Confirm purge", "Yes", "No") - if(U.stat||U.wear_suit!=src||!s_initialized) - U << browse(null, "window=spideros") - return - if(confirm == "Yes"&&AI) - if(A.laws.zeroth)//Gives a few seconds to re-upload the AI somewhere before it takes full control. - s_busy = 1 - for(var/i,i<5,i++) - if(AI==A) - switch(i) - if(0) - A << "WARNING: purge procedure detected. \nNow hacking host..." - U << "WARNING: HACKING AT��TEMP� IN PR0GRESs!" - spideros = 0 - k_unlock = 0 - U << browse(null, "window=spideros") - if(1) - A << "Disconnecting neural interface..." - U << "WAR�NING: �R�O0�Gr�--S 2&3%" - if(2) - A << "Shutting down external protocol..." - U << "WARNING: P����RֆGr�5S 677^%" - cancel_stealth() - if(3) - A << "Connecting to kernel..." - U << "WARNING: �R�r�R_404" - A.control_disabled = 0 - if(4) - A << "Connection established and secured. Menu updated." - U << "W�r#nING: #%@!!WȆ|_4�54@ \nUn�B88l3 T� L�-�o-L�CaT2 ##$!�RN�0..%.." - grant_AI_verbs() - return - sleep(s_delay) - else break - s_busy = 0 - U << "Hacking attempt disconnected. Resuming normal operation." - else - NAI.flush = 1 - A.suiciding = 1 - A << "Your core files are being purged! This is the end..." - spawn(0) - display_spideros()//To refresh the screen and let this finish. - while (A.stat != 2) - A.adjustOxyLoss(2) - A.updatehealth() - sleep(10) - killai(NAI) - U << "Artificial Intelligence was terminated. Rebooting..." - NAI.flush = 0 - - if("Wireless AI") - A.control_disabled = !A.control_disabled - A << "AI wireless has been [A.control_disabled ? "disabled" : "enabled"]." - else//If it's not a defined function, it's a menu. - spideros=text2num(href_list["choice"]) - - display_spideros()//Refreshes the screen by calling it again (which replaces current screen with new screen). - return - -//=======//SPECIAL AI FUNCTIONS//=======// - -/obj/item/clothing/suit/space/space_ninja/proc/ai_holo(var/turf/T in oview(3,affecting))//To have an internal AI display a hologram to the AI and ninja only. - set name = "Display Hologram" - set desc = "Channel a holographic image directly to the user's field of vision. Others will not see it." - set category = null - set src = usr.loc - - if(s_initialized&&affecting&&affecting.client&&istype(affecting.loc, /turf))//If the host exists and they are playing, and their location is a turf. - if(!hologram)//If there is not already a hologram. - hologram = new(T)//Spawn a blank effect at the location. - hologram.invisibility = 101//So that it doesn't show up, ever. This also means one could attach a number of images to a single obj and display them differently to differnet people. - hologram.anchored = 1//So it cannot be dragged by space wind and the like. - hologram.dir = get_dir(T,affecting.loc) - - for(var/mob/living/silicon/ai/A in NAI) - var/image/I = image(A.holo_icon,hologram)//Attach an image to object. - hologram.i_attached = I//To attach the image in order to later reference. - A << I - affecting << I - affecting << "An image flicks to life nearby. It appears visible to you only." - - verbs += /obj/item/clothing/suit/space/space_ninja/proc/ai_holo_clear - - ai_holo_process()//Move to initialize - else - AI << "ERROR: Image feed in progress." - else - AI << "ERROR: Unable to project image." - return - -/obj/item/clothing/suit/space/space_ninja/proc/ai_holo_process() - set background = BACKGROUND_ENABLED - - spawn while(hologram&&s_initialized&&AI)//Suit on and there is an AI present. - if(!s_initialized||get_dist(affecting,hologram.loc)>3)//Once suit is de-initialized or hologram reaches out of bounds. - qdel(hologram.i_attached) - qdel(hologram) - - verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ai_holo_clear - return - sleep(10)//Checks every second. - -/obj/item/clothing/suit/space/space_ninja/proc/ai_instruction()//Let's the AI know what they can do. - set name = "Instructions" - set desc = "Displays a list of helpful information." - set category = "AI Ninja Equip" - set src = usr.loc - - AI << "The menu you are seeing will contain other commands if they become available.\nRight click a nearby turf to display an AI Hologram. It will only be visible to you and your host. You can move it freely using normal movement keys--it will disappear if placed too far away." - -/obj/item/clothing/suit/space/space_ninja/proc/ai_holo_clear() - set name = "Clear Hologram" - set desc = "Stops projecting the current holographic image." - set category = "AI Ninja Equip" - set src = usr.loc - - qdel(hologram.i_attached) - qdel(hologram) - - verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ai_holo_clear - return - -/obj/item/clothing/suit/space/space_ninja/proc/ai_hack_ninja() - set name = "Hack SpiderOS" - set desc = "Hack directly into the Black Widow(tm) neuro-interface." - set category = "AI Ninja Equip" - set src = usr.loc - - display_spideros() - return - -/obj/item/clothing/suit/space/space_ninja/proc/ai_return_control() - set name = "Relinquish Control" - set desc = "Return control to the user." - set category = "AI Ninja Equip" - set src = usr.loc - - - for(var/mob/living/silicon/ai/A in NAI) - AI << browse(null, "window=spideros")//Close window - AI << "You have seized your hacking attempt. [affecting.real_name] has regained control." - affecting << "UPDATE: [A.real_name] has ceased hacking attempt. All systems clear." - - remove_AI_verbs() - return - -//=======//GENERAL SUIT PROCS//=======// - -/obj/item/clothing/suit/space/space_ninja/attackby(obj/item/I, mob/U, params) - if(U==affecting)//Safety, in case you try doing this without wearing the suit/being the person with the suit. - if(istype(I, /obj/item/device/aicard))//If it's an AI card. - if(s_control) - I:transfer_ai("NINJASUIT","AICARD",src,U) - else - U << "ERROR: Remote access channel disabled." - return//Return individually so that ..() can run properly at the end of the proc. - else if(istype(I, /obj/item/device/paicard) && !pai)//If it's a pai card. - U:drop_item() - I.loc = src - pai = I - U << "You slot \the [I] into \the [src]." - updateUsrDialog() - return - else if(istype(I, /obj/item/weapon/reagent_containers/glass))//If it's a glass beaker. - var/total_reagent_transfer//Keep track of this stuff. - for(var/reagent_id in reagent_list) - var/datum/reagent/R = I.reagents.has_reagent(reagent_id)//Mostly to pull up the name of the reagent after calculating. Also easier to use than writing long proc paths. - if(R&&reagents.get_reagent_amount(reagent_id)=a_transfer)//Radium is always special. - //Here we determine how much reagent will actually transfer if there is enough to transfer or there is a need of transfer. Minimum of max amount available (using a_transfer) or amount needed. - var/amount_to_transfer = min( (r_maxamount+(reagent_id == "radium"?(a_boost*a_transfer):0)-reagents.get_reagent_amount(reagent_id)) ,(round(R.volume/a_transfer))*a_transfer)//In the end here, we round the amount available, then multiply it again. - R.volume -= amount_to_transfer//Remove from reagent volume. Don't want to delete the reagent now since we need to perserve the name. - reagents.add_reagent(reagent_id, amount_to_transfer)//Add to suit. Reactions are not important. - total_reagent_transfer += amount_to_transfer//Add to total reagent trans. - U << "Added [amount_to_transfer] units of [R.name]."//Reports on the specific reagent added. - I.reagents.update_total()//Now we manually update the total to make sure everything is properly shoved under the rug. - - U << "Replenished a total of [total_reagent_transfer ? total_reagent_transfer : "zero"] chemical units."//Let the player know how much total volume was added. - return - else if(istype(I, /obj/item/weapon/stock_parts/cell)) - if(I:maxcharge>cell.maxcharge&&n_gloves&&n_gloves.candrain) - U << "Higher maximum capacity detected.\nUpgrading..." - if (n_gloves&&n_gloves.candrain&&do_after(U,s_delay)) - U.drop_item() - I.loc = src - I:charge = min(I:charge+cell.charge, I:maxcharge) - var/obj/item/weapon/stock_parts/cell/old_cell = cell - old_cell.charge = 0 - U.put_in_hands(old_cell) - old_cell.add_fingerprint(U) - old_cell.corrupt() - old_cell.updateicon() - cell = I - U << "Upgrade complete. Maximum capacity: [round(cell.maxcharge/100)]%" - else - U << "Procedure interrupted. Protocol terminated." - return - else if(istype(I, /obj/item/weapon/disk/tech_disk))//If it's a data disk, we want to copy the research on to the suit. - var/obj/item/weapon/disk/tech_disk/TD = I - if(TD.stored)//If it has something on it. - U << "Research information detected, processing..." - if(do_after(U,s_delay)) - for(var/datum/tech/current_data in stored_research) - if(current_data.id==TD.stored.id) - if(current_data.levelData analyzed and updated. Disk erased." - else - U << "ERROR: Procedure interrupted. Process terminated." - else - I.loc = src - t_disk = I - U << "You slot \the [I] into \the [src]." - return - ..() - -/obj/item/clothing/suit/space/space_ninja/proc/toggle_stealth() - var/mob/living/carbon/human/U = affecting - if(s_active) - cancel_stealth() - else - spawn(0) - anim(U.loc,U,'icons/mob/mob.dmi',,"cloak",,U.dir) - s_active=!s_active - U.alpha = 0 - U.visible_message("[U.name] vanishes into thin air!", \ - "You are now invisible to normal detection.") - return - -/obj/item/clothing/suit/space/space_ninja/proc/cancel_stealth() - var/mob/living/carbon/human/U = affecting - if(s_active) - spawn(0) - anim(U.loc,U,'icons/mob/mob.dmi',,"uncloak",,U.dir) - s_active=!s_active - U.alpha = 255 - U.visible_message("[U.name] appears from thin air!", \ - "You are now visible.") - return 1 - return 0 - -/obj/item/clothing/suit/space/space_ninja/proc/blade_check(mob/living/carbon/U, X = 1)//Default to checking for blade energy. - switch(X) - if(1) - if(istype(U.get_active_hand(), /obj/item/weapon/melee/energy/blade)) - if(cell.charge<=0)//If no charge left. - U.drop_item()//Blade is dropped from active hand (and deleted). - else return 1 - else if(istype(U.get_inactive_hand(), /obj/item/weapon/melee/energy/blade)) - if(cell.charge<=0) - U.swap_hand()//swap hand - U.drop_item()//drop blade - else return 1 - if(2) - if(istype(U.get_active_hand(), /obj/item/weapon/melee/energy/blade)) - U.drop_item() - if(istype(U.get_inactive_hand(), /obj/item/weapon/melee/energy/blade)) - U.swap_hand() - U.drop_item() - return 0 - -/obj/item/clothing/suit/space/space_ninja/examine(mob/user) - ..() - if(s_initialized) - if(user == affecting) - if(s_control) - user << "All systems operational. Current energy capacity: [cell.charge]." - if(!kamikaze) - user << "The CLOAK-tech device is [s_active?"active":"inactive"]." - else - user << "KAMIKAZE MODE ENGAGED!" - user << "There are [s_bombs] smoke bomb\s remaining." - user << "There are [a_boost] adrenaline booster\s remaining." - else - user << "�rr�R �a��a�� No-�-� f��N� 3RR�r" - -/* -=================================================================================== -<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -=================================================================================== -*/ - -//=======//ENERGY DRAIN PROCS//=======// - -/obj/item/clothing/gloves/space_ninja/proc/drain(target_type as text, target, obj/suit) -//Var Initialize - var/obj/item/clothing/suit/space/space_ninja/S = suit - var/mob/living/carbon/human/U = S.affecting - var/obj/item/clothing/gloves/space_ninja/G = S.n_gloves - - var/drain = 0//To drain from battery. - var/maxcapacity = 0//Safety check for full battery. - var/totaldrain = 0//Total energy drained. - - G.draining = 1 - - if(target_type!="RESEARCH")//I lumped research downloading here for ease of use. - U << "Now charging battery..." - - switch(target_type) - - if("APC") - var/obj/machinery/power/apc/A = target - if(A.cell&&A.cell.charge) - var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread() - spark_system.set_up(5, 0, A.loc) - while(G.candrain&&A.cell.charge>0&&!maxcapacity) - drain = rand(G.mindrain,G.maxdrain) - if(A.cell.chargeS.cell.maxcharge) - drain = S.cell.maxcharge-S.cell.charge - maxcapacity = 1//Reached maximum battery capacity. - if (do_after(U,10)) - spark_system.start() - playsound(A.loc, "sparks", 50, 1) - A.cell.charge-=drain - S.cell.charge+=drain - totaldrain+=drain - else break - U << "Gained [totaldrain] energy from the APC." - if(!A.emagged) - flick("apc-spark", src) - A.emagged = 1 - A.locked = 0 - A.update_icon() - else - U << "This APC has run dry of power. You must find another source." - - if("SMES") - var/obj/machinery/power/smes/A = target - if(A.charge) - var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread() - spark_system.set_up(5, 0, A.loc) - while(G.candrain&&A.charge>0&&!maxcapacity) - drain = rand(G.mindrain,G.maxdrain) - if(A.chargeS.cell.maxcharge) - drain = S.cell.maxcharge-S.cell.charge - maxcapacity = 1 - if (do_after(U,10)) - spark_system.start() - playsound(A.loc, "sparks", 50, 1) - A.charge-=drain - S.cell.charge+=drain - totaldrain+=drain - else break - U << "Gained [totaldrain] energy from the SMES cell." - else - U << "This SMES cell has run dry of power. You must find another source." - - if("CELL") - var/obj/item/weapon/stock_parts/cell/A = target - if(A.charge) - if (G.candrain&&do_after(U,30)) - U << "Gained [A.charge] energy from the cell." - if(S.cell.charge+A.charge>S.cell.maxcharge) - S.cell.charge=S.cell.maxcharge - else - S.cell.charge+=A.charge - A.charge = 0 - G.draining = 0 - A.corrupt() - A.updateicon() - else - U << "Procedure interrupted. Protocol terminated." - else - U << "This cell is empty and of no use." - - if("MACHINERY")//Can be applied to generically to all powered machinery. I'm leaving this alone for now. - var/obj/machinery/A = target - if(A.powered())//If powered. - - var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread() - spark_system.set_up(5, 0, A.loc) - - var/obj/machinery/power/apc/B = A.loc.loc:get_apc()//Object.turf.area find APC - if(B)//If APC exists. Might not if the area is unpowered like Centcom. - var/datum/powernet/PN = B.terminal.powernet - while(G.candrain&&!maxcapacity&&!isnull(A))//And start a proc similar to drain from wire. - drain = rand(G.mindrain,G.maxdrain) - var/drained = 0 - if(PN&&do_after(U,10)) - drained = min(drain, PN.avail) - PN.load += drained - if(drained < drain)//if no power on net, drain apcs - for(var/obj/machinery/power/terminal/T in PN.nodes) - if(istype(T.master, /obj/machinery/power/apc)) - var/obj/machinery/power/apc/AP = T.master - if(AP.operating && AP.cell && AP.cell.charge>0) - AP.cell.charge = max(0, AP.cell.charge - 5) - drained += 5 - else break - S.cell.charge += drained - if(S.cell.charge>S.cell.maxcharge) - totaldrain += (drained-(S.cell.charge-S.cell.maxcharge)) - S.cell.charge = S.cell.maxcharge - maxcapacity = 1 - else - totaldrain += drained - spark_system.start() - if(drained==0) break - U << "Gained [totaldrain] energy from the power network." - else - U << "Power network could not be found. Aborting." - else - U << "This recharger is not providing energy. You must find another source." - - if("RESEARCH") - var/obj/machinery/A = target - U << "Hacking \the [A]..." - spawn(0) - var/turf/location = get_turf(U) - for(var/mob/living/silicon/ai/AI in player_list) - AI << "Network Alert: Hacking attempt detected[location?" in [location]":". Unable to pinpoint location"]." - if(A:files&&A:files.known_tech.len) - for(var/datum/tech/current_data in S.stored_research) - U << "Checking \the [current_data.name] database." - if(do_after(U, S.s_delay)&&G.candrain&&!isnull(A)) - for(var/datum/tech/analyzing_data in A:files.known_tech) - if(current_data.id==analyzing_data.id) - if(analyzing_data.level>current_data.level) - U << "Database: UPDATED." - current_data.level = analyzing_data.level - break//Move on to next. - else break//Otherwise, quit processing. - U << "Data analyzed. Process finished." - - if("WIRE") - var/obj/structure/cable/A = target - var/datum/powernet/PN = A.powernet - while(G.candrain&&!maxcapacity&&!isnull(A)) - drain = (round((rand(G.mindrain,G.maxdrain))/2)) - var/drained = 0 - if(PN&&do_after(U,10)) - drained = min(drain, PN.avail) - PN.load += drained - if(drained < drain)//if no power on net, drain apcs - for(var/obj/machinery/power/terminal/T in PN.nodes) - if(istype(T.master, /obj/machinery/power/apc)) - var/obj/machinery/power/apc/AP = T.master - if(AP.operating && AP.cell && AP.cell.charge>0) - AP.cell.charge = max(0, AP.cell.charge - 5) - drained += 5 - else break - S.cell.charge += drained - if(S.cell.charge>S.cell.maxcharge) - totaldrain += (drained-(S.cell.charge-S.cell.maxcharge)) - S.cell.charge = S.cell.maxcharge - maxcapacity = 1 - else - totaldrain += drained - S.spark_system.start() - if(drained==0) break - U << "Gained [totaldrain] energy from the power network." - - if("MECHA") - var/obj/mecha/A = target - A.occupant_message("Warning: Unauthorized access through sub-route 4, block H, detected.") - if(A.get_charge()) - while(G.candrain&&A.cell.charge>0&&!maxcapacity) - drain = rand(G.mindrain,G.maxdrain) - if(A.cell.chargeS.cell.maxcharge) - drain = S.cell.maxcharge-S.cell.charge - maxcapacity = 1 - if (do_after(U,10)) - A.spark_system.start() - playsound(A.loc, "sparks", 50, 1) - A.cell.use(drain) - S.cell.charge+=drain - totaldrain+=drain - else break - U << "Gained [totaldrain] energy from [src]." - else - U << "The exosuit's battery has run dry. You must find another source of power." - - if("CYBORG") - var/mob/living/silicon/robot/A = target - A << "Warning: Unauthorized access through sub-route 12, block C, detected." - G.draining = 1 - if(A.cell&&A.cell.charge) - while(G.candrain&&A.cell.charge>0&&!maxcapacity) - drain = rand(G.mindrain,G.maxdrain) - if(A.cell.chargeS.cell.maxcharge) - drain = S.cell.maxcharge-S.cell.charge - maxcapacity = 1 - if (do_after(U,10)) - A.spark_system.start() - playsound(A.loc, "sparks", 50, 1) - A.cell.charge-=drain - S.cell.charge+=drain - totaldrain+=drain - else break - U << "Gained [totaldrain] energy from [A]." - else - U << "Their battery has run dry of power. You must find another source." - - else//Else nothing :< - - G.draining = 0 - - return - -//=======//GENERAL PROCS//=======// - -/obj/item/clothing/gloves/space_ninja/proc/toggled() - set name = "Toggle Interaction" - set desc = "Toggles special interaction on or off." - set category = "Ninja Equip" - - var/mob/living/carbon/human/U = loc - U << "You [candrain?"disable":"enable"] special interaction." - candrain=!candrain - -/obj/item/clothing/gloves/space_ninja/examine(mob/user) - ..() - if(flags & NODROP) - user << "The energy drain mechanism is: [candrain?"active":"inactive"]." - -/* -=================================================================================== -<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -=================================================================================== -*/ - -/obj/item/clothing/mask/gas/voice/space_ninja/New() - verbs += /obj/item/clothing/mask/gas/voice/space_ninja/proc/togglev - -//This proc is linked to human life.dm. It determines what hud icons to display based on mind special role for most mobs. -/obj/item/clothing/mask/gas/voice/space_ninja/proc/assess_targets(list/target_list, mob/living/carbon/U) - var/icon/tempHud = 'icons/mob/hud.dmi' - for(var/mob/living/target in target_list) - if(iscarbon(target)) - switch(target.mind.special_role) - if("traitor") - U.client.images += image(tempHud,target,"hudtraitor") - if("Revolutionary","Head Revolutionary") - U.client.images += image(tempHud,target,"hudrevolutionary") - if("Cultist") - U.client.images += image(tempHud,target,"hudcultist") - if("Changeling") - U.client.images += image(tempHud,target,"hudchangeling") - if("Wizard","Fake Wizard") - U.client.images += image(tempHud,target,"hudwizard") - if("Hunter","Sentinel","Drone","Queen") - U.client.images += image(tempHud,target,"hudalien") - if("Syndicate") - U.client.images += image(tempHud,target,"hudoperative") - if("Death Commando") - U.client.images += image(tempHud,target,"huddeathsquad") - if("Space Ninja") - U.client.images += image(tempHud,target,"hudninja") - else//If we don't know what role they have but they have one. - U.client.images += image(tempHud,target,"hudunknown1") - else if(issilicon(target))//If the silicon mob has no law datum, no inherent laws, or a law zero, add them to the hud. - var/mob/living/silicon/silicon_target = target - if(!silicon_target.laws||(silicon_target.laws&&(silicon_target.laws.zeroth||!silicon_target.laws.inherent.len))) - if(isrobot(silicon_target))//Different icons for robutts and AI. - U.client.images += image(tempHud,silicon_target,"hudmalborg") - else - U.client.images += image(tempHud,silicon_target,"hudmalai") - return 1 - -/obj/item/clothing/mask/gas/voice/space_ninja/proc/togglev() - set name = "Toggle Voice" - set desc = "Toggles the voice synthesizer on or off." - set category = "Ninja Equip" - - var/mob/U = loc//Can't toggle voice when you're not wearing the mask. - var/vchange = (alert("Would you like to synthesize a new name or turn off the voice synthesizer?",,"New Name","Turn Off")) - if(vchange=="New Name") - var/chance = rand(1,100) - switch(chance) - if(1 to 50)//High chance of a regular name. - voice = "[rand(0,1)==1?pick(first_names_female):pick(first_names_male)] [pick(last_names)]" - if(51 to 80)//Smaller chance of a clown name. - voice = "[pick(clown_names)]" - if(81 to 90)//Small chance of a wizard name. - voice = "[pick(wizard_first)] [pick(wizard_second)]" - if(91 to 100)//Small chance of an existing crew name. - var/names[] = new() - for(var/mob/living/carbon/human/M in player_list) - if(M==U||!M.client||!M.real_name) continue - names.Add(M.real_name) - voice = !names.len ? "Cuban Pete" : pick(names) - U << "You are now mimicking [voice]." - else - U << "The voice synthesizer is [voice!="Unknown"?"now":"already"] deactivated." - voice = "Unknown" - return - -/obj/item/clothing/mask/gas/voice/space_ninja/examine(mob/user) - ..() - user << "Voice mimicking algorithm is set [!vchange?"inactive":"active"]." - -/* -=================================================================================== -<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -=================================================================================== -*/ - -/* -It will teleport people to a holding facility after 30 seconds. (Check the process() proc to change where teleport goes) -It is possible to destroy the net by the occupant or someone else. -*/ - -/obj/effect/energy_net - name = "energy net" - desc = "It's a net made of green energy." - icon = 'icons/effects/effects.dmi' - icon_state = "energynet" - - density = 1//Can't pass through. - opacity = 0//Can see through. - mouse_opacity = 1//So you can hit it with stuff. - anchored = 1//Can't drag/grab the trapped mob. - - var/health = 25//How much health it has. - var/mob/living/affecting = null//Who it is currently affecting, if anyone. - var/mob/living/master = null//Who shot web. Will let this person know if the net was successful or failed. - -/obj/effect/energy_net/proc/healthcheck() - if(health <=0) - density = 0 - if(affecting) - var/mob/living/carbon/M = affecting - M.anchored = 0 - for(var/mob/O in viewers(src, 3)) - O.show_message("[M.name] was recovered from the energy net!", 1, "You hear a grunt.", 2) - if(!isnull(master))//As long as they still exist. - master << "ERROR: unable to initiate transport protocol. Procedure terminated." - qdel(src) - return - -/obj/effect/energy_net/process(var/mob/living/carbon/M as mob) - var/check = 30//30 seconds before teleportation. Could be extended I guess. - var/mob_name = affecting.name//Since they will report as null if terminated before teleport. - //The person can still try and attack the net when inside. - while(!isnull(M)&&!isnull(src)&&check>0)//While M and net exist, and 30 seconds have not passed. - check-- - sleep(10) - - if(isnull(M)||M.loc!=loc)//If mob is gone or not at the location. - if(!isnull(master))//As long as they still exist. - master << "ERROR: unable to locate \the [mob_name]. Procedure terminated." - qdel(src)//Get rid of the net. - return - - if(!isnull(src))//As long as both net and person exist. - //No need to check for countdown here since while() broke, it's implicit that it finished. - - density = 0//Make the net pass-through. - invisibility = 101//Make the net invisible so all the animations can play out. - health = INFINITY//Make the net invincible so that an explosion/something else won't kill it while, spawn() is running. - for(var/obj/item/W in M) - if(istype(M,/mob/living/carbon/human)) - if(W==M:w_uniform) continue//So all they're left with are shoes and uniform. - if(W==M:shoes) continue - M.unEquip(W) - - spawn(0) - playsound(M.loc, 'sound/effects/sparks4.ogg', 50, 1) - anim(M.loc,M,'icons/mob/mob.dmi',,"phaseout",,M.dir) - - M.loc = pick(holdingfacility)//Throw mob in to the holding facility. - M << "You appear in a strange place!" - - spawn(0) - var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread() - spark_system.set_up(5, 0, M.loc) - spark_system.start() - playsound(M.loc, 'sound/effects/phasein.ogg', 25, 1) - playsound(M.loc, 'sound/effects/sparks2.ogg', 50, 1) - anim(M.loc,M,'icons/mob/mob.dmi',,"phasein",,M.dir) - qdel(src)//Wait for everything to finish, delete the net. Else it will stop everything once net is deleted, including the spawn(0). - - for(var/mob/O in viewers(src, 3)) - O.show_message("[M] vanished!", 1, "You hear sparks flying!", 2) - - if(!isnull(master))//As long as they still exist. - master << "SUCCESS: transport procedure of \the [affecting] complete." - - M.anchored = 0//Important. - - else//And they are free. - M << "You are free of the net!" - return - -/obj/effect/energy_net/bullet_act(var/obj/item/projectile/Proj) - health -= Proj.damage - healthcheck() - ..() - -/obj/effect/energy_net/ex_act(severity, target) - switch(severity) - if(1.0) - health-=50 - if(2.0) - health-=50 - if(3.0) - health-=prob(50)?50:25 - healthcheck() - return - -/obj/effect/energy_net/blob_act() - health-=50 - healthcheck() - return - -/obj/effect/energy_net/hitby(AM as mob|obj) - ..() - visible_message("[src] was hit by [AM].") - var/tforce = 0 - if(ismob(AM)) - tforce = 10 - else - tforce = AM:throwforce - playsound(src.loc, 'sound/weapons/slash.ogg', 80, 1) - health = max(0, health - tforce) - healthcheck() - ..() - return - -/obj/effect/energy_net/attack_hulk(mob/living/carbon/human/user) - ..(user, 1) - user.visible_message("[user] rips the energy net apart!", \ - "You easily destroy the energy net.") - health-=50 - healthcheck() - -/obj/effect/energy_net/attack_paw(mob/user) - return attack_hand() - -/obj/effect/energy_net/attack_alien(mob/living/user as mob) - user.do_attack_animation(src) - if (islarva(user)) - return - playsound(src.loc, 'sound/weapons/slash.ogg', 80, 1) - health -= rand(10, 20) - if(health > 0) - user.visible_message("[user] claws at the energy net!", \ - "\green You claw at the net.") - else - user.visible_message("[user] slices the energy net apart!", \ - "\green You slice the energy net to pieces.") - healthcheck() - return - -/obj/effect/energy_net/attackby(obj/item/weapon/W as obj, mob/user as mob, params) - var/aforce = W.force - health = max(0, health - aforce) - healthcheck() - ..() - return - -proc/create_ninja_mind(key) - var/datum/mind/Mind = new /datum/mind(key) - Mind.assigned_role = "MODE" - Mind.special_role = "Space Ninja" - ticker.mode.traitors |= Mind //Adds them to current traitor list. Which is really the extra antagonist list. - return Mind diff --git a/code/modules/food&drinks/food/customizables.dm b/code/modules/food&drinks/food/customizables.dm index 46c1f0dace6..168210ad21f 100644 --- a/code/modules/food&drinks/food/customizables.dm +++ b/code/modules/food&drinks/food/customizables.dm @@ -15,6 +15,7 @@ /obj/item/weapon/reagent_containers/food/snacks/customizable bitesize = 4 w_class = 3 + volume = 60 var/ingMax = 12 var/list/ingredients = list() @@ -67,9 +68,8 @@ return name = "[customname] [initial(name)]" - else . = ..() - return + /obj/item/weapon/reagent_containers/food/snacks/customizable/proc/update_name(obj/item/weapon/reagent_containers/food/snacks/S) for(var/obj/item/I in ingredients) diff --git a/code/modules/food&drinks/food/snacks/dough.dm b/code/modules/food&drinks/food/snacks/dough.dm index aca417a2473..d03339809cd 100644 --- a/code/modules/food&drinks/food/snacks/dough.dm +++ b/code/modules/food&drinks/food/snacks/dough.dm @@ -8,9 +8,8 @@ icon = 'icons/obj/food_ingredients.dmi' icon_state = "dough" cooked_type = /obj/item/weapon/reagent_containers/food/snacks/store/bread/plain - list_reagents = list("nutriment" = 3) + list_reagents = list("nutriment" = 6) w_class = 3 - flags = OPENCONTAINER // Dough + rolling pin = flat dough @@ -35,9 +34,8 @@ slice_path = /obj/item/weapon/reagent_containers/food/snacks/doughslice slices_num = 3 cooked_type = /obj/item/weapon/reagent_containers/food/snacks/pizzabread - list_reagents = list("nutriment" = 3) + list_reagents = list("nutriment" = 6) w_class = 3 - flags = OPENCONTAINER /obj/item/weapon/reagent_containers/food/snacks/pizzabread name = "pizza bread" @@ -56,7 +54,6 @@ icon_state = "doughslice" cooked_type = /obj/item/weapon/reagent_containers/food/snacks/bun filling_color = "#CD853F" - flags = OPENCONTAINER /obj/item/weapon/reagent_containers/food/snacks/bun @@ -74,7 +71,7 @@ icon = 'icons/obj/food_ingredients.dmi' icon_state = "cakebatter" cooked_type = /obj/item/weapon/reagent_containers/food/snacks/store/cake/plain - list_reagents = list("nutriment" = 3) + list_reagents = list("nutriment" = 9) w_class = 3 // Cake batter + rolling pin = pie dough @@ -97,7 +94,7 @@ slice_path = /obj/item/weapon/reagent_containers/food/snacks/rawpastrybase slices_num = 3 cooked_type = /obj/item/weapon/reagent_containers/food/snacks/pie/plain - list_reagents = list("nutriment" = 3) + list_reagents = list("nutriment" = 9) w_class = 3 /obj/item/weapon/reagent_containers/food/snacks/rawpastrybase diff --git a/code/modules/food&drinks/food/snacks_burgers.dm b/code/modules/food&drinks/food/snacks_burgers.dm index 62612c9b47d..83340dc3f14 100644 --- a/code/modules/food&drinks/food/snacks_burgers.dm +++ b/code/modules/food&drinks/food/snacks_burgers.dm @@ -1,11 +1,11 @@ /obj/item/weapon/reagent_containers/food/snacks/burger filling_color = "#CD853F" + icon_state = "hburger" /obj/item/weapon/reagent_containers/food/snacks/burger/plain name = "burger" desc = "The cornerstone of every nutritious breakfast." - icon_state = "hburger" list_reagents = list("vitamin" = 1) bitesize = 3 @@ -14,13 +14,13 @@ var/job = null name = "-burger" desc = "A bloody burger." - icon_state = "hburger" list_reagents = list("vitamin" = 4) /obj/item/weapon/reagent_containers/food/snacks/burger/appendix name = "appendix burger" desc = "Tastes like appendicitis." list_reagents = list("nutriment" = 6, "vitamin" = 6) + icon_state = "appendixburger" /obj/item/weapon/reagent_containers/food/snacks/burger/fish name = "fillet -o- carp sandwich" diff --git a/code/modules/food&drinks/food/snacks_cake.dm b/code/modules/food&drinks/food/snacks_cake.dm index c51750173dc..d8a65be515b 100644 --- a/code/modules/food&drinks/food/snacks_cake.dm +++ b/code/modules/food&drinks/food/snacks_cake.dm @@ -161,3 +161,16 @@ name = "cake slice" icon_state = "plaincake_slice" filling_color = "#FFFFFF" + +/obj/item/weapon/reagent_containers/food/snacks/store/cake/slimecake + name = "Slime cake" + desc = "A cake made of slimes. Probably not electrified." + icon_state = "slimecake" + slice_path = /obj/item/weapon/reagent_containers/food/snacks/cakeslice/slimecake + slices_num = 5 + list_reagents = list("nutriment" = 1, "vitamin" = 3) + +/obj/item/weapon/reagent_containers/food/snacks/cakeslice/slimecake + name = "Slime cake slice" + icon_state = "slimecake_slice" + filling_color = "#00FFFF" diff --git a/code/modules/food&drinks/recipes/food_mixtures.dm b/code/modules/food&drinks/recipes/food_mixtures.dm index d468f33dfde..f038a3b3fb1 100644 --- a/code/modules/food&drinks/recipes/food_mixtures.dm +++ b/code/modules/food&drinks/recipes/food_mixtures.dm @@ -111,43 +111,6 @@ required_reagents = list("capsaicin" = 1, "hot_ramen" = 6) result_amount = 6 -/datum/chemical_reaction/cakebatter - name = "Cake Batter" - id = "cakebatter" - result = null - required_reagents = list("milk" = 5) - result_amount = 1 - required_container = /obj/item/weapon/reagent_containers/food/snacks/dough - mix_message = "The dough forms a cake batter." - -/datum/chemical_reaction/cakebatter/on_reaction(var/datum/reagents/holder) - var/obj/item/weapon/reagent_containers/food/snacks/S = new /obj/item/weapon/reagent_containers/food/snacks/cakebatter - S.loc = get_turf(holder.my_atom) - if(holder && holder.my_atom) - qdel(holder.my_atom) - -/datum/chemical_reaction/piedough - name = "Pie Dough" - id = "piedough" - result = null - required_reagents = list("milk" = 5) - result_amount = 1 - required_container = /obj/item/weapon/reagent_containers/food/snacks/flatdough - mix_message = "The dough forms a pie dough." - -/datum/chemical_reaction/piedough/on_reaction(var/datum/reagents/holder) - var/obj/item/weapon/reagent_containers/food/snacks/S = new /obj/item/weapon/reagent_containers/food/snacks/piedough - S.loc = get_turf(holder.my_atom) - if(holder && holder.my_atom) - qdel(holder.my_atom) - -/datum/chemical_reaction/cakebatter/alt - id = "cakebatteralt" - required_reagents = list("soymilk" = 5) - -/datum/chemical_reaction/piedough/alt - id = "piedoughalt" - required_reagents = list("soymilk" = 5) /datum/chemical_reaction/imitationcarpmeat name = "Imitation Carpmeat" @@ -164,22 +127,35 @@ if(holder && holder.my_atom) qdel(holder.my_atom) -/datum/chemical_reaction/rawpastrybase - name = "Raw Pastry Base" - id = "rawpastrybase" +/datum/chemical_reaction/dough + name = "Dough" + id = "dough" result = null - required_reagents = list("milk" = 5) + required_reagents = list("water" = 10, "flour" = 15) result_amount = 1 - required_container = /obj/item/weapon/reagent_containers/food/snacks/doughslice - mix_message = "The doughslice forms a raw pastry base" + mix_message = "The ingredients form a dough." -/datum/chemical_reaction/rawpastrybase/on_reaction(var/datum/reagents/holder) - var/obj/item/weapon/reagent_containers/food/snacks/S = new /obj/item/weapon/reagent_containers/food/snacks/rawpastrybase +/datum/chemical_reaction/cakebatter/on_reaction(var/datum/reagents/holder) + var/obj/item/weapon/reagent_containers/food/snacks/S = new /obj/item/weapon/reagent_containers/food/snacks/cakebatter S.loc = get_turf(holder.my_atom) if(holder && holder.my_atom) qdel(holder.my_atom) -/datum/chemical_reaction/rawpastrybase/alt - id = "rawpastrybasealt" - required_reagents = list("soymilk" = 5) +/datum/chemical_reaction/cakebatter + name = "Cake Batter" + id = "cakebatter" + result = null + required_reagents = list("eggyolk" = 15, "flour" = 15, "sugar" = 5) + result_amount = 1 + mix_message = "The ingredients form a cake batter." + +/datum/chemical_reaction/cakebatter/on_reaction(var/datum/reagents/holder) + var/obj/item/weapon/reagent_containers/food/snacks/S = new /obj/item/weapon/reagent_containers/food/snacks/cakebatter + S.loc = get_turf(holder.my_atom) + if(holder && holder.my_atom) + qdel(holder.my_atom) + +/datum/chemical_reaction/cakebatter/vegan + id = "vegancakebatter" + required_reagents = list("soymilk" = 15, "flour" = 15, "sugar" = 5) diff --git a/code/modules/food&drinks/recipes/tablecraft/recipes_cake.dm b/code/modules/food&drinks/recipes/tablecraft/recipes_cake.dm index e866629edca..e9fbbdacc7a 100644 --- a/code/modules/food&drinks/recipes/tablecraft/recipes_cake.dm +++ b/code/modules/food&drinks/recipes/tablecraft/recipes_cake.dm @@ -74,3 +74,11 @@ /obj/item/weapon/reagent_containers/food/snacks/store/cake/plain = 1 ) result = /obj/item/weapon/reagent_containers/food/snacks/store/cake/brain + +/datum/table_recipe/slimecake + name = "Slime cake" + reqs = list( + /obj/item/slime_extract = 1, + /obj/item/weapon/reagent_containers/food/snacks/store/cake/plain = 1 + ) + result = /obj/item/weapon/reagent_containers/food/snacks/store/cake/slimecake \ No newline at end of file diff --git a/code/modules/food&drinks/recipes/tablecraft/recipes_dough.dm b/code/modules/food&drinks/recipes/tablecraft/recipes_dough.dm deleted file mode 100644 index a81fee36e52..00000000000 --- a/code/modules/food&drinks/recipes/tablecraft/recipes_dough.dm +++ /dev/null @@ -1,53 +0,0 @@ - - -// see code/module/crafting/table.dm - -////////////////////////////////////////////////DOUGH//////////////////////////////////////////////// - -//these recipes can also be done with attackby. - -/datum/table_recipe/cakebatter - name = "Cake Batter" - reqs = list( - /datum/reagent/consumable/milk = 5, - /obj/item/weapon/reagent_containers/food/snacks/dough = 1 - ) - result = /obj/item/weapon/reagent_containers/food/snacks/cakebatter - -/datum/table_recipe/cakebatter/alt - reqs = list( - /datum/reagent/consumable/soymilk = 5, - /obj/item/weapon/reagent_containers/food/snacks/dough = 1 - ) - -/datum/table_recipe/piedough - name = "Pie Dough" - reqs = list( - /datum/reagent/consumable/milk = 5, - /obj/item/weapon/reagent_containers/food/snacks/flatdough = 1 - ) - result = /obj/item/weapon/reagent_containers/food/snacks/piedough - -/datum/table_recipe/piedough/alt - reqs = list( - /datum/reagent/consumable/soymilk = 5, - /obj/item/weapon/reagent_containers/food/snacks/flatdough = 1 - ) - -/datum/table_recipe/rawpastrybase - name = "Raw Pastry Base" - reqs = list( - /datum/reagent/consumable/milk = 5, - /obj/item/weapon/reagent_containers/food/snacks/doughslice = 1 - ) - result = /obj/item/weapon/reagent_containers/food/snacks/rawpastrybase - -/datum/table_recipe/rawpastrybase/alt - reqs = list( - /datum/reagent/consumable/soymilk = 5, - /obj/item/weapon/reagent_containers/food/snacks/doughslice = 1 - ) - - - - diff --git a/code/modules/food&drinks/recipes/tablecraft/recipes_sandwich.dm b/code/modules/food&drinks/recipes/tablecraft/recipes_sandwich.dm index 41aa0f936e6..57e1a1f6614 100644 --- a/code/modules/food&drinks/recipes/tablecraft/recipes_sandwich.dm +++ b/code/modules/food&drinks/recipes/tablecraft/recipes_sandwich.dm @@ -52,7 +52,7 @@ name = "Not a sandwich" reqs = list( /obj/item/weapon/reagent_containers/food/snacks/breadslice/plain = 2, - /obj/item/clothing/mask/fakemoustache + /obj/item/clothing/mask/fakemoustache = 1 ) result = /obj/item/weapon/reagent_containers/food/snacks/notasandwich diff --git a/code/modules/hydroponics/hydroponics.dm b/code/modules/hydroponics/hydroponics.dm index dc57adaae27..7294b806112 100644 --- a/code/modules/hydroponics/hydroponics.dm +++ b/code/modules/hydroponics/hydroponics.dm @@ -242,19 +242,22 @@ obj/machinery/hydroponics/update_icon() UpdateDescription() if(planted) + var/image/I if(dead) - overlays += image('icons/obj/hydroponics/growing.dmi', icon_state = "[myseed.species]-dead") + I = image('icons/obj/hydroponics/growing.dmi', icon_state = "[myseed.species]-dead") else if(harvest) if(myseed.plant_type == 2) // Shrooms don't have a -harvest graphic - overlays += image('icons/obj/hydroponics/growing.dmi', icon_state = "[myseed.species]-grow[myseed.growthstages]") + I = image('icons/obj/hydroponics/growing.dmi', icon_state = "[myseed.species]-grow[myseed.growthstages]") else - overlays += image('icons/obj/hydroponics/growing.dmi', icon_state = "[myseed.species]-harvest") + I = image('icons/obj/hydroponics/growing.dmi', icon_state = "[myseed.species]-harvest") else if(age < myseed.maturation) var/t_growthstate = ((age / myseed.maturation) * myseed.growthstages ) // Make sure it won't crap out due to HERPDERP 6 stages only - overlays += image('icons/obj/hydroponics/growing.dmi', icon_state = "[myseed.species]-grow[round(t_growthstate)]") + I = image('icons/obj/hydroponics/growing.dmi', icon_state = "[myseed.species]-grow[round(t_growthstate)]") lastproduce = age //Cheating by putting this here, it means that it isn't instantly ready to harvest else - overlays += image('icons/obj/hydroponics/growing.dmi', icon_state = "[myseed.species]-grow[myseed.growthstages]") // Same + I = image('icons/obj/hydroponics/growing.dmi', icon_state = "[myseed.species]-grow[myseed.growthstages]") // Same + I.layer = MOB_LAYER + 0.1 + overlays += I if(waterlevel <= 10) overlays += image('icons/obj/hydroponics/equipment.dmi', icon_state = "over_lowwater3") @@ -842,7 +845,9 @@ obj/machinery/hydroponics/attackby(var/obj/item/O as obj, var/mob/user as mob, p podman.ckey = ckey_holder podman.gender = blood_gender podman.faction |= factions - hardset_dna(podman,null,null,podman.real_name,blood_type,/datum/species/plant/pod)//Discard SE's and UI's, podman cloning is inaccurate, and always make them a podman + if(!mutant_color) + mutant_color = "#59CE00" + hardset_dna(podman,null,null,podman.real_name,blood_type,/datum/species/plant/pod,mutant_color)//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/seeds.dm b/code/modules/hydroponics/seeds.dm index 8765e6d2c67..a7aa6c83db0 100644 --- a/code/modules/hydroponics/seeds.dm +++ b/code/modules/hydroponics/seeds.dm @@ -90,6 +90,7 @@ var/datum/mind/mind = null var/blood_gender = null var/blood_type = null + var/mutant_color = null var/factions = null var/contains_sample = 0 @@ -103,6 +104,7 @@ realName = bloodSample.data["real_name"] blood_gender = bloodSample.data["gender"] blood_type = bloodSample.data["blood_type"] + mutant_color = bloodSample.data["mutant_color"] factions = bloodSample.data["factions"] W.reagents.clear_reagents() user << "You inject the contents of the syringe into the seeds." diff --git a/code/modules/mining/mine_items.dm b/code/modules/mining/mine_items.dm index 1d746d9068a..fffb61016e5 100644 --- a/code/modules/mining/mine_items.dm +++ b/code/modules/mining/mine_items.dm @@ -63,7 +63,6 @@ var/list/digsound = list('sound/effects/picaxe1.ogg','sound/effects/picaxe2.ogg','sound/effects/picaxe3.ogg') origin_tech = "materials=1;engineering=1" attack_verb = list("hit", "pierced", "sliced", "attacked") - var/powered = 1 //used to check for drill charge when mining /obj/item/weapon/pickaxe/proc/playDigSound() playsound(src, pick(digsound),50,1) @@ -87,21 +86,12 @@ desc = "An electric mining drill for the especially scrawny." var/drillcost = 125 //80 mineral walls by default var/obj/item/weapon/stock_parts/cell/high/bcell = null - powered = 0 /obj/item/weapon/pickaxe/drill/New() //this one starts with a cell pre-installed. ..() bcell = new(src) - update_charge() return -/obj/item/weapon/pickaxe/drill/proc/update_charge() - if(bcell && bcell.charge >= drillcost) - powered = 1 - else - powered = 0 - update_icon() - /obj/item/weapon/pickaxe/drill/update_icon() if(!bcell) icon_state = "[initial(icon_state)]-nocell" @@ -119,14 +109,14 @@ W.loc = src bcell = W user << "You install a cell in [src]." - update_charge() + update_icon() else if(istype(W, /obj/item/weapon/screwdriver)) if(bcell) bcell.updateicon() bcell.loc = get_turf(src.loc) bcell = null user << "You remove the cell from [src]." - update_charge() + update_icon() return ..() return diff --git a/code/modules/mining/mine_turfs.dm b/code/modules/mining/mine_turfs.dm index e7702171258..38afd36308c 100644 --- a/code/modules/mining/mine_turfs.dm +++ b/code/modules/mining/mine_turfs.dm @@ -392,39 +392,28 @@ if (!( istype(T, /turf) )) return - if(!P.powered) - return -/* - if (istype(W, /obj/item/weapon/pickaxe/radius)) - var/turf/T = user.loc - if (!( istype(T, /turf) )) - return -*/ -//Watch your tabbing, microwave. --NEO + if(istype(P, /obj/item/weapon/pickaxe/drill)) + var/obj/item/weapon/pickaxe/drill/D = P + if(isrobot(user)) + var/mob/living/silicon/robot/R = user + if(!R.cell.use(D.drillcost)) + R << "Your [D.name] doesn't have enough charge." + return + if(!D.bcell.use(D.drillcost)) + user << "Your [D.name] doesn't have enough charge." + return + if(last_act+P.digspeed > world.time)//prevents message spam return last_act = world.time user << "You start picking." - //playsound(user, 'sound/weapons/Genhit.ogg', 20, 1) P.playDigSound() if(do_after(user,P.digspeed)) - if(istype(P, /obj/item/weapon/pickaxe/drill)) - var/obj/item/weapon/pickaxe/drill/D = P - if(isrobot(user)) - var/mob/living/silicon/robot/R = user - if(R && R.cell) - if(!R.cell.use(D.drillcost)) - D.update_charge() - return - else - if(!D.bcell.use(D.drillcost)) - user << "Your drill ran out of power." - D.update_charge() - return - D.update_charge() - user << "You finish cutting into the rock." - gets_drilled(user) + if(istype(src, /turf/simulated/mineral)) //sanity check against turf being deleted during digspeed delay + user << "You finish cutting into the rock." + P.update_icon() + gets_drilled(user) else return attack_hand(user) return diff --git a/code/modules/mob/living/carbon/alien/life.dm b/code/modules/mob/living/carbon/alien/life.dm index 248333825ae..6654abf55f9 100644 --- a/code/modules/mob/living/carbon/alien/life.dm +++ b/code/modules/mob/living/carbon/alien/life.dm @@ -90,12 +90,4 @@ handle_hud_icons_health() - if(pullin) - if(pulling) - pullin.icon_state = "pull" - else - pullin.icon_state = "pull0" - - - - return 1 + return 1 \ No newline at end of file diff --git a/code/modules/mob/living/carbon/brain/emote.dm b/code/modules/mob/living/carbon/brain/emote.dm index 6c7b938288f..4a75b2765fe 100644 --- a/code/modules/mob/living/carbon/brain/emote.dm +++ b/code/modules/mob/living/carbon/brain/emote.dm @@ -62,7 +62,7 @@ for(var/mob/M in dead_mob_list) if (!M.client || istype(M, /mob/new_player)) continue //skip monkeys, leavers, and new_players - if(M.stat == DEAD && (M.client && (M.client.prefs.toggles & CHAT_GHOSTSIGHT)) && !(M in viewers(src,null))) + if(M.stat == DEAD && (M.client && (M.client.prefs.chat_toggles & CHAT_GHOSTSIGHT)) && !(M in viewers(src,null))) M.show_message(message) diff --git a/code/modules/mob/living/carbon/emote.dm b/code/modules/mob/living/carbon/emote.dm index 0c9893c0d39..cdbb56ad240 100644 --- a/code/modules/mob/living/carbon/emote.dm +++ b/code/modules/mob/living/carbon/emote.dm @@ -188,7 +188,7 @@ for(var/mob/M in dead_mob_list) if(!M.client || istype(M, /mob/new_player)) continue //skip monkeys, leavers and new players - if(M.stat == DEAD && M.client && (M.client.prefs.toggles & CHAT_GHOSTSIGHT) && !(M in viewers(src,null))) + if(M.stat == DEAD && M.client && (M.client.prefs.chat_toggles & CHAT_GHOSTSIGHT) && !(M in viewers(src,null))) M.show_message(message) diff --git a/code/modules/mob/living/carbon/human/blood.dm b/code/modules/mob/living/carbon/human/blood.dm index e8c04f0444b..48da639f97e 100644 --- a/code/modules/mob/living/carbon/human/blood.dm +++ b/code/modules/mob/living/carbon/human/blood.dm @@ -30,7 +30,7 @@ var/const/BLOOD_VOLUME_SURVIVE = 122 /mob/living/carbon/human/proc/fixblood() for(var/datum/reagent/blood/B in vessel.reagent_list) if(B.id == "blood") - B.data = list("donor"=src,"viruses"=null,"blood_DNA"=dna.unique_enzymes,"blood_type"=dna.blood_type,"resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null) + B.data = list("donor"=src,"viruses"=null,"blood_DNA"=dna.unique_enzymes,"blood_type"=dna.blood_type,"resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"mutant_color"=null, "factions"=null) /mob/living/carbon/human/proc/suppress_bloodloss(var/amount) if(bleedsuppress) @@ -171,6 +171,7 @@ var/const/BLOOD_VOLUME_SURVIVE = 122 B.data["blood_type"] = copytext(src.dna.blood_type,1,0) B.data["gender"] = src.gender B.data["real_name"] = src.real_name + B.data["mutant_color"] = src.dna.mutant_color B.data["factions"] = src.faction return B diff --git a/code/modules/mob/living/carbon/human/emote.dm b/code/modules/mob/living/carbon/human/emote.dm index 4c16885f216..bc73e507787 100644 --- a/code/modules/mob/living/carbon/human/emote.dm +++ b/code/modules/mob/living/carbon/human/emote.dm @@ -328,7 +328,7 @@ for(var/mob/M in dead_mob_list) if(!M.client || istype(M, /mob/new_player)) continue //skip monkeys, leavers and new players - if(M.stat == DEAD && M.client && (M.client.prefs.toggles & CHAT_GHOSTSIGHT) && !(M in viewers(src,null))) + if(M.stat == DEAD && M.client && (M.client.prefs.chat_toggles & CHAT_GHOSTSIGHT) && !(M in viewers(src,null))) M.show_message(message) diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 6e546dfaabf..96855646337 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -73,8 +73,12 @@ if(mind.changeling) stat("Chemical Storage", "[mind.changeling.chem_charges]/[mind.changeling.chem_storage]") stat("Absorbed DNA", mind.changeling.absorbedcount) - if (istype(wear_suit, /obj/item/clothing/suit/space/space_ninja)&&wear_suit:s_initialized) - stat("Energy Charge", round(wear_suit:cell:charge/100)) + + //NINJACODE + if(istype(wear_suit, /obj/item/clothing/suit/space/space_ninja)) + var/obj/item/clothing/suit/space/space_ninja/SN = wear_suit + if(SN.s_initialized) + stat("Energy Charge", round(SN.cell.charge/100)) /mob/living/carbon/human/ex_act(severity, ex_target) @@ -251,11 +255,11 @@ var/obj/item/organ/limb/L = locate(href_list["embedded_limb"]) if(!I || !L || I.loc != src) //no item, no limb, or item is not in limb (the person atleast) anymore return - var/time_taken = 30*I.w_class + var/time_taken = I.embedded_unsafe_removal_time*I.w_class usr.visible_message("[usr] attempts to remove [I] from their [L.getDisplayName()]!","You attempt to remove [I] from your [L.getDisplayName()], it will take [time_taken/10] seconds.") if(do_after(usr, time_taken, needhand = 1)) L.embedded_objects -= I - L.take_damage(8*I.w_class)//It hurts to rip it out, get surgery you dingus. + L.take_damage(I.embedded_unsafe_removal_pain_multiplier*I.w_class)//It hurts to rip it out, get surgery you dingus. I.loc = get_turf(src) usr.put_in_hands(I) usr.emote("scream") diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index 0748e9d3747..108d680a734 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -67,7 +67,7 @@ emp_act return 2 return (..(P , def_zone)) -/mob/living/carbon/human/proc/check_reflect(var/def_zone) //Reflection checks for anything in your l_hand, r_hand, or wear_suit based on reflect_chance var of the object +/mob/living/carbon/human/proc/check_reflect(var/def_zone) //Reflection checks for anything in your l_hand, r_hand, or wear_suit based on the reflection chance of the object if(wear_suit && istype(wear_suit, /obj/item/)) var/obj/item/I = wear_suit if(I.IsReflect(def_zone) == 1) diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index 8738f4da1f0..71b8c4f9dbb 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -38,6 +38,9 @@ tinttotal = tintcheck() //here as both hud updates and status updates call it if(..()) + if(dna) + for(var/datum/mutation/human/HM in dna.mutations) + HM.on_life(src) //Stuff jammed in your limbs hurts handle_embedded_objects() @@ -347,11 +350,11 @@ for(var/obj/item/organ/limb/L in organs) for(var/obj/item/I in L.embedded_objects) if(prob(I.embedded_pain_chance)) - L.take_damage(I.w_class*2) + L.take_damage(I.w_class*I.embedded_pain_multiplier) src << "\the [I] embedded in your [L.getDisplayName()] hurts!" if(prob(I.embedded_fall_chance)) - L.take_damage(I.w_class*5) + L.take_damage(I.w_class*I.embedded_fall_pain_multiplier) L.embedded_objects -= I I.loc = get_turf(src) visible_message("\the [I] falls out of [name]'s [L.getDisplayName()]!","\the [I] falls out of your [L.getDisplayName()]!") diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm index 124d77b23db..9ede33a4c9b 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -608,14 +608,6 @@ else H.throw_alert("nutrition","starving") - if(H.pullin) - if(H.pulling) H.pullin.icon_state = "pull" - else H.pullin.icon_state = "pull0" -// if(rest) //Not used with new UI -// if(resting || lying || sleeping) rest.icon_state = "rest1" -// else rest.icon_state = "rest0" - - return 1 /datum/species/proc/handle_mutations_and_radiation(var/mob/living/carbon/human/H) @@ -757,7 +749,8 @@ atk_verb = M.dna.species.attack_verb var/damage = rand(0, 9) - damage += punchmod + if(M.dna) + damage += M.dna.species.punchmod if(!damage) if(M.dna) diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index f9f227fa930..9139c933661 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -264,7 +264,12 @@ Please contact me on #coderbus IRC. ~Carnie x var/t_color = w_uniform.item_color if(!t_color) t_color = icon_state - var/image/standing = image("icon"='icons/mob/uniform.dmi', "icon_state"="[t_color]_s", "layer"=-UNIFORM_LAYER) + + var/image/standing + if(U.alternate_worn_icon) + standing = image("icon"=U.alternate_worn_icon, "icon_state"="[t_color]_s", "layer"=-UNIFORM_LAYER) + if(!standing) + standing = image("icon"='icons/mob/uniform.dmi', "icon_state"="[t_color]_s", "layer"=-UNIFORM_LAYER) overlays_standing[UNIFORM_LAYER] = standing @@ -311,7 +316,13 @@ Please contact me on #coderbus IRC. ~Carnie x var/t_state = gloves.item_state if(!t_state) t_state = gloves.icon_state - var/image/standing = image("icon"='icons/mob/hands.dmi', "icon_state"="[t_state]", "layer"=-GLOVES_LAYER) + + var/image/standing + if(gloves.alternate_worn_icon) + standing = image("icon"=gloves.alternate_worn_icon, "icon_state"="[t_state]", "layer"=-GLOVES_LAYER) + if(!standing) + standing = image("icon"='icons/mob/hands.dmi', "icon_state"="[t_state]", "layer"=-GLOVES_LAYER) + overlays_standing[GLOVES_LAYER] = standing if(gloves.blood_DNA) @@ -334,7 +345,13 @@ Please contact me on #coderbus IRC. ~Carnie x glasses.screen_loc = ui_glasses //...draw the item in the inventory screen client.screen += glasses //Either way, add the item to the HUD - overlays_standing[GLASSES_LAYER] = image("icon"='icons/mob/eyes.dmi', "icon_state"="[glasses.icon_state]", "layer"=-GLASSES_LAYER) + var/image/standing + if(glasses.alternate_worn_icon) + standing = image("icon"=glasses.alternate_worn_icon, "icon_state"="[glasses.icon_state]","layer"=-GLASSES_LAYER) + if(!standing) + standing = image("icon"='icons/mob/eyes.dmi', "icon_state"="[glasses.icon_state]", "layer"=-GLASSES_LAYER) + + overlays_standing[GLASSES_LAYER] = standing apply_overlay(GLASSES_LAYER) @@ -348,7 +365,13 @@ Please contact me on #coderbus IRC. ~Carnie x ears.screen_loc = ui_ears //...draw the item in the inventory screen client.screen += ears //Either way, add the item to the HUD - overlays_standing[EARS_LAYER] = image("icon"='icons/mob/ears.dmi', "icon_state"="[ears.icon_state]", "layer"=-EARS_LAYER) + var/image/standing + if(ears.alternate_worn_icon) + standing = image("icon"=ears.alternate_worn_icon, "icon_state"="[ears.icon_state]", "layer"=-EARS_LAYER) + if(!standing) + standing = image("icon"='icons/mob/ears.dmi', "icon_state"="[ears.icon_state]", "layer"=-EARS_LAYER) + + overlays_standing[EARS_LAYER] = standing apply_overlay(EARS_LAYER) @@ -362,7 +385,11 @@ Please contact me on #coderbus IRC. ~Carnie x shoes.screen_loc = ui_shoes //...draw the item in the inventory screen client.screen += shoes //Either way, add the item to the HUD - var/image/standing = image("icon"='icons/mob/feet.dmi', "icon_state"="[shoes.icon_state]", "layer"=-SHOES_LAYER) + var/image/standing + if(shoes.alternate_worn_icon) + standing = image("icon"=shoes.alternate_worn_icon, "icon_state"="[shoes.icon_state]","layer"=-SHOES_LAYER) + if(!standing) + standing = image("icon"='icons/mob/feet.dmi', "icon_state"="[shoes.icon_state]", "layer"=-SHOES_LAYER) overlays_standing[SHOES_LAYER] = standing if(shoes.blood_DNA) @@ -396,7 +423,11 @@ Please contact me on #coderbus IRC. ~Carnie x head.screen_loc = ui_head //TODO //...draw the item in the inventory screen client.screen += head //Either way, add the item to the HUD - var/image/standing = image("icon"='icons/mob/head.dmi', "icon_state"="[head.icon_state]", "layer"=-HEAD_LAYER) + var/image/standing + if(head.alternate_worn_icon) + standing = image("icon"=head.alternate_worn_icon, "icon_state"="[head.icon_state]", "layer"=-HEAD_LAYER) + if(!standing) + standing = image("icon"='icons/mob/head.dmi', "icon_state"="[head.icon_state]", "layer"=-HEAD_LAYER) standing.color = head.color // For now, this is here solely for kitty ears, but everything should do this eventually standing.alpha = head.alpha @@ -418,7 +449,14 @@ Please contact me on #coderbus IRC. ~Carnie x var/t_state = belt.item_state if(!t_state) t_state = belt.icon_state - overlays_standing[BELT_LAYER] = image("icon"='icons/mob/belt.dmi', "icon_state"="[t_state]", "layer"=-BELT_LAYER) + + var/image/standing + if(belt.alternate_worn_icon) + standing = image("icon"=belt.alternate_worn_icon, "icon_state"="[t_state]", "layer"=-BELT_LAYER) + if(!standing) + standing = image("icon"='icons/mob/belt.dmi', "icon_state"="[t_state]", "layer"=-BELT_LAYER) + + overlays_standing[BELT_LAYER] = standing apply_overlay(BELT_LAYER) @@ -433,7 +471,11 @@ Please contact me on #coderbus IRC. ~Carnie x wear_suit.screen_loc = ui_oclothing //TODO //...draw the item in the inventory screen client.screen += wear_suit //Either way, add the item to the HUD - var/image/standing = image("icon"='icons/mob/suit.dmi', "icon_state"="[wear_suit.icon_state]", "layer"=-SUIT_LAYER) + var/image/standing + if(wear_suit.alternate_worn_icon) + standing = image("icon"=wear_suit.alternate_worn_icon, "icon_state"="[wear_suit.icon_state]", "layer"=-SUIT_LAYER) + if(!standing) + standing = image("icon"='icons/mob/suit.dmi', "icon_state"="[wear_suit.icon_state]", "layer"=-SUIT_LAYER) overlays_standing[SUIT_LAYER] = standing if(istype(wear_suit, /obj/item/clothing/suit/straight_jacket)) @@ -470,7 +512,12 @@ Please contact me on #coderbus IRC. ~Carnie x wear_mask.screen_loc = ui_mask //TODO //...draw the item in the inventory screen client.screen += wear_mask //Either way, add the item to the HUD - var/image/standing = image("icon"='icons/mob/mask.dmi', "icon_state"="[wear_mask.icon_state]", "layer"=-FACEMASK_LAYER) + var/image/standing + if(wear_mask.alternate_worn_icon) + standing = image("icon"=wear_mask.alternate_worn_icon, "icon_state"="[wear_mask.icon_state]", "layer"=-FACEMASK_LAYER) + if(!standing) + standing = image("icon"='icons/mob/mask.dmi', "icon_state"="[wear_mask.icon_state]", "layer"=-FACEMASK_LAYER) + overlays_standing[FACEMASK_LAYER] = standing if(wear_mask.blood_DNA && !istype(wear_mask, /obj/item/clothing/mask/cigarette)) @@ -488,7 +535,13 @@ Please contact me on #coderbus IRC. ~Carnie x if(client && hud_used && hud_used.hud_shown) client.screen += back - overlays_standing[BACK_LAYER] = image("icon"='icons/mob/back.dmi', "icon_state"="[back.icon_state]", "layer"=-BACK_LAYER) + var/image/standing + if(back.alternate_worn_icon) + standing = image("icon"=back.alternate_worn_icon, "icon_state"="[back.icon_state]", "layer"=-BACK_LAYER) + if(!standing) + standing = image("icon"='icons/mob/back.dmi', "icon_state"="[back.icon_state]", "layer"=-BACK_LAYER) + + overlays_standing[BACK_LAYER] = standing apply_overlay(BACK_LAYER) diff --git a/code/modules/mob/living/carbon/human/whisper.dm b/code/modules/mob/living/carbon/human/whisper.dm index b7df925da57..24d98e205e7 100644 --- a/code/modules/mob/living/carbon/human/whisper.dm +++ b/code/modules/mob/living/carbon/human/whisper.dm @@ -46,7 +46,7 @@ var/list/listening_dead = list() for(var/mob/M in player_list) - if(M.stat == DEAD && M.client && ((M.client.prefs.toggles & CHAT_GHOSTWHISPER) || (get_dist(M, src) <= 7))) + if(M.stat == DEAD && M.client && ((M.client.prefs.chat_toggles & CHAT_GHOSTWHISPER) || (get_dist(M, src) <= 7))) listening_dead |= M var/list/listening = get_hearers_in_view(1, src) diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm index d683811948d..3a51992007d 100644 --- a/code/modules/mob/living/carbon/life.dm +++ b/code/modules/mob/living/carbon/life.dm @@ -349,12 +349,12 @@ silent = 0 return 1 - if( (getOxyLoss() > 50) || (config.health_threshold_crit >= health) ) + if(getOxyLoss() > 50 || health <= config.health_threshold_crit) Paralyse(3) + stat = UNCONSCIOUS if(paralysis) AdjustParalysis(-1) - stat = UNCONSCIOUS else if(sleeping) handle_dreams() adjustStaminaLoss(-10) diff --git a/code/modules/mob/living/carbon/monkey/life.dm b/code/modules/mob/living/carbon/monkey/life.dm index f9589c35ca9..12cac68350c 100644 --- a/code/modules/mob/living/carbon/monkey/life.dm +++ b/code/modules/mob/living/carbon/monkey/life.dm @@ -97,16 +97,6 @@ handle_hud_icons_health() - - - if(pullin) - if(pulling) - pullin.icon_state = "pull" - else - pullin.icon_state = "pull0" - - //blame the person who coded them. Temporary fix added. - return 1 /mob/living/carbon/monkey/handle_random_events() diff --git a/code/modules/mob/living/carbon/slime/life.dm b/code/modules/mob/living/carbon/slime/life.dm index f15fd5196a7..484f2700ae8 100644 --- a/code/modules/mob/living/carbon/slime/life.dm +++ b/code/modules/mob/living/carbon/slime/life.dm @@ -234,6 +234,10 @@ /mob/living/carbon/slime/proc/handle_nutrition() + if(docile) //God as my witness, I will never go hungry again + nutrition = 700 + return + if(prob(15)) nutrition -= 1 + is_adult @@ -291,7 +295,7 @@ if(Target) --target_patience - if (target_patience <= 0 || SStun || Discipline || attacked) // Tired of chasing or something draws out attention + if (target_patience <= 0 || SStun || Discipline || attacked || docile) // Tired of chasing or something draws out attention target_patience = 0 Target = null @@ -385,6 +389,7 @@ //Mood starts here var/newmood = "" if (rabid || attacked) newmood = "angry" + else if (docile) newmood = ":3" else if (Target) newmood = "mischevous" if (!newmood) @@ -555,6 +560,7 @@ else return 200 /mob/living/carbon/slime/proc/will_hunt(var/hunger = -1) // Check for being stopped from feeding and chasing + if (docile) return 0 if (hunger == 2 || rabid || attacked) return 1 if (Leader) return 0 if (holding_still) return 0 diff --git a/code/modules/mob/living/carbon/slime/powers.dm b/code/modules/mob/living/carbon/slime/powers.dm index ef91582c3ec..01918ec5fc5 100644 --- a/code/modules/mob/living/carbon/slime/powers.dm +++ b/code/modules/mob/living/carbon/slime/powers.dm @@ -5,6 +5,10 @@ Feedstop() return 0 + if(docile) + src << "I'm not hungry anymore..." + return 0 + if(stat) src << "I must be conscious to do this..." return 0 diff --git a/code/modules/mob/living/carbon/slime/slime.dm b/code/modules/mob/living/carbon/slime/slime.dm index 2cce3590566..beff640a3f2 100644 --- a/code/modules/mob/living/carbon/slime/slime.dm +++ b/code/modules/mob/living/carbon/slime/slime.dm @@ -6,6 +6,7 @@ say_message = "hums" ventcrawler = 2 var/is_adult = 0 + var/docile = 0 languages = SLIME | HUMAN faction = list("slime") @@ -135,8 +136,8 @@ stat(null, "Health: [round((health / 200) * 100)]%") else stat(null, "Health: [round((health / 150) * 100)]%") - - stat(null, "Nutrition: [nutrition]/[get_max_nutrition()]") + if(!docile) + stat(null, "Nutrition: [nutrition]/[get_max_nutrition()]") if(amount_grown >= 10) if(is_adult) stat(null, "You can reproduce!") @@ -602,71 +603,60 @@ ////Pet Slime Creation/// -/obj/item/weapon/slimepotion +/obj/item/slimepotion name = "docility potion" - desc = "A potent chemical mix that will nullify a slime's powers, causing it to become docile and tame." + desc = "A potent chemical mix that nullifies a slime's hunger, causing it to become docile and tame." icon = 'icons/obj/chemical.dmi' icon_state = "bottle19" - attack(mob/living/carbon/slime/M as mob, mob/user as mob) - if(!istype(M, /mob/living/carbon/slime))//If target is not a slime. - user << " The potion only works on baby slimes!" - return ..() - if(M.is_adult) //Can't tame adults - user << " Only baby slimes can be tamed!" - return..() - if(M.stat) - user << " The slime is dead!" - return..() - if(M.mind) - user << " The slime resists!" - return ..() - var/mob/living/simple_animal/slime/pet = new /mob/living/simple_animal/slime(M.loc) - pet.icon_state = "[M.colour] baby slime" - pet.icon_living = "[M.colour] baby slime" - pet.icon_dead = "[M.colour] baby slime dead" - pet.colour = "[M.colour]" - user <<"You feed the slime the potion, removing it's powers and calming it." - qdel(M) - var/newname = copytext(sanitize(input(user, "Would you like to give the slime a name?", "Name your new pet", "pet slime") as null|text),1,MAX_NAME_LEN) - - if (!newname) - newname = "pet slime" - pet.name = newname - pet.real_name = newname - qdel(src) - -/obj/item/weapon/slimepotion2 - name = "advanced docility potion" - desc = "A potent chemical mix that will nullify a slime's powers, causing it to become docile and tame. This one is meant for adult slimes" - icon = 'icons/obj/chemical.dmi' - icon_state = "bottle19" - -/obj/item/weapon/slimepotion2/attack(mob/living/carbon/slime/M as mob, mob/user as mob) - if(!istype(M, /mob/living/carbon/slime/))//If target is not a slime. - user << " The potion only works on slimes!" +/obj/item/slimepotion/attack(mob/living/carbon/slime/M as mob, mob/user as mob) + if(!isslime(M)) + user << "The potion only works on slimes!" return ..() if(M.stat) - user << " The slime is dead!" + user << "The slime is dead!" return..() - if(M.mind) - user << " The slime resists!" - return ..() - var/mob/living/simple_animal/slime/adult/pet = new /mob/living/simple_animal/slime/adult(M.loc) - pet.icon_state = "[M.colour] adult slime" - pet.icon_living = "[M.colour] adult slime" - pet.icon_dead = "[M.colour] baby slime dead" - pet.colour = "[M.colour]" - user <<"You feed the slime the potion, removing it's powers and calming it." - qdel(M) + + M.docile = 1 + M.nutrition = 700 + M <<" You absorb the potion and feel your intense desire to feed melt away." + user <<" You feed the slime the potion, removing it's hunger and calming it." var/newname = copytext(sanitize(input(user, "Would you like to give the slime a name?", "Name your new pet", "pet slime") as null|text),1,MAX_NAME_LEN) if (!newname) newname = "pet slime" - pet.name = newname - pet.real_name = newname + M.name = newname + M.real_name = newname qdel(src) +/obj/item/slimepotion2 + name = "sentience potion" + desc = "A miraculous chemical mix that can raise the intelligence of creatures to human levels." + icon = 'icons/obj/chemical.dmi' + icon_state = "bottle19" + +/obj/item/slimepotion2/afterattack(mob/living/M as mob, mob/user as mob) + if(!(isslime(M) || isanimal(M) || ismonkey(M) || !M.ckey)) //I'm sorry for this line + user << "[M] is already too intelligent for this to work!" + return ..() + if(M.stat) + user << "[M] is dead!" + return..() + + var/list/candidates = get_candidates(BE_ALIEN, ALIEN_AFK_BRACKET) + var/client/C = null + + if(candidates.len) + C = pick(candidates) + M.key = C.key + M.languages |= HUMAN + M << "All at once it makes sense, you know what you are and who you are! Self awareness is yours!" + M << "You are grateful to be self aware and owe [user] a great debt. Serve [user], and assist them in completing their goals at any cost." + user << "[M] is suddenly attentive and aware. It worked!" + qdel(src) + else + user << "[M] looks interested for a moment, but then looks back down. Maybe you should try again later..." + ..() /obj/item/weapon/slimesteroid name = "slime steroid" diff --git a/code/modules/mob/living/emote.dm b/code/modules/mob/living/emote.dm index 891fae0abeb..35817513e08 100644 --- a/code/modules/mob/living/emote.dm +++ b/code/modules/mob/living/emote.dm @@ -268,7 +268,7 @@ if(!M.client || istype(M, /mob/new_player)) continue //skip monkeys, leavers and new players var/T = get_turf(src) - if(M.stat == DEAD && M.client && (M.client.prefs.toggles & CHAT_GHOSTSIGHT) && !(M in viewers(T,null))) + if(M.stat == DEAD && M.client && (M.client.prefs.chat_toggles & CHAT_GHOSTSIGHT) && !(M in viewers(T,null))) M.show_message(message) diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 9dc994a1bad..3772bd681fa 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -450,6 +450,8 @@ Sorry Giacom. Please don't be mad :( if(ishuman(src)) var/mob/living/carbon/human/human_mob = src human_mob.restore_blood() + human_mob.remove_all_embedded_objects() + update_fire() regenerate_icons() ..() diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm index e68d1be4cdf..d158b3648c1 100644 --- a/code/modules/mob/living/say.dm +++ b/code/modules/mob/living/say.dm @@ -161,7 +161,7 @@ var/list/department_radio_keys = list( var/list/listening = get_hearers_in_view(message_range, source) var/list/listening_dead = list() for(var/mob/M in player_list) - if(M.stat == DEAD && M.client && ((M.client.prefs.toggles & CHAT_GHOSTEARS) || (get_dist(M, src) <= 7)) && client) // client is so that ghosts don't have to listen to mice + if(M.stat == DEAD && M.client && ((M.client.prefs.chat_toggles & CHAT_GHOSTEARS) || (get_dist(M, src) <= 7)) && client) // client is so that ghosts don't have to listen to mice listening_dead |= M listening -= listening_dead //so ghosts dont hear stuff twice diff --git a/code/modules/mob/living/silicon/robot/life.dm b/code/modules/mob/living/silicon/robot/life.dm index d90e464cee2..94ee5d29975 100644 --- a/code/modules/mob/living/silicon/robot/life.dm +++ b/code/modules/mob/living/silicon/robot/life.dm @@ -206,13 +206,6 @@ else throw_alert("charge","nocell") - - if(pullin) - if(pulling) - pullin.icon_state = "pull" - else - pullin.icon_state = "pull0" - client.screen.Remove(global_hud.blurry,global_hud.druggy,global_hud.vimpaired) if ((src.blind && src.stat != 2)) diff --git a/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm b/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm index 4a003c9a72f..8a70dd5e4b2 100644 --- a/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm +++ b/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm @@ -119,15 +119,6 @@ user << "The drone's LED screen shows a BSOD, Blue screen of Death!" -/mob/living/simple_animal/drone/Move() - if(pullin) - if(pulling) - pullin.icon_state = "pull" - else - pullin.icon_state = "pull0" - ..() - - /mob/living/simple_animal/drone/IsAdvancedToolUser() return 1 diff --git a/code/modules/mob/living/simple_animal/hostile/alien.dm b/code/modules/mob/living/simple_animal/hostile/alien.dm index e08f84a93fd..b00b0c95e70 100644 --- a/code/modules/mob/living/simple_animal/hostile/alien.dm +++ b/code/modules/mob/living/simple_animal/hostile/alien.dm @@ -43,6 +43,17 @@ health = 60 melee_damage_lower = 15 melee_damage_upper = 15 + var/plant_cooldown = 30 + var/plants_off = 0 + +/mob/living/simple_animal/hostile/alien/drone/Life() + ..() + if(!stat) + plant_cooldown-- + if(stance==HOSTILE_STANCE_IDLE) + if(!plants_off && prob(10) && plant_cooldown<=0) + plant_cooldown = initial(plant_cooldown) + SpreadPlants() /mob/living/simple_animal/hostile/alien/sentinel name = "alien sentinel" @@ -75,6 +86,39 @@ projectiletype = /obj/item/projectile/neurotox projectilesound = 'sound/weapons/pierce.ogg' status_flags = 0 + var/sterile = 1 + var/plants_off = 0 + var/egg_cooldown = 30 + var/plant_cooldown = 30 + +/mob/living/simple_animal/hostile/alien/queen/Life() + ..() + if(!stat) + egg_cooldown-- + plant_cooldown-- + if(stance==HOSTILE_STANCE_IDLE) + if(!plants_off && prob(10) && plant_cooldown<=0) + plant_cooldown = initial(plant_cooldown) + SpreadPlants() + if(!sterile && prob(10) && egg_cooldown<=0) + egg_cooldown = initial(egg_cooldown) + LayEggs() + +/mob/living/simple_animal/hostile/alien/proc/SpreadPlants() + if(!isturf(loc) || istype(loc, /turf/space)) + return + if(locate(/obj/structure/alien/weeds/node) in get_turf(src)) + return + visible_message("[src] has planted some alien weeds!") + new /obj/structure/alien/weeds/node(loc) + +/mob/living/simple_animal/hostile/alien/proc/LayEggs() + if(!isturf(loc) || istype(loc, /turf/space)) + return + if(locate(/obj/structure/alien/egg) in get_turf(src)) + return + visible_message("[src] has laid an egg!") + new /obj/structure/alien/egg(loc) /mob/living/simple_animal/hostile/alien/queen/large name = "alien empress" diff --git a/code/modules/mob/living/simple_animal/hostile/hostile.dm b/code/modules/mob/living/simple_animal/hostile/hostile.dm index 3828dbdce6c..7d1b74fe07a 100644 --- a/code/modules/mob/living/simple_animal/hostile/hostile.dm +++ b/code/modules/mob/living/simple_animal/hostile/hostile.dm @@ -30,6 +30,8 @@ var/stat_exclusive = 0 //Mobs with this set to 1 will exclusively attack things defined by stat_attack, stat_attack 2 means they will only attack corpses var/attack_same = 0 //Set us to 1 to allow us to attack our own faction, or 2, to only ever attack our own faction + var/AIStatus = AI_ON //The Status of our AI, can be set to AI_ON (On, usual processing), AI_SLEEP (Will not process, but will return to AI_ON if an enemy comes near), AI_OFF (Off, Not processing ever) + /mob/living/simple_animal/hostile/Life() . = ..() @@ -40,6 +42,8 @@ ranged_cooldown-- if(client) return 0 + if(!AICanContinue()) + return 0 if(!stat) switch(stance) if(HOSTILE_STANCE_IDLE) @@ -56,6 +60,9 @@ AttackTarget() DestroySurroundings() + if(AIShouldSleep()) + AIStatus = AI_SLEEP + //////////////HOSTILE MOB TARGETTING AND AGGRESSION//////////// @@ -313,4 +320,33 @@ if(ranged && ranged_cooldown <= 0) target = A OpenFire(A) - ..() \ No newline at end of file + ..() + + + +////// AI Status /////// +/mob/living/simple_animal/hostile/proc/AICanContinue() + switch(AIStatus) + if(AI_ON) + . = 1 + if(AI_SLEEP) + if(AIShouldWake()) + . = 1 + AIStatus = AI_ON //Wake up for more than one Life() cycle. + else + . = 0 + if(AI_OFF) + . = 0 + + +//Returns 1 if the AI should wake up +//Returns 0 if the AI should remain asleep +/mob/living/simple_animal/hostile/proc/AIShouldWake() + . = 0 + if(FindTarget()) + . = 1 + + +//Convenience +/mob/living/simple_animal/hostile/proc/AIShouldSleep() + . = !(AIShouldWake()) \ No newline at end of file diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index e9b5cc5f4c9..0743fbaa710 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -390,6 +390,8 @@ var/list/slot_equipment_priority = list( \ src.pulling = AM AM.pulledby = src + if(pullin) + pullin.update_icon(src) if(ismob(AM)) var/mob/M = AM if(!iscarbon(src)) @@ -405,6 +407,8 @@ var/list/slot_equipment_priority = list( \ if(pulling) pulling.pulledby = null pulling = null + if(pullin) + pullin.update_icon(src) /mob/verb/mode() set name = "Activate Held Object" diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index 6db29529209..b8d73c2e266 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -286,7 +286,7 @@ proc/Gibberish(t, p)//t is the inputted message, and any value higher than 70 fo return returntext -/proc/ninjaspeak(n) +/proc/ninjaspeak(n) //NINJACODE /* The difference with stutter is that this proc can stutter more than 1 letter The issue here is that anything that does not have a space is treated as one word (in many instances). For instance, "LOOKING," is a word, including the comma. diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm index b33337556f3..70a8b157f64 100644 --- a/code/modules/mob/new_player/new_player.dm +++ b/code/modules/mob/new_player/new_player.dm @@ -251,6 +251,8 @@ return 0 if((job.current_positions >= job.total_positions) && job.total_positions != -1) if(job.title == "Assistant") + if(isnum(client.player_age) && client.player_age <= 14) //Newbies can always be assistants + return 1 for(var/datum/job/J in SSjob.occupations) if(J && J.current_positions < J.total_positions && J.title != job.title) return 0 diff --git a/code/modules/mob/say.dm b/code/modules/mob/say.dm index 544522c7934..95ac2edf15f 100644 --- a/code/modules/mob/say.dm +++ b/code/modules/mob/say.dm @@ -45,7 +45,7 @@ for(var/mob/M in player_list) if(istype(M, /mob/new_player)) continue - if(M.client && M.client.holder && (M.client.prefs.toggles & CHAT_DEAD)) //admins can toggle deadchat on and off. This is a proc in admin.dm and is only give to Administrators and above + if(M.client && M.client.holder && (M.client.prefs.chat_toggles & CHAT_DEAD)) //admins can toggle deadchat on and off. This is a proc in admin.dm and is only give to Administrators and above M << rendered //Admins can hear deadchat, if they choose to, no matter if they're blind/deaf or not. else if(M.stat == DEAD) //M.show_message(rendered, 2) //Takes into account blindness and such. //preserved so you can look at it and cry at the stupidity of oldcoders. whoever coded this should be punched into the sun diff --git a/code/modules/ninja/Ninja_Readme.dm b/code/modules/ninja/Ninja_Readme.dm new file mode 100644 index 00000000000..2d383f9b1fa --- /dev/null +++ b/code/modules/ninja/Ninja_Readme.dm @@ -0,0 +1,10 @@ + +/* + +Removing Snowflake: +- Search for NINJACODE (one word, all caps) to find Space Ninja Code outside of the /modules/ninja folder. + +Ninja Folder: +- This folder contains 90% of Ninja code and will eventually contain it all, once snowflake is cleaned out + +*/ diff --git a/code/modules/ninja/__ninjaDefines.dm b/code/modules/ninja/__ninjaDefines.dm new file mode 100644 index 00000000000..a8dc65f9f13 --- /dev/null +++ b/code/modules/ninja/__ninjaDefines.dm @@ -0,0 +1,13 @@ + +/* + +Contents: +- Definitions, because the original Ninja code has so much magic. + +*/ + + +//ninjacost() specificCheck defines +#define N_STEALTH_CANCEL 1 +#define N_SMOKE_BOMB 2 +#define N_ADRENALINE 3 \ No newline at end of file diff --git a/code/modules/ninja/admin_ninja_verbs.dm b/code/modules/ninja/admin_ninja_verbs.dm new file mode 100644 index 00000000000..59baa2c48e9 --- /dev/null +++ b/code/modules/ninja/admin_ninja_verbs.dm @@ -0,0 +1,61 @@ + +/* + +Contents: +- Admin procs that make ninjas + +*/ + + +//ADMIN CREATE NINJA (From Player) +/client/proc/cmd_admin_ninjafy(var/mob/living/carbon/human/H in player_list) + set category = null + set name = "Make Space Ninja" + + if(!ticker) + alert("Wait until the game starts") + return + + if(!istype(H)) + return + + if(alert(src, "You sure?", "Confirm", "Yes", "No") != "Yes") + return + + log_admin("[key_name(src)] turned [H.key] into a Space Ninja.") + H.mind = create_ninja_mind(H.key) + H.mind_initialize() + H.equip_space_ninja(1) + if(istype(H.wear_suit, /obj/item/clothing/suit/space/space_ninja)) + H.wear_suit:randomize_param() + spawn(0) + H.wear_suit:ninitialize(10,H) + + +//ADMIN CREATE NINJA (From Ghost) +/client/proc/send_space_ninja() + set category = "Fun" + set name = "Spawn Space Ninja" + set desc = "Spawns a space ninja for when you need a teenager with attitude." + set popup_menu = 0 + + if(!holder) + src << "Only administrators may use this command." + return + if(!ticker.mode) + alert("The game hasn't started yet!") + return + if(alert("Are you sure you want to send in a space ninja?",,"Yes","No")=="No") + return + + var/client/C = input("Pick character to spawn as the Space Ninja", "Key", "") as null|anything in clients + if(!C) + return + + var/datum/round_event/ninja/E = new /datum/round_event/ninja() + E.key=C.key + + message_admins("[key_name_admin(key)] has spawned [key_name_admin(C.key)] as a Space Ninja.") + log_admin("[key] used Spawn Space Ninja.") + + return \ No newline at end of file diff --git a/code/modules/ninja/energy_katana.dm b/code/modules/ninja/energy_katana.dm new file mode 100644 index 00000000000..0a398a7ba27 --- /dev/null +++ b/code/modules/ninja/energy_katana.dm @@ -0,0 +1,20 @@ + + +/obj/item/weapon/katana/energy + name = "energy katana" + desc = "a katana infused with a strong energy" + icon_state = "energy_katana" + item_state = "energy_katana" + force = 40 + throwforce = 20 + +/obj/item/weapon/katana/energy/afterattack(atom/target, mob/user, proximity_flag, click_parameters) + if(!user || !target) + return + + if(proximity_flag) + target.emag_act() + user.visible_message("[user] masterfully slices [target]!", "You masterfully slice [target]!") + playsound(user, "sparks", 50, 1) + playsound(user, 'sound/weapons/blade1.ogg', 50, 1) + diff --git a/code/modules/ninja/ninja_event.dm b/code/modules/ninja/ninja_event.dm new file mode 100644 index 00000000000..47251f6f556 --- /dev/null +++ b/code/modules/ninja/ninja_event.dm @@ -0,0 +1,214 @@ +//Note to future generations: I didn't write this god-awful code I just ported it to the event system and tried to make it less moon-speaky. +//Don't judge me D; ~Carn //Maximum judging occuring - Remie. + + +/* + +Contents: +- The Ninja "Random" Event +- Ninja creation code + +*/ + +/datum/round_event_control/ninja + name = "Space Ninja" + typepath = /datum/round_event/ninja + max_occurrences = 1 + earliest_start = 30000 // 1 hour + + +/datum/round_event/ninja + var/success_spawn = 0 + + var/helping_station + var/key + var/spawn_loc + + var/mob/living/carbon/human/Ninja + + +/datum/round_event/ninja/setup() + helping_station = rand(0,1) + + +/datum/round_event/ninja/kill() + if(!success_spawn && control) + control.occurrences-- + return ..() + + +/datum/round_event/ninja/start() + //selecting a spawn_loc + if(!spawn_loc) + var/list/spawn_locs = list() + for(var/obj/effect/landmark/L in landmarks_list) + if(isturf(L.loc)) + switch(L.name) + if("ninjaspawn","carpspawn") + spawn_locs += L.loc + if(!spawn_locs.len) + return kill() + spawn_loc = pick(spawn_locs) + if(!spawn_loc) + return kill() + + //selecting a candidate player + if(!key) + var/list/candidates = get_candidates(BE_NINJA) + if(!candidates.len) + return kill() + var/client/C = pick(candidates) + key = C.key + if(!key) + return kill() + + //Prepare ninja player mind + var/datum/mind/Mind = create_ninja_mind(key) + Mind.active = 1 + + //generate objectives - You'll generally get 6 objectives (Ninja is meant to be hardmode!) + var/list/possible_targets = list() + for(var/datum/mind/M in ticker.minds) + if(M.current && M.current.stat != DEAD) + if(istype(M.current,/mob/living/carbon/human)) + if(M.special_role) + possible_targets[M] = 0 //bad-guy + else if(M.assigned_role in command_positions) + possible_targets[M] = 1 //good-guy + + var/list/objectives = list(1,2,3,4) + while(Mind.objectives.len < 6) //still not enough objectives! + switch(pick_n_take(objectives)) + if(1) //research + var/datum/objective/download/O = new /datum/objective/download() + O.owner = Mind + O.gen_amount_goal() + Mind.objectives += O + + if(2) //steal + var/datum/objective/steal/special/O = new /datum/objective/steal/special() + O.owner = Mind + Mind.objectives += O + + if(3) //protect/kill + if(!possible_targets.len) continue + var/selected = rand(1,possible_targets.len) + var/datum/mind/M = possible_targets[selected] + var/is_bad_guy = possible_targets[M] + possible_targets.Cut(selected,selected+1) + + if(is_bad_guy ^ helping_station) //kill (good-ninja + bad-guy or bad-ninja + good-guy) + var/datum/objective/assassinate/O = new /datum/objective/assassinate() + O.owner = Mind + O.target = M + O.explanation_text = "Slay \the [M.current.real_name], the [M.assigned_role]." + Mind.objectives += O + else //protect + var/datum/objective/protect/O = new /datum/objective/protect() + O.owner = Mind + O.target = M + O.explanation_text = "Protect \the [M.current.real_name], the [M.assigned_role], from harm." + Mind.objectives += O + if(4) //debrain/capture + if(!possible_targets.len) continue + var/selected = rand(1,possible_targets.len) + var/datum/mind/M = possible_targets[selected] + var/is_bad_guy = possible_targets[M] + possible_targets.Cut(selected,selected+1) + + if(is_bad_guy ^ helping_station) //debrain (good-ninja + bad-guy or bad-ninja + good-guy) + var/datum/objective/debrain/O = new /datum/objective/debrain() + O.owner = Mind + O.target = M + O.explanation_text = "Steal the brain of [M.current.real_name]." + Mind.objectives += O + else //capture + var/datum/objective/capture/O = new /datum/objective/capture() + O.owner = Mind + O.gen_amount_goal() + Mind.objectives += O + else + break + + //Add a survival objective since it's usually broad enough for any round type. + var/datum/objective/O = new /datum/objective/survive() + O.owner = Mind + Mind.objectives += O + + //add some RP-fluff + Mind.store_memory("I am an elite mercenary assassin of the mighty Spider Clan. A SPACE NINJA!") + Mind.store_memory("Suprise is my weapon. Shadows are my armor. Without them, I am nothing. (//initialize your suit by right clicking on it, to use abilities like stealth)!") + Mind.store_memory("Officially, [helping_station?"Nanotrasen":"The Syndicate"] are my employer.") + + //spawn the ninja and assign the candidate + Ninja = create_space_ninja(spawn_loc) + Mind.transfer_to(Ninja) + + //initialise equipment + if(istype(Ninja.wear_suit,/obj/item/clothing/suit/space/space_ninja)) + //Should be true but we have to check these things. + var/obj/item/clothing/suit/space/space_ninja/N = Ninja.wear_suit + N.randomize_param() + + Ninja.internal = Ninja.s_store + if(Ninja.internals) + Ninja.internals.icon_state = "internal1" + + if(Ninja.mind != Mind) //something has gone wrong! + ERROR("The ninja wasn't assigned the right mind. ;ç;") + + Ninja << sound('sound/effects/ninja_greeting.ogg') //so ninja you probably wouldn't even know if you were made one + + success_spawn = 1 + + +//=======//NINJA CREATION PROCS//=======// + +/proc/create_space_ninja(spawn_loc) + var/mob/living/carbon/human/new_ninja = new(spawn_loc) + if(prob(50)) new_ninja.gender = "female" + var/datum/preferences/A = new()//Randomize appearance for the ninja. + A.real_name = "[pick(ninja_titles)] [pick(ninja_names)]" + A.copy_to(new_ninja) + ready_dna(new_ninja) + new_ninja.equip_space_ninja() + return new_ninja + + +proc/create_ninja_mind(key) + var/datum/mind/Mind = new /datum/mind(key) + Mind.assigned_role = "MODE" + Mind.special_role = "Space Ninja" + ticker.mode.traitors |= Mind //Adds them to current traitor list. Which is really the extra antagonist list. + return Mind + + +/mob/living/carbon/human/proc/equip_space_ninja(safety=0)//Safety in case you need to unequip stuff for existing characters. + if(safety) + qdel(w_uniform) + qdel(wear_suit) + qdel(wear_mask) + qdel(head) + qdel(shoes) + qdel(gloves) + + var/obj/item/device/radio/R = new /obj/item/device/radio/headset(src) + equip_to_slot_or_del(R, slot_ears) + equip_to_slot_or_del(new /obj/item/clothing/under/color/black(src), slot_w_uniform) + equip_to_slot_or_del(new /obj/item/clothing/shoes/space_ninja(src), slot_shoes) + equip_to_slot_or_del(new /obj/item/clothing/suit/space/space_ninja(src), slot_wear_suit) + equip_to_slot_or_del(new /obj/item/clothing/gloves/space_ninja(src), slot_gloves) + equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/space_ninja(src), slot_head) + equip_to_slot_or_del(new /obj/item/clothing/mask/gas/voice/space_ninja(src), slot_wear_mask) + equip_to_slot_or_del(new /obj/item/clothing/glasses/night(src), slot_glasses) + equip_to_slot_or_del(new /obj/item/weapon/katana/energy(src), slot_belt) + equip_to_slot_or_del(new /obj/item/device/flashlight(src), slot_r_store) + equip_to_slot_or_del(new /obj/item/weapon/c4(src), slot_l_store) + equip_to_slot_or_del(new /obj/item/weapon/tank/internals/emergency_oxygen(src), slot_s_store) + equip_to_slot_or_del(new /obj/item/weapon/tank/jetpack/carbondioxide(src), slot_back) + + var/obj/item/weapon/implant/explosive/E = new/obj/item/weapon/implant/explosive(src) + E.imp_in = src + E.implanted = 1 + E.implanted(src) + return 1 diff --git a/code/modules/ninja/suit/SpiderOS.dm b/code/modules/ninja/suit/SpiderOS.dm new file mode 100644 index 00000000000..f73a6cbc3d0 --- /dev/null +++ b/code/modules/ninja/suit/SpiderOS.dm @@ -0,0 +1,277 @@ + + +//HERE BE A VERY LARGE DRAGON + +/obj/item/clothing/suit/space/space_ninja/proc/spideros() + set name = "Display SpiderOS" + set desc = "Utilize built-in computer system." + set category = "Ninja Equip" + + if(!s_busy) + display_spideros() + else + affecting << "The interface is locked!" + + +/obj/item/clothing/suit/space/space_ninja/proc/display_spideros() + if(!affecting) return//If no mob is wearing the suit. I almost forgot about this variable. + var/mob/living/carbon/human/U = affecting + var/display_to = U//Who do we want to display certain messages to? + + var/dat = "SpiderOS" + dat += " Refresh" + if(spideros) + dat += " | Return" + dat += " | Close" + dat += "
    " + dat += "

    SpiderOS v.1.337

    " + dat += "Welcome, [U.real_name].
    " + dat += "
    " + dat += " Current Time: [worldtime2text()]
    " + dat += " Battery Life: [round(cell.charge/100)]%
    " + dat += " Smoke Bombs: \Roman [s_bombs]
    " + dat += "

    " + + switch(spideros) + if(0) + dat += "

    Available Functions:

    " + dat += "" + if(3) + dat += "

    Medical Report:

    " + if(U.dna) + dat += "Fingerprints: [md5(U.dna.uni_identity)]
    " + dat += "Unique identity: [U.dna.unique_enzymes]
    " + dat += "

    Overall Status: [U.stat > 1 ? "dead" : "[U.health]% healthy"]

    " + dat += "

    Nutrition Status: [U.nutrition]

    " + dat += "Oxygen loss: [U.getOxyLoss()]" + dat += " | Toxin levels: [U.getToxLoss()]
    " + dat += "Burn severity: [U.getFireLoss()]" + dat += " | Brute trauma: [U.getBruteLoss()]
    " + dat += "Radiation Level: [U.radiation] rad
    " + dat += "Body Temperature: [U.bodytemperature-T0C]°C ([U.bodytemperature*1.8-459.67]°F)
    " + + for(var/datum/disease/D in U.viruses) + dat += "Warning: Virus Detected. Name: [D.name].Type: [D.spread_text]. Stage: [D.stage]/[D.max_stages]. Possible Cure: [D.cure_text].
    " + dat += "" + if(1) + dat += "

    Atmospheric Scan:

    "//Headers don't need breaks. They are automatically placed. + var/turf/T = get_turf(U.loc) + if (isnull(T)) + dat += "Unable to obtain a reading." + else + var/datum/gas_mixture/environment = T.return_air() + + var/pressure = environment.return_pressure() + var/total_moles = environment.total_moles() + + dat += "Air Pressure: [round(pressure,0.1)] kPa" + + if (total_moles) + var/o2_level = environment.oxygen/total_moles + var/n2_level = environment.nitrogen/total_moles + var/co2_level = environment.carbon_dioxide/total_moles + var/plasma_level = environment.toxins/total_moles + var/unknown_level = 1-(o2_level+n2_level+co2_level+plasma_level) + dat += "
      " + dat += "
    • Nitrogen: [round(n2_level*100)]%
    • " + dat += "
    • Oxygen: [round(o2_level*100)]%
    • " + dat += "
    • Carbon Dioxide: [round(co2_level*100)]%
    • " + dat += "
    • Plasma: [round(plasma_level*100)]%
    • " + dat += "
    " + if(unknown_level > 0.01) + dat += "OTHER: [round(unknown_level)]%
    " + + dat += "Temperature: [round(environment.temperature-T0C)]°C" + if(2) + dat += "

    Anonymous Messenger:

    "//Anonymous because the receiver will not know the sender's identity. + dat += "

    Detected PDAs:

    " + dat += "
      " + var/count = 0 + for (var/obj/item/device/pda/P in get_viewable_pdas()) + dat += "
    • [P]" + dat += "
    • " + count++ + dat += "
    " + if (count == 0) + dat += "None detected.
    " + if(4) + dat += {" +

    Ninja Manual:

    +
    Who they are:
    + Space ninjas are a special type of ninja, specifically one of the space-faring type. The vast majority of space ninjas belong to the Spider Clan, a cult-like sect, which has existed for several hundred years. The Spider Clan practice a sort of augmentation of human flesh in order to achieve a more perfect state of being and follow Postmodern Space Bushido. They also kill people for money. Their leaders are chosen from the oldest of the grand-masters, people that have lived a lot longer than any mortal man should.
    Being a sect of technology-loving fanatics, the Spider Clan have the very best to choose from in terms of hardware--cybernetic implants, exoskeleton rigs, hyper-capacity batteries, and you get the idea. Some believe that much of the Spider Clan equipment is based on reverse-engineered alien technology while others doubt such claims.
    Whatever the case, their technology is absolutely superb. +
    How they relate to other SS13 organizations:
    +
      +
    • *Nanotrasen and the Syndicate are two sides of the same coin and that coin is valuable.
    • +
    • *The Space Wizard Federation is a problem, mainly because they are an extremely dangerous group of unpredictable individuals--not to mention the wizards hate technology and are in direct opposition of the Spider Clan. Best avoided or left well-enough alone. How to battle: wizards possess several powerful abilities to steer clear off. Blind in particular is a nasty spell--jaunt away if you are blinded and never approach a wizard in melee. Stealth may also work if the wizard is not wearing thermal scanners--don't count on this. Run away if you feel threatened and await a better opportunity.
    • +
    • *Changeling Hivemind: extremely dangerous and to be killed on sight. How to battle: they will likely try to absorb you. Adrenaline boost, then phase shift into them. If you get stung, use SpiderOS to inject counter-agents. Stealth may also work but detecting a changeling is the real battle.
    • +
    • *Xeno Hivemind: their skulls make interesting kitchen decorations and are challenging to best, especially in larger nests. How to battle: they can see through your stealth guise and energy stars will not work on them. Best killed with a Phase Shift or at range. If you happen on a projectile stun weapon, use it and then close in to melee.
    • +
    +
    The reason they (you) are here:
    + Space ninjas are renowned throughout the known controlled space as fearless spies, infiltrators, and assassins. They are sent on missions of varying nature by Nanotrasen, the Syndicate, and other shady organizations and people. To hire a space ninja means serious business. +
    Their playstyle:
    + A mix of traitor, changeling, and wizard. Ninjas rely on energy, or electricity to be precise, to keep their suits running (when out of energy, a suit hibernates). Suits gain energy from objects or creatures that contain electrical charge. APCs, cell batteries, rechargers, SMES batteries, cyborgs, mechs, and exposed wires are currently supported. Through energy ninjas gain access to special powers--while all powers are tied to the ninja suit, the most useful of them are verb activated--to help them in their mission.
    It is a constant struggle for a ninja to remain hidden long enough to recharge the suit and accomplish their objective; despite their arsenal of abilities, ninjas can die like any other. Unlike wizards, ninjas do not possess good crowd control and are typically forced to play more subdued in order to achieve their goals. Some of their abilities are specifically designed to confuse and disorient others.
    With that said, it should be perfectly possible to completely flip the fuck out and rampage as a ninja. +
    Their powers:
    + There are two primary types: Equipment and Abilties. Passive effect are always on. Active effect must be turned on and remain active only when there is energy to do so. Ability costs are listed next to them. + Equipment: cannot be tracked by AI (passive), faster speed (passive), stealth (active), vision switch (passive if toggled), voice masking (passive), SpiderOS (passive if toggled), energy drain (passive if toggled). +
      +
    • Voice masking generates a random name the ninja can use over the radio and in-person. Although, the former use is recommended.
    • +
    • Toggling vision cycles to one of the following: thermal, meson, or darkness vision. The starting mode allows one to scout the identity of those in view, revealing their role. Traitors, revolutionaries, wizards, and other such people will be made known to you.
    • +
    • Stealth, when activated, drains more battery charge and works similarly to a syndicate cloak. The cloak will deactivate when most Abilities are utilized.
    • +
    • On-board AI: The suit is able to download an AI much like an intellicard. Check with SpiderOS for details once downloaded.
    • +
    • SpiderOS is a specialized, PDA-like screen that allows for a small variety of functions, such as injecting healing chemicals directly from the suit. You are using it now, if that was not already obvious. You may also download AI modules directly to the OS.
    • +
    + Abilities: +
      +
    • *Phase Shift (2000E) and Phase Jaunt (1000E) are unique powers in that they can both be used for defense and offense. Jaunt launches the ninja forward facing up to 9 squares, somewhat randomly selecting the final destination. Shift can only be used on turf in view but is precise (cannot be used on walls). Any living mob in the area teleported to is instantly gibbed (mechs are damaged, huggers and other similar critters are killed). It is possible to teleport with a target, provided you grab them before teleporting.
    • +
    • *Energy Blade (500E) is a highly effective weapon. It is summoned directly to the ninja's hand and can also function as an EMAG for certain objects (doors/lockers/etc). You may also use it to cut through walls and disabled doors. Experiment! The blade will crit humans in two hits. This item cannot be placed in containers and when dropped or thrown disappears. Having an energy blade drains more power from the battery each tick.
    • +
    • *EM Pulse (2500E) is a highly useful ability that will create an electromagnetic shockwave around the ninja, disabling technology whenever possible. If used properly it can render a security force effectively useless. Of course, getting beat up with a toolbox is not accounted for.
    • +
    • *Energy Star (500E) is a ninja star made of green energy AND coated in poison. It works by picking a random living target within range and can be spammed to great effect in incapacitating foes. Just remember that the poison used is also used by the Xeno Hivemind (and will have no effect on them).
    • +
    • *Energy Net (2000E) is a non-lethal solution to incapacitating humanoids. The net is made of non-harmful phase energy and will halt movement as long as it remains in effect--it can be destroyed. If the net is not destroyed, after a certain time it will teleport the target to a holding facility for the Spider Clan and then vanish. You will be notified if the net fails or succeeds in capturing a target in this manner. Combine with energy stars or stripping to ensure success. Abduction never looked this leet.
    • +
    • *Adrenaline Boost (1 E. Boost/3) recovers the user from stun, weakness, and paralysis. Also injects 20 units of radium into the bloodstream.
    • +
    • *Smoke Bomb (1 Sm.Bomb/10) is a weak but potentially useful ability. It creates harmful smoke and can be used in tandem with other powers to confuse enemies.
    • +
    • *???: unleash the True Ultimate Power!
    • +

      IMPORTANT:

      +
        +
      • *Make sure to toggle Special Interaction from the Ninja Equipment menu to interact differently with certain objects.
      • +
      • *Your starting power cell can be replaced if you find one with higher maximum energy capacity by clicking on your suit with the higher capacity cell.
      • +
      • *Conserve your energy. Without it, you are very vulnerable.
      • +
      + That is all you will need to know. The rest will come with practice and talent. Good luck! +

      Master /N

      + "} + if(6) + dat += {" +

      Activate Abilities:

      + + "} + if(7) + dat += "

      Research Stored:

      " + if(t_disk) + dat += "Eject Disk
      " + dat += "
        " + if(istype(stored_research,/list))//If there is stored research. Should be but just in case. + for(var/datum/tech/current_data in stored_research) + dat += "
      • " + dat += "[current_data.name]: [current_data.level]" + if(t_disk)//If there is a disk inserted. We can either write or overwrite. + dat += " *Copy to Disk
        " + dat += "
      • " + dat += "
      " + dat += "" + + //Setting the can>resize etc to 0 remove them from the drag bar but still allows the window to be draggable. + display_to << browse(dat,"window=spideros;size=400x444;border=1;can_resize=1;can_close=0;can_minimize=0") + +//=======//SPIDEROS TOPIC PROC//=======// + +/obj/item/clothing/suit/space/space_ninja/Topic(href, href_list) + ..() + var/mob/living/carbon/human/U = affecting + var/display_to = U + + + if(!affecting||U.stat||!s_initialized)//Check to make sure the guy is wearing the suit after clicking and it's on. + U << "Your suit must be worn and active to use this function." + U << browse(null, "window=spideros")//Closes the window. + return + + switch(href_list["choice"]) + if("Close") + display_to << browse(null, "window=spideros") + return + if("Refresh")//Refresh, goes to the end of the proc. + if("Return")//Return + if(spideros<=9) + spideros=0 + else + spideros = round(spideros/10)//Best way to do this, flooring to nearest integer. + + if("Message") + var/obj/item/device/pda/P = locate(href_list["target"]) + var/t = input(U, "Please enter untraceable message.") as text + t = copytext(sanitize(t), 1, MAX_MESSAGE_LEN) + if(!t||U.stat||U.wear_suit!=src||!s_initialized)//Wow, another one of these. Man... + display_to << browse(null, "window=spideros") + return + if(isnull(P)||P.toff)//So it doesn't freak out if the object no-longer exists. + display_to << "Error: unable to deliver message." + display_spideros() + return + P.tnote += "← From an unknown source:
      [t]
      " + if (!P.silent) + playsound(P.loc, 'sound/machines/twobeep.ogg', 50, 1) + P.audible_message("\icon[P] *[P.ttone]*", null, 3) + P.overlays.Cut() + P.overlays += image('icons/obj/pda.dmi', "pda-r") + + if("Inject") + if( (href_list["tag"]=="radium"? (reagents.get_reagent_amount("radium"))<=(a_boost*a_transfer) : !reagents.get_reagent_amount(href_list["tag"])) )//Special case for radium. If there are only a_boost*a_transfer radium units left. + display_to << "Error: the suit cannot perform this function. Out of [href_list["name"]]." + else + reagents.reaction(U, 2) + reagents.trans_id_to(U, href_list["tag"], href_list["tag"]=="nutriment"?5:a_transfer)//Nutriment is a special case since it's very potent. Shouldn't influence actual refill amounts or anything. + display_to << "Injecting..." + U << "You feel a tiny prick and a sudden rush of substance in to your veins." + + if("Trigger Ability") + var/ability_name = href_list["name"]+href_list["cost"]//Adds the name and cost to create the full proc name. + var/proc_arguments//What arguments to later pass to the proc, if any. + var/list/targets = list()//To later check for. + var/safety = 0//To later make sure we're triggering the proc when needed. + switch(href_list["name"])//Special case. + if("Phase Shift") + safety = 1 + for(var/turf/T in oview(5,loc)) + targets.Add(T) + if("Energy Net") + safety = 1 + for(var/mob/living/carbon/M in oview(5,loc)) + targets.Add(M) + if(targets.len)//Let's create an argument for the proc if needed. + proc_arguments = pick(targets) + safety = 0 + if(!safety) + U << "[href_list["name"]] suddenly triggered!" + call(src,ability_name)(proc_arguments) + + if("Eject Disk") + var/turf/T = get_turf(loc) + if(!U.get_active_hand()) + U.put_in_hands(t_disk) + t_disk.add_fingerprint(U) + t_disk = null + else + if(T) + t_disk.loc = T + t_disk = null + else + U << "ERROR: Could not eject disk." + + if("Copy to Disk") + var/datum/tech/current_data = locate(href_list["target"]) + U << "[current_data.name] successfully [(!t_disk.stored) ? "copied" : "overwritten"] to disk." + t_disk.stored = current_data + + + display_spideros()//Refreshes the screen by calling it again (which replaces current screen with new screen). + return diff --git a/code/modules/ninja/suit/gloves.dm b/code/modules/ninja/suit/gloves.dm new file mode 100644 index 00000000000..3f23ac333e2 --- /dev/null +++ b/code/modules/ninja/suit/gloves.dm @@ -0,0 +1,343 @@ + + + +/* + Dear ninja gloves + + This isn't because I like you + this is because your father is a bastard + + ... + I guess you're a little cool. + -Sayu +*/ + +/obj/item/clothing/gloves/space_ninja + desc = "These nano-enhanced gloves insulate from electricity and provide fire resistance." + name = "ninja gloves" + icon_state = "s-ninja" + item_state = "s-ninja" + siemens_coefficient = 0 + cold_protection = HANDS + min_cold_protection_temperature = GLOVES_MIN_TEMP_PROTECT + heat_protection = HANDS + max_heat_protection_temperature = GLOVES_MAX_TEMP_PROTECT + strip_delay = 120 + var/draining = 0 + var/candrain = 0 + var/mindrain = 200 + var/maxdrain = 400 + +/* + This runs the gamut of what ninja gloves can do + The other option would be a dedicated ninja touch bullshit proc on everything + which would probably more efficient, but ninjas are pretty rare. + This was mostly introduced to keep ninja code from contaminating other code; + with this in place it would be easier to untangle the rest of it. + + For the drain proc, see events/ninja.dm +*/ +/obj/item/clothing/gloves/space_ninja/Touch(var/atom/A,var/proximity) + if(!candrain || draining) + return 0 + var/mob/living/carbon/human/H = loc + if(!istype(H)) + return 0 // what + var/obj/item/clothing/suit/space/space_ninja/suit = H.wear_suit + if(!istype(suit)) + return 0 + if(isturf(A)) + return 0 + + if(!proximity) // todo: you could add ninja stars or computer hacking here + return 0 + + A.add_fingerprint(H) + + // steal energy from powered things + if(istype(A,/mob/living/silicon/robot)) + drain("CYBORG",A,suit) + return 1 + + if(istype(A, /obj/item/weapon/stock_parts/cell)) + drain("CELL", A,suit) + return 1 + + if(istype(A,/obj/machinery/power/apc)) + drain("APC",A,suit) + return 1 + + if(istype(A,/obj/structure/cable)) + drain("WIRE",A,suit) + return 1 + + if(istype(A,/obj/structure/grille)) + var/obj/structure/cable/C = locate() in A.loc + if(C) + drain("WIRE",C,suit) + return 1 + + if(istype(A,/obj/machinery/power/smes)) + drain("SMES",A,suit) + return 1 + + if(istype(A,/obj/mecha)) + drain("MECHA",A,suit) + return 1 + + if(istype(A,/obj/machinery/computer/rdconsole)) // download research + drain("RESEARCH",A,suit) + return 1 + + if(istype(A,/obj/machinery/r_n_d/server)) + A.add_fingerprint(H) + var/obj/machinery/r_n_d/server/S = A + if(S.disabled) + return 1 + if(S.shocked) + S.shock(H,50) + return 1 + drain("RESEARCH",A,suit) + return 1 + + +/obj/item/clothing/gloves/space_ninja/proc/drain(target_type as text, target, obj/suit) + //Var Initialize + var/obj/item/clothing/suit/space/space_ninja/S = suit + var/mob/living/carbon/human/U = S.affecting + var/obj/item/clothing/gloves/space_ninja/G = S.n_gloves + + var/drain = 0//To drain from battery. + var/maxcapacity = 0//Safety check for full battery. + var/totaldrain = 0//Total energy drained. + + G.draining = 1 + + if(target_type!="RESEARCH")//I lumped research downloading here for ease of use. + U << "Now charging battery..." + + switch(target_type) + + if("APC") + var/obj/machinery/power/apc/A = target + if(A.cell&&A.cell.charge) + var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread() + spark_system.set_up(5, 0, A.loc) + while(G.candrain&&A.cell.charge>0&&!maxcapacity) + drain = rand(G.mindrain,G.maxdrain) + if(A.cell.chargeS.cell.maxcharge) + drain = S.cell.maxcharge-S.cell.charge + maxcapacity = 1//Reached maximum battery capacity. + if (do_after(U,10)) + spark_system.start() + playsound(A.loc, "sparks", 50, 1) + A.cell.charge-=drain + S.cell.charge+=drain + totaldrain+=drain + else break + U << "Gained [totaldrain] energy from the APC." + if(!A.emagged) + flick("apc-spark", src) + A.emagged = 1 + A.locked = 0 + A.update_icon() + else + U << "This APC has run dry of power. You must find another source." + + if("SMES") + var/obj/machinery/power/smes/A = target + if(A.charge) + var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread() + spark_system.set_up(5, 0, A.loc) + while(G.candrain&&A.charge>0&&!maxcapacity) + drain = rand(G.mindrain,G.maxdrain) + if(A.chargeS.cell.maxcharge) + drain = S.cell.maxcharge-S.cell.charge + maxcapacity = 1 + if (do_after(U,10)) + spark_system.start() + playsound(A.loc, "sparks", 50, 1) + A.charge-=drain + S.cell.charge+=drain + totaldrain+=drain + else break + U << "Gained [totaldrain] energy from the SMES cell." + else + U << "This SMES cell has run dry of power. You must find another source." + + if("CELL") + var/obj/item/weapon/stock_parts/cell/A = target + if(A.charge) + if (G.candrain&&do_after(U,30)) + U << "Gained [A.charge] energy from the cell." + if(S.cell.charge+A.charge>S.cell.maxcharge) + S.cell.charge=S.cell.maxcharge + else + S.cell.charge+=A.charge + A.charge = 0 + G.draining = 0 + A.corrupt() + A.updateicon() + else + U << "Procedure interrupted. Protocol terminated." + else + U << "This cell is empty and of no use." + + if("MACHINERY")//Can be applied to generically to all powered machinery. I'm leaving this alone for now. + var/obj/machinery/A = target + if(A.powered())//If powered. + + var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread() + spark_system.set_up(5, 0, A.loc) + + var/area/A_Area = get_area(A) + var/obj/machinery/power/apc/B = A_Area.get_apc() //find APC + if(B)//If APC exists. Might not if the area is unpowered like Centcom. + var/datum/powernet/PN = B.terminal.powernet + while(G.candrain&&!maxcapacity&&!isnull(A))//And start a proc similar to drain from wire. + drain = rand(G.mindrain,G.maxdrain) + var/drained = 0 + if(PN&&do_after(U,10)) + drained = min(drain, PN.avail) + PN.load += drained + if(drained < drain)//if no power on net, drain apcs + for(var/obj/machinery/power/terminal/T in PN.nodes) + if(istype(T.master, /obj/machinery/power/apc)) + var/obj/machinery/power/apc/AP = T.master + if(AP.operating && AP.cell && AP.cell.charge>0) + AP.cell.charge = max(0, AP.cell.charge - 5) + drained += 5 + else break + S.cell.charge += drained + if(S.cell.charge>S.cell.maxcharge) + totaldrain += (drained-(S.cell.charge-S.cell.maxcharge)) + S.cell.charge = S.cell.maxcharge + maxcapacity = 1 + else + totaldrain += drained + spark_system.start() + if(drained==0) break + U << "Gained [totaldrain] energy from the power network." + else + U << "Power network could not be found. Aborting." + else + U << "This recharger is not providing energy. You must find another source." + + if("RESEARCH") + var/obj/machinery/A = target + U << "Hacking \the [A]..." + spawn(0) + var/turf/location = get_turf(U) + for(var/mob/living/silicon/ai/AI in player_list) + AI << "Network Alert: Hacking attempt detected[location?" in [location]":". Unable to pinpoint location"]." + if(A:files&&A:files.known_tech.len) + for(var/datum/tech/current_data in S.stored_research) + U << "Checking \the [current_data.name] database." + if(do_after(U, S.s_delay)&&G.candrain&&!isnull(A)) + for(var/datum/tech/analyzing_data in A:files.known_tech) + if(current_data.id==analyzing_data.id) + if(analyzing_data.level>current_data.level) + U << "Database: UPDATED." + current_data.level = analyzing_data.level + break//Move on to next. + else break//Otherwise, quit processing. + U << "Data analyzed. Process finished." + + if("WIRE") + var/obj/structure/cable/A = target + var/datum/powernet/PN = A.powernet + while(G.candrain&&!maxcapacity&&!isnull(A)) + drain = (round((rand(G.mindrain,G.maxdrain))/2)) + var/drained = 0 + if(PN&&do_after(U,10)) + drained = min(drain, PN.avail) + PN.load += drained + if(drained < drain)//if no power on net, drain apcs + for(var/obj/machinery/power/terminal/T in PN.nodes) + if(istype(T.master, /obj/machinery/power/apc)) + var/obj/machinery/power/apc/AP = T.master + if(AP.operating && AP.cell && AP.cell.charge>0) + AP.cell.charge = max(0, AP.cell.charge - 5) + drained += 5 + else break + S.cell.charge += drained + if(S.cell.charge>S.cell.maxcharge) + totaldrain += (drained-(S.cell.charge-S.cell.maxcharge)) + S.cell.charge = S.cell.maxcharge + maxcapacity = 1 + else + totaldrain += drained + S.spark_system.start() + if(drained==0) break + U << "Gained [totaldrain] energy from the power network." + + if("MECHA") + var/obj/mecha/A = target + A.occupant_message("Warning: Unauthorized access through sub-route 4, block H, detected.") + if(A.get_charge()) + while(G.candrain&&A.cell.charge>0&&!maxcapacity) + drain = rand(G.mindrain,G.maxdrain) + if(A.cell.chargeS.cell.maxcharge) + drain = S.cell.maxcharge-S.cell.charge + maxcapacity = 1 + if (do_after(U,10)) + A.spark_system.start() + playsound(A.loc, "sparks", 50, 1) + A.cell.use(drain) + S.cell.charge+=drain + totaldrain+=drain + else break + U << "Gained [totaldrain] energy from [src]." + else + U << "The exosuit's battery has run dry. You must find another source of power." + + if("CYBORG") + var/mob/living/silicon/robot/A = target + A << "Warning: Unauthorized access through sub-route 12, block C, detected." + G.draining = 1 + if(A.cell&&A.cell.charge) + while(G.candrain&&A.cell.charge>0&&!maxcapacity) + drain = rand(G.mindrain,G.maxdrain) + if(A.cell.chargeS.cell.maxcharge) + drain = S.cell.maxcharge-S.cell.charge + maxcapacity = 1 + if (do_after(U,10)) + A.spark_system.start() + playsound(A.loc, "sparks", 50, 1) + A.cell.charge-=drain + S.cell.charge+=drain + totaldrain+=drain + else break + U << "Gained [totaldrain] energy from [A]." + else + U << "Their battery has run dry of power. You must find another source." + + else//Else nothing :< + + G.draining = 0 + + return + + +/obj/item/clothing/gloves/space_ninja/proc/toggled() + set name = "Toggle Interaction" + set desc = "Toggles special interaction on or off." + set category = "Ninja Equip" + + var/mob/living/carbon/human/U = loc + U << "You [candrain?"disable":"enable"] special interaction." + candrain=!candrain + + +/obj/item/clothing/gloves/space_ninja/examine(mob/user) + ..() + if(flags & NODROP) + user << "The energy drain mechanism is: [candrain?"active":"inactive"]." diff --git a/code/modules/ninja/suit/head.dm b/code/modules/ninja/suit/head.dm new file mode 100644 index 00000000000..5707a1bd809 --- /dev/null +++ b/code/modules/ninja/suit/head.dm @@ -0,0 +1,11 @@ + + +/obj/item/clothing/head/helmet/space/space_ninja + desc = "What may appear to be a simple black garment is in fact a highly sophisticated nano-weave helmet. Standard issue ninja gear." + name = "ninja hood" + icon_state = "s-ninja" + item_state = "s-ninja_mask" + armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 30, rad = 25) + strip_delay = 12 + unacidable = 1 + blockTracking = 1//Roughly the only unique thing about this helmet. \ No newline at end of file diff --git a/code/modules/ninja/suit/mask.dm b/code/modules/ninja/suit/mask.dm new file mode 100644 index 00000000000..cd8a2ba822d --- /dev/null +++ b/code/modules/ninja/suit/mask.dm @@ -0,0 +1,137 @@ + +/* + +Contents: +- The Ninja Space Mask +- Ninja Space Mask speech modification + +*/ + + + + +/obj/item/clothing/mask/gas/voice/space_ninja + name = "ninja mask" + desc = "A close-fitting mask that acts both as an air filter and a post-modern fashion statement." + icon_state = "s-ninja" + item_state = "s-ninja_mask" + vchange = 1 + strip_delay = 120 + +/obj/item/clothing/mask/gas/voice/space_ninja/speechModification(message) + if(voice == "Unknown") + if(copytext(message, 1, 2) != "*") + var/list/temp_message = text2list(message, " ") + var/list/pick_list = list() + for(var/i = 1, i <= temp_message.len, i++) + pick_list += i + for(var/i=1, i <= abs(temp_message.len/3), i++) + var/H = pick(pick_list) + if(findtext(temp_message[H], "*") || findtext(temp_message[H], ";") || findtext(temp_message[H], ":")) continue + temp_message[H] = ninjaspeak(temp_message[H]) + pick_list -= H + message = list2text(temp_message, " ") + + //The Alternate speech mod is now the main one. + message = replacetext(message, "l", "r") + message = replacetext(message, "rr", "ru") + message = replacetext(message, "v", "b") + message = replacetext(message, "f", "hu") + message = replacetext(message, "'t", "") + message = replacetext(message, "t ", "to ") + message = replacetext(message, " I ", " ai ") + message = replacetext(message, "th", "z") + message = replacetext(message, "is", "izu") + message = replacetext(message, "ziz", "zis") + message = replacetext(message, "se", "su") + message = replacetext(message, "br", "bur") + message = replacetext(message, "ry", "ri") + message = replacetext(message, "you", "yuu") + message = replacetext(message, "ck", "cku") + message = replacetext(message, "eu", "uu") + message = replacetext(message, "ow", "au") + message = replacetext(message, "are", "aa") + message = replacetext(message, "ay", "ayu") + message = replacetext(message, "ea", "ii") + message = replacetext(message, "ch", "chi") + message = replacetext(message, "than", "sen") + message = replacetext(message, ".", "") + message = lowertext(message) + + return message + + + +/obj/item/clothing/mask/gas/voice/space_ninja/New() + verbs += /obj/item/clothing/mask/gas/voice/space_ninja/proc/togglev + + +//This proc is linked to human life.dm. It determines what hud icons to display based on mind special role for most mobs. +/obj/item/clothing/mask/gas/voice/space_ninja/proc/assess_targets(list/target_list, mob/living/carbon/U) + var/icon/tempHud = 'icons/mob/hud.dmi' + for(var/mob/living/target in target_list) + if(iscarbon(target)) + switch(target.mind.special_role) + if("traitor") + U.client.images += image(tempHud,target,"hudtraitor") + if("Revolutionary","Head Revolutionary") + U.client.images += image(tempHud,target,"hudrevolutionary") + if("Cultist") + U.client.images += image(tempHud,target,"hudcultist") + if("Changeling") + U.client.images += image(tempHud,target,"hudchangeling") + if("Wizard","Fake Wizard") + U.client.images += image(tempHud,target,"hudwizard") + if("Hunter","Sentinel","Drone","Queen") + U.client.images += image(tempHud,target,"hudalien") + if("Syndicate") + U.client.images += image(tempHud,target,"hudoperative") + if("Death Commando") + U.client.images += image(tempHud,target,"huddeathsquad") + if("Space Ninja") + U.client.images += image(tempHud,target,"hudninja") + else//If we don't know what role they have but they have one. + U.client.images += image(tempHud,target,"hudunknown1") + else if(issilicon(target))//If the silicon mob has no law datum, no inherent laws, or a law zero, add them to the hud. + var/mob/living/silicon/silicon_target = target + if(!silicon_target.laws||(silicon_target.laws&&(silicon_target.laws.zeroth||!silicon_target.laws.inherent.len))) + if(isrobot(silicon_target))//Different icons for robutts and AI. + U.client.images += image(tempHud,silicon_target,"hudmalborg") + else + U.client.images += image(tempHud,silicon_target,"hudmalai") + return 1 + + +/obj/item/clothing/mask/gas/voice/space_ninja/proc/togglev() + set name = "Toggle Voice" + set desc = "Toggles the voice synthesizer on or off." + set category = "Ninja Equip" + + var/mob/U = loc//Can't toggle voice when you're not wearing the mask. + var/vchange = (alert("Would you like to synthesize a new name or turn off the voice synthesizer?",,"New Name","Turn Off")) + if(vchange == "New Name") + var/chance = rand(1,100) + switch(chance) + if(1 to 50)//High chance of a regular name. + voice = "[rand(0,1) == 1 ? pick(first_names_female) : pick(first_names_male)] [pick(last_names)]" + if(51 to 80)//Smaller chance of a clown name. + voice = "[pick(clown_names)]" + if(81 to 90)//Small chance of a wizard name. + voice = "[pick(wizard_first)] [pick(wizard_second)]" + if(91 to 100)//Small chance of an existing crew name. + var/list/names = list() + for(var/mob/living/carbon/human/M in player_list) + if(M == U || !M.client || !M.real_name) + continue + names.Add(M.real_name) + voice = !names.len ? "Cuban Pete" : pick(names) + U << "You are now mimicking [voice]." + else + U << "The voice synthesizer is [voice!="Unknown"?"now":"already"] deactivated." + voice = "Unknown" + return + + +/obj/item/clothing/mask/gas/voice/space_ninja/examine(mob/user) + ..() + user << "Voice mimicking algorithm is set [!vchange?"inactive":"active"]." diff --git a/code/modules/ninja/suit/n_suit_verbs/energy_net_nets.dm b/code/modules/ninja/suit/n_suit_verbs/energy_net_nets.dm new file mode 100644 index 00000000000..86d1cc128f8 --- /dev/null +++ b/code/modules/ninja/suit/n_suit_verbs/energy_net_nets.dm @@ -0,0 +1,174 @@ +/* +It will teleport people to a holding facility after 30 seconds. (Check the process() proc to change where teleport goes) +It is possible to destroy the net by the occupant or someone else. +*/ + +/obj/effect/energy_net + name = "energy net" + desc = "It's a net made of green energy." + icon = 'icons/effects/effects.dmi' + icon_state = "energynet" + + density = 1//Can't pass through. + opacity = 0//Can see through. + mouse_opacity = 1//So you can hit it with stuff. + anchored = 1//Can't drag/grab the trapped mob. + + var/health = 25//How much health it has. + var/mob/living/affecting = null//Who it is currently affecting, if anyone. + var/mob/living/master = null//Who shot web. Will let this person know if the net was successful or failed. + + + +/obj/effect/energy_net/proc/healthcheck() + if(health <=0) + density = 0 + if(affecting) + var/mob/living/carbon/M = affecting + M.anchored = 0 + for(var/mob/O in viewers(src, 3)) + O.show_message("[M.name] was recovered from the energy net!", 1, "You hear a grunt.", 2) + if(!isnull(master))//As long as they still exist. + master << "ERROR: unable to initiate transport protocol. Procedure terminated." + qdel(src) + return + + + +/obj/effect/energy_net/process(var/mob/living/carbon/M as mob) + var/check = 30//30 seconds before teleportation. Could be extended I guess. + var/mob_name = affecting.name//Since they will report as null if terminated before teleport. + //The person can still try and attack the net when inside. + while(!isnull(M)&&!isnull(src)&&check>0)//While M and net exist, and 30 seconds have not passed. + check-- + sleep(10) + + if(isnull(M)||M.loc!=loc)//If mob is gone or not at the location. + if(!isnull(master))//As long as they still exist. + master << "ERROR: unable to locate \the [mob_name]. Procedure terminated." + qdel(src)//Get rid of the net. + return + + if(!isnull(src))//As long as both net and person exist. + //No need to check for countdown here since while() broke, it's implicit that it finished. + + density = 0//Make the net pass-through. + invisibility = 101//Make the net invisible so all the animations can play out. + health = INFINITY//Make the net invincible so that an explosion/something else won't kill it while, spawn() is running. + for(var/obj/item/W in M) + if(istype(M,/mob/living/carbon/human)) + if(W==M:w_uniform) continue//So all they're left with are shoes and uniform. + if(W==M:shoes) continue + M.unEquip(W) + + spawn(0) + playsound(M.loc, 'sound/effects/sparks4.ogg', 50, 1) + anim(M.loc,M,'icons/mob/mob.dmi',,"phaseout",,M.dir) + + M.loc = pick(holdingfacility)//Throw mob in to the holding facility. + M << "You appear in a strange place!" + + spawn(0) + var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread() + spark_system.set_up(5, 0, M.loc) + spark_system.start() + playsound(M.loc, 'sound/effects/phasein.ogg', 25, 1) + playsound(M.loc, 'sound/effects/sparks2.ogg', 50, 1) + anim(M.loc,M,'icons/mob/mob.dmi',,"phasein",,M.dir) + qdel(src)//Wait for everything to finish, delete the net. Else it will stop everything once net is deleted, including the spawn(0). + + for(var/mob/O in viewers(src, 3)) + O.show_message("[M] vanished!", 1, "You hear sparks flying!", 2) + + if(!isnull(master))//As long as they still exist. + master << "SUCCESS: transport procedure of \the [affecting] complete." + + M.anchored = 0//Important. + + else//And they are free. + M << "You are free of the net!" + return + + + +/obj/effect/energy_net/bullet_act(var/obj/item/projectile/Proj) + health -= Proj.damage + healthcheck() + ..() + + + +/obj/effect/energy_net/ex_act(severity, target) + switch(severity) + if(1.0) + health-=50 + if(2.0) + health-=50 + if(3.0) + health-=prob(50)?50:25 + healthcheck() + return + + + +/obj/effect/energy_net/blob_act() + health-=50 + healthcheck() + return + + + +/obj/effect/energy_net/hitby(AM as mob|obj) + ..() + visible_message("[src] was hit by [AM].") + var/tforce = 0 + if(ismob(AM)) + tforce = 10 + else + tforce = AM:throwforce + playsound(src.loc, 'sound/weapons/slash.ogg', 80, 1) + health = max(0, health - tforce) + healthcheck() + ..() + return + + + +/obj/effect/energy_net/attack_hulk(mob/living/carbon/human/user) + ..(user, 1) + user.visible_message("[user] rips the energy net apart!", \ + "You easily destroy the energy net.") + health-=50 + healthcheck() + + + +/obj/effect/energy_net/attack_paw(mob/user) + return attack_hand() + + + +/obj/effect/energy_net/attack_alien(mob/living/user as mob) + user.do_attack_animation(src) + if (islarva(user)) + return + playsound(src.loc, 'sound/weapons/slash.ogg', 80, 1) + health -= rand(10, 20) + if(health > 0) + user.visible_message("[user] claws at the energy net!", \ + "\green You claw at the net.") + else + user.visible_message("[user] slices the energy net apart!", \ + "\green You slice the energy net to pieces.") + healthcheck() + return + + + +/obj/effect/energy_net/attackby(obj/item/weapon/W as obj, mob/user as mob, params) + var/aforce = W.force + health = max(0, health - aforce) + healthcheck() + ..() + return + diff --git a/code/modules/ninja/suit/n_suit_verbs/ninja_adrenaline.dm b/code/modules/ninja/suit/n_suit_verbs/ninja_adrenaline.dm new file mode 100644 index 00000000000..d6dc568105f --- /dev/null +++ b/code/modules/ninja/suit/n_suit_verbs/ninja_adrenaline.dm @@ -0,0 +1,26 @@ + + +//Wakes the user so they are able to do their thing. Also injects a decent dose of radium. +//Movement impairing would indicate drugs and the like. +/obj/item/clothing/suit/space/space_ninja/proc/ninjaboost() + set name = "Adrenaline Boost" + set desc = "Inject a secret chemical that will counteract all movement-impairing effect." + set category = "Ninja Ability" + set popup_menu = 0 + + if(!ninjacost(0,N_ADRENALINE))//Have to make sure stat is not counted for this ability. + var/mob/living/carbon/human/H = affecting + H.SetParalysis(0) + H.SetStunned(0) + H.SetWeakened(0) + + H.stat = 0//At least now you should be able to teleport away or shoot ninja stars. + spawn(30)//Slight delay so the enemy does not immedietly know the ability was used. Due to lag, this often came before waking up. + H.say(pick("A CORNERED FOX IS MORE DANGEROUS THAN A JACKAL!","HURT ME MOOORRREEE!","IMPRESSIVE!")) + spawn(70) + reagents.reaction(H, 2) + reagents.trans_id_to(H, "radium", a_transfer) + H << "You are beginning to feel the after-effect of the injection." + a_boost-- + s_coold = 3 + return \ No newline at end of file diff --git a/code/modules/ninja/suit/n_suit_verbs/ninja_cost_check.dm b/code/modules/ninja/suit/n_suit_verbs/ninja_cost_check.dm new file mode 100644 index 00000000000..1675dda4530 --- /dev/null +++ b/code/modules/ninja/suit/n_suit_verbs/ninja_cost_check.dm @@ -0,0 +1,29 @@ + + +//Cost function for suit Procs/Verbs/Abilities +/obj/item/clothing/suit/space/space_ninja/proc/ninjacost(cost = 0, specificCheck = 0) + var/mob/living/carbon/human/H = affecting + if((H.stat || H.incorporeal_move) && (specificCheck != N_ADRENALINE))//Will not return if user is using an adrenaline booster since you can use them when stat==1. + H << "You must be conscious and solid to do this."//It's not a problem of stat==2 since the ninja will explode anyway if they die. + return 1 + + var/actualCost = cost*10 + if(cost && cell.charge < actualCost) + H << "Not enough energy." + return 1 + else + //This shit used to be handled individually on every proc.. why even bother with a universal check proc then? + cell.charge-=(actualCost) + + switch(specificCheck) + if(N_STEALTH_CANCEL) + cancel_stealth()//Get rid of it. + if(N_SMOKE_BOMB) + if(!s_bombs) + H << "There are no more smoke bombs remaining." + return 1 + if(N_ADRENALINE) + if(!a_boost) + H << "You do not have any more adrenaline boosters." + return 1 + return (s_coold)//Returns the value of the variable which counts down to zero. \ No newline at end of file diff --git a/code/modules/ninja/suit/n_suit_verbs/ninja_empulse.dm b/code/modules/ninja/suit/n_suit_verbs/ninja_empulse.dm new file mode 100644 index 00000000000..8cfc6b89370 --- /dev/null +++ b/code/modules/ninja/suit/n_suit_verbs/ninja_empulse.dm @@ -0,0 +1,15 @@ + + +//Disables nearby tech equipment. +/obj/item/clothing/suit/space/space_ninja/proc/ninjapulse() + set name = "EM Burst (25E)" + set desc = "Disable any nearby technology with a electro-magnetic pulse." + set category = "Ninja Ability" + set popup_menu = 0 + + if(!ninjacost(250,N_STEALTH_CANCEL)) + var/mob/living/carbon/human/H = affecting + playsound(H.loc, 'sound/effects/EMPulse.ogg', 60, 2) + empulse(H, 4, 6) //Procs sure are nice. Slightly weaker than wizard's disable tch. + s_coold = 2 + return \ No newline at end of file diff --git a/code/modules/ninja/suit/n_suit_verbs/ninja_net.dm b/code/modules/ninja/suit/n_suit_verbs/ninja_net.dm new file mode 100644 index 00000000000..0a28094ca91 --- /dev/null +++ b/code/modules/ninja/suit/n_suit_verbs/ninja_net.dm @@ -0,0 +1,32 @@ + +//Allows the ninja to kidnap people +/obj/item/clothing/suit/space/space_ninja/proc/ninjanet(mob/living/carbon/C in oview())//Only living carbon mobs. + set name = "Energy Net (20E)" + set desc = "Captures a fallen opponent in a net of energy. Will teleport them to a holding facility after 30 seconds." + set category = null + set src = usr.contents + + if(!ninjacost(200,N_STEALTH_CANCEL) && iscarbon(C)) + var/mob/living/carbon/human/H = affecting + if(C.client)//Monkeys without a client can still step_to() and bypass the net. Also, netting inactive people is lame. + if(!locate(/obj/effect/energy_net) in C.loc)//Check if they are already being affected by an energy net. + for(var/turf/T in getline(H.loc, C.loc)) + if(T.density)//Don't want them shooting nets through walls. It's kind of cheesy. + H << "You may not use an energy net through solid obstacles!" + return + spawn(0) + H.Beam(C,"n_beam",,15) + C.anchored = 1//Anchors them so they can't move. + H.say("Get over here!") + var/obj/effect/energy_net/E = new /obj/effect/energy_net(C.loc) + E.layer = C.layer+1//To have it appear one layer above the mob. + H.visible_message("[H] caught [C] with an energy net!","You caught [C] with an energy net!") + E.affecting = C + E.master = H + spawn(0)//Parallel processing. + E.process(C) + else + H << "They are already trapped inside an energy net." + else + H << "They will bring no honor to your Clan!" + return \ No newline at end of file diff --git a/code/modules/ninja/suit/n_suit_verbs/ninja_smoke.dm b/code/modules/ninja/suit/n_suit_verbs/ninja_smoke.dm new file mode 100644 index 00000000000..8d2ff7c3cfe --- /dev/null +++ b/code/modules/ninja/suit/n_suit_verbs/ninja_smoke.dm @@ -0,0 +1,19 @@ + + +//Smoke bomb +/obj/item/clothing/suit/space/space_ninja/proc/ninjasmoke() + set name = "Smoke Bomb" + set desc = "Blind your enemies momentarily with a well-placed smoke bomb." + set category = "Ninja Ability" + set popup_menu = 0//Will not see it when right clicking. + + if(!ninjacost(0,N_SMOKE_BOMB)) + var/mob/living/carbon/human/H = affecting + H << "There are [s_bombs] smoke bombs remaining." + var/datum/effect/effect/system/bad_smoke_spread/smoke = new /datum/effect/effect/system/bad_smoke_spread() + smoke.set_up(10, 0, H.loc) + smoke.start() + playsound(H.loc, 'sound/effects/bamf.ogg', 50, 2) + s_bombs-- + s_coold = 1 + return \ No newline at end of file diff --git a/code/modules/ninja/suit/n_suit_verbs/ninja_stars.dm b/code/modules/ninja/suit/n_suit_verbs/ninja_stars.dm new file mode 100644 index 00000000000..9196ed92be7 --- /dev/null +++ b/code/modules/ninja/suit/n_suit_verbs/ninja_stars.dm @@ -0,0 +1,33 @@ + + +//Shoots ninja stars at a random target +/obj/item/clothing/suit/space/space_ninja/proc/ninjastar() + set name = "Energy Star (5E)" + set desc = "Launches an energy star at a random living target." + set category = "Ninja Ability" + set popup_menu = 0 + + if(!ninjacost(50)) + var/mob/living/carbon/human/H = affecting + var/list/targets = list() + for(var/mob/living/M in oview(loc)) + if(M.stat) continue//Doesn't target corpses or paralyzed persons. + targets.Add(M) + if(targets.len) + var/mob/living/target=pick(targets)//The point here is to pick a random, living mob in oview to shoot stuff at. + + var/turf/curloc = get_turf(H) + var/turf/targloc = get_turf(target) + if (!targloc || !curloc) + return + if (targloc == curloc) + return + var/obj/item/projectile/energy/dart/A = new /obj/item/projectile/energy/dart(curloc) + A.current = curloc + A.yo = targloc.y - curloc.y + A.xo = targloc.x - curloc.x + + A.fire() + else + H << "There are no targets in view." + return diff --git a/code/modules/ninja/suit/n_suit_verbs/ninja_stealth.dm b/code/modules/ninja/suit/n_suit_verbs/ninja_stealth.dm new file mode 100644 index 00000000000..e87ac8e1ff8 --- /dev/null +++ b/code/modules/ninja/suit/n_suit_verbs/ninja_stealth.dm @@ -0,0 +1,78 @@ + +/* + +Contents: +- Stealth Verbs +- Stealth Icon Stuff + +*/ + + +/obj/item/clothing/suit/space/space_ninja/proc/toggle_stealth() + var/mob/living/carbon/human/U = affecting + if(s_active) + cancel_stealth() + else + spawn(0) + anim(U.loc,U,'icons/mob/mob.dmi',,"cloak",,U.dir) + s_active=!s_active + U.alpha = 0 + U.visible_message("[U.name] vanishes into thin air!", \ + "You are now invisible to normal detection.") + return + + +/obj/item/clothing/suit/space/space_ninja/proc/cancel_stealth() + var/mob/living/carbon/human/U = affecting + if(s_active) + spawn(0) + anim(U.loc,U,'icons/mob/mob.dmi',,"uncloak",,U.dir) + s_active=!s_active + U.alpha = 255 + U.visible_message("[U.name] appears from thin air!", \ + "You are now visible.") + return 1 + return 0 + + +/obj/item/clothing/suit/space/space_ninja/proc/stealth() + set name = "Toggle Stealth" + set desc = "Utilize the internal CLOAK-tech device to activate or deactivate stealth-camo." + set category = "Ninja Equip" + + if(!s_busy) + toggle_stealth() + else + affecting << "Stealth does not appear to work!" + + +//Allows the mob to grab a stealth icon. +/mob/proc/NinjaStealthActive(atom/A)//A is the atom which we are using as the overlay. + invisibility = INVISIBILITY_LEVEL_TWO//Set ninja invis to 2. + var/icon/opacity_icon = new(A.icon, A.icon_state) + var/icon/alpha_mask = getIconMask(src) + var/icon/alpha_mask_2 = new('icons/effects/effects.dmi', "at_shield1") + alpha_mask.AddAlphaMask(alpha_mask_2) + opacity_icon.AddAlphaMask(alpha_mask) + for(var/i=0,i<5,i++)//And now we add it as overlays. It's faster than creating an icon and then merging it. + var/image/I = image("icon" = opacity_icon, "icon_state" = A.icon_state, "layer" = layer+0.8)//So it's above other stuff but below weapons and the like. + switch(i)//Now to determine offset so the result is somewhat blurred. + if(1) + I.pixel_x -= 1 + if(2) + I.pixel_x += 1 + if(3) + I.pixel_y -= 1 + if(4) + I.pixel_y += 1 + + overlays += I//And finally add the overlay. + overlays += image("icon"='icons/effects/effects.dmi',"icon_state" ="electricity","layer" = layer+0.9) + +//When ninja steal malfunctions. +/mob/proc/NinjaStealthMalf() + invisibility = 0//Set ninja invis to 0. + overlays += image("icon"='icons/effects/effects.dmi',"icon_state" ="electricity","layer" = layer+0.9) + playsound(loc, 'sound/effects/stealthoff.ogg', 75, 1) + + diff --git a/code/modules/ninja/suit/n_suit_verbs/ninja_teleporting.dm b/code/modules/ninja/suit/n_suit_verbs/ninja_teleporting.dm new file mode 100644 index 00000000000..27f46f0d8ee --- /dev/null +++ b/code/modules/ninja/suit/n_suit_verbs/ninja_teleporting.dm @@ -0,0 +1,89 @@ + + +/* + +Contents: +- Proc for handling teleporting while grabbing someone +- Telport Ability +- Right-Click Teleport Ability + +*/ + + +//Handles elporting while grabbing someone +/obj/item/clothing/suit/space/space_ninja/proc/handle_teleport_grab(turf/T, mob/living/H) + if(istype(H.get_active_hand(),/obj/item/weapon/grab))//Handles grabbed persons. + var/obj/item/weapon/grab/G = H.get_active_hand() + G.affecting.loc = locate(T.x+rand(-1,1),T.y+rand(-1,1),T.z)//variation of position. + if(istype(H.get_inactive_hand(),/obj/item/weapon/grab)) + var/obj/item/weapon/grab/G = H.get_inactive_hand() + G.affecting.loc = locate(T.x+rand(-1,1),T.y+rand(-1,1),T.z)//variation of position. + return + + +//Jaunt +/obj/item/clothing/suit/space/space_ninja/proc/ninjajaunt() + set name = "Phase Jaunt (10E)" + set desc = "Utilizes the internal VOID-shift device to rapidly transit in direction facing." + set category = "Ninja Ability" + set popup_menu = 0 + + if(!ninjacost(100,N_STEALTH_CANCEL)) + var/mob/living/carbon/human/H = affecting + var/turf/destination = get_teleport_loc(H.loc,H,9,1,3,1,0,1) + var/turf/mobloc = get_turf(H.loc)//Safety + + if(destination&&istype(mobloc, /turf))//So we don't teleport out of containers + spawn(0) + playsound(H.loc, "sparks", 50, 1) + anim(mobloc,src,'icons/mob/mob.dmi',,"phaseout",,H.dir) + + handle_teleport_grab(destination, H) + H.loc = destination + + spawn(0) + spark_system.start() + playsound(H.loc, 'sound/effects/phasein.ogg', 25, 1) + playsound(H.loc, "sparks", 50, 1) + anim(H.loc,H,'icons/mob/mob.dmi',,"phasein",,H.dir) + + spawn(0) + destination.phase_damage_creatures(20,H)//Paralyse and damage mobs and mechas on the turf + s_coold = 1 + else + H << "The VOID-shift device is malfunctioning, teleportation failed." + return + + +//Right-Click teleport: It's basically admin "jump to turf" +/obj/item/clothing/suit/space/space_ninja/proc/ninjashift(turf/T in oview()) + set name = "Phase Shift (20E)" + set desc = "Utilizes the internal VOID-shift device to rapidly transit to a destination in view." + set category = null//So it does not show up on the panel but can still be right-clicked. + set src = usr.contents//Fixes verbs not attaching properly for objects. Praise the DM reference guide! + + if(!ninjacost(200,N_STEALTH_CANCEL)) + var/mob/living/carbon/human/H = affecting + var/turf/mobloc = get_turf(H.loc)//To make sure that certain things work properly below. + if((!T.density)&&istype(mobloc, /turf)) + spawn(0) + playsound(H.loc, 'sound/effects/sparks4.ogg', 50, 1) + anim(mobloc,src,'icons/mob/mob.dmi',,"phaseout",,H.dir) + + handle_teleport_grab(T, H) + H.loc = T + + spawn(0) + spark_system.start() + playsound(H.loc, 'sound/effects/phasein.ogg', 25, 1) + playsound(H.loc, 'sound/effects/sparks2.ogg', 50, 1) + anim(H.loc,H,'icons/mob/mob.dmi',,"phasein",,H.dir) + + spawn(0)//Any living mobs in teleport area are gibbed. + T.phase_damage_creatures(20,H)//Paralyse and damage mobs and mechas on the turf + s_coold = 1 + else + H << "You cannot teleport into solid walls or from solid matter" + return + + diff --git a/code/modules/ninja/suit/shoes.dm b/code/modules/ninja/suit/shoes.dm new file mode 100644 index 00000000000..732f8a37e8d --- /dev/null +++ b/code/modules/ninja/suit/shoes.dm @@ -0,0 +1,14 @@ + +/obj/item/clothing/shoes/space_ninja + name = "ninja shoes" + desc = "A pair of running shoes. Excellent for running and even better for smashing skulls." + icon_state = "s-ninja" + item_state = "secshoes" + permeability_coefficient = 0.01 + flags = NOSLIP + armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 30, rad = 30) + strip_delay = 120 + cold_protection = FEET + min_cold_protection_temperature = SHOES_MIN_TEMP_PROTECT + heat_protection = FEET + max_heat_protection_temperature = SHOES_MAX_TEMP_PROTECT \ No newline at end of file diff --git a/code/modules/ninja/suit/suit.dm b/code/modules/ninja/suit/suit.dm new file mode 100644 index 00000000000..cfe6dc3c807 --- /dev/null +++ b/code/modules/ninja/suit/suit.dm @@ -0,0 +1,172 @@ + +/* + +Contents: +- The Ninja Space Suit +- Ninja Space Suit Procs + +*/ + + +// /obj/item/clothing/suit/space/space_ninja + + +/obj/item/clothing/suit/space/space_ninja + name = "ninja suit" + desc = "A unique, vaccum-proof suit of nano-enhanced armor designed specifically for Spider Clan assassins." + icon_state = "s-ninja" + item_state = "s-ninja_suit" + allowed = list(/obj/item/weapon/gun,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/restraints/handcuffs,/obj/item/weapon/tank/internals,/obj/item/weapon/stock_parts/cell) + slowdown = 0 + unacidable = 1 + armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 30, rad = 30) + strip_delay = 12 + + //Important parts of the suit. + var/mob/living/carbon/human/affecting = null + var/obj/item/weapon/stock_parts/cell/cell + var/datum/effect/effect/system/spark_spread/spark_system + var/list/reagent_list = list("omnizine","salbutamol","spaceacillin","charcoal","nutriment","radium","potass_iodide")//The reagents ids which are added to the suit at New(). + var/list/stored_research = list()//For stealing station research. + var/obj/item/weapon/disk/tech_disk/t_disk//To copy design onto disk. + + //Other articles of ninja gear worn together, used to easily reference them after initializing. + var/obj/item/clothing/head/helmet/space/space_ninja/n_hood + var/obj/item/clothing/shoes/space_ninja/n_shoes + var/obj/item/clothing/gloves/space_ninja/n_gloves + + //Main function variables. + var/s_initialized = 0//Suit starts off. + var/s_coold = 0//If the suit is on cooldown. Can be used to attach different cooldowns to abilities. Ticks down every second based on suit ntick(). + var/s_cost = 5.0//Base energy cost each ntick. + var/s_acost = 25.0//Additional cost for additional powers active. + var/s_delay = 40.0//How fast the suit does certain things, lower is faster. Can be overridden in specific procs. Also determines adverse probability. + var/a_transfer = 20.0//How much reagent is transferred when injecting. + var/r_maxamount = 80.0//How much reagent in total there is. + + //Support function variables. + var/spideros = 0//Mode of SpiderOS. This can change so I won't bother listing the modes here (0 is hub). Check ninja_equipment.dm for how it all works. + var/s_active = 0//Stealth off. + var/s_busy = 0//Is the suit busy with a process? Like AI hacking. Used for safety functions. + + //Ability function variables. + var/s_bombs = 10.0//Number of starting ninja smoke bombs. + var/a_boost = 3.0//Number of adrenaline boosters. + + +/obj/item/clothing/suit/space/space_ninja/New() + ..() + verbs += /obj/item/clothing/suit/space/space_ninja/proc/init//suit initialize verb + + //Spark Init + spark_system = new() + spark_system.set_up(5, 0, src) + spark_system.attach(src) + + //Research Init + stored_research = new() + for(var/T in typesof(/datum/tech) - /datum/tech)//Store up on research. + stored_research += new T(src) + + //Reagent Init + var/reagent_amount + for(var/reagent_id in reagent_list) + reagent_amount += reagent_id == "radium" ? r_maxamount+(a_boost*a_transfer) : r_maxamount + reagents = new(reagent_amount) + reagents.my_atom = src + for(var/reagent_id in reagent_list) + reagent_id == "radium" ? reagents.add_reagent(reagent_id, r_maxamount+(a_boost*a_transfer)) : reagents.add_reagent(reagent_id, r_maxamount)//It will take into account radium used for adrenaline boosting. + + //Cell Init + cell = new/obj/item/weapon/stock_parts/cell/high + cell.charge = 9000 + + + +/obj/item/clothing/suit/space/space_ninja/Destroy() + if(affecting) + affecting << browse(null, "window=hack spideros") + ..() + + +//Simply deletes all the attachments and self, killing all related procs. +/obj/item/clothing/suit/space/space_ninja/proc/terminate() + qdel(n_hood) + qdel(n_gloves) + qdel(n_shoes) + qdel(src) + + +//Randomizes suit parameters. +/obj/item/clothing/suit/space/space_ninja/proc/randomize_param() + s_cost = rand(1,20) + s_acost = rand(20,100) + s_delay = rand(10,100) + s_bombs = rand(5,20) + a_boost = rand(1,7) + + +//This proc prevents the suit from being taken off. +/obj/item/clothing/suit/space/space_ninja/proc/lock_suit(mob/living/carbon/human/H, var/checkIcons = 0) + if(!istype(H)) + return 0 + if(checkIcons) + icon_state = H.gender==FEMALE ? "s-ninjanf" : "s-ninjan" + H.gloves.icon_state = "s-ninjan" + H.gloves.item_state = "s-ninjan" + else + if(H.mind.special_role!="Space Ninja") + H << "\red fÄTaL ÈÈRRoR: 382200-*#00CÖDE RED\nUNAU†HORIZED USÈ DETÈC†††eD\nCoMMÈNCING SUB-R0U†IN3 13...\nTÈRMInATING U-U-USÈR..." + H.gib() + return 0 + if(!istype(H.head, /obj/item/clothing/head/helmet/space/space_ninja)) + H << "ERROR: 100113 UNABLE TO LOCATE HEAD GEAR\nABORTING..." + return 0 + if(!istype(H.shoes, /obj/item/clothing/shoes/space_ninja)) + H << "ERROR: 122011 UNABLE TO LOCATE FOOT GEAR\nABORTING..." + return 0 + if(!istype(H.gloves, /obj/item/clothing/gloves/space_ninja)) + H << "ERROR: 110223 UNABLE TO LOCATE HAND GEAR\nABORTING..." + return 0 + + affecting = H + flags |= NODROP //colons make me go all |= + slowdown = 0 + n_hood = H.head + n_hood.flags |= NODROP + n_shoes = H.shoes + n_shoes.flags |= NODROP + n_shoes.slowdown-- + n_gloves = H.gloves + n_gloves.flags |= NODROP + + return 1 + + +//This proc allows the suit to be taken off. +/obj/item/clothing/suit/space/space_ninja/proc/unlock_suit() + affecting = null + flags &= ~NODROP + slowdown = 1 + icon_state = "s-ninja" + if(n_hood)//Should be attached, might not be attached. + n_hood.flags &= ~NODROP + if(n_shoes) + n_shoes.flags &= ~NODROP + n_shoes.slowdown++ + if(n_gloves) + n_gloves.icon_state = "s-ninja" + n_gloves.item_state = "s-ninja" + n_gloves.flags &= ~NODROP + n_gloves.candrain=0 + n_gloves.draining=0 + + +/obj/item/clothing/suit/space/space_ninja/examine(mob/user) + ..() + if(s_initialized) + if(user == affecting) + user << "All systems operational. Current energy capacity: [cell.charge]." + user << "The CLOAK-tech device is [s_active?"active":"inactive"]." + user << "There are [s_bombs] smoke bomb\s remaining." + user << "There are [a_boost] adrenaline booster\s remaining." diff --git a/code/modules/ninja/suit/suit_attackby.dm b/code/modules/ninja/suit/suit_attackby.dm new file mode 100644 index 00000000000..e7098179d6a --- /dev/null +++ b/code/modules/ninja/suit/suit_attackby.dm @@ -0,0 +1,61 @@ + + +/obj/item/clothing/suit/space/space_ninja/attackby(obj/item/I, mob/U, params) + if(U==affecting)//Safety, in case you try doing this without wearing the suit/being the person with the suit. + + if(istype(I, /obj/item/weapon/reagent_containers/glass))//If it's a glass beaker. + var/total_reagent_transfer//Keep track of this stuff. + for(var/reagent_id in reagent_list) + var/datum/reagent/R = I.reagents.has_reagent(reagent_id)//Mostly to pull up the name of the reagent after calculating. Also easier to use than writing long proc paths. + if(R&&reagents.get_reagent_amount(reagent_id)=a_transfer)//Radium is always special. + //Here we determine how much reagent will actually transfer if there is enough to transfer or there is a need of transfer. Minimum of max amount available (using a_transfer) or amount needed. + var/amount_to_transfer = min( (r_maxamount+(reagent_id == "radium"?(a_boost*a_transfer):0)-reagents.get_reagent_amount(reagent_id)) ,(round(R.volume/a_transfer))*a_transfer)//In the end here, we round the amount available, then multiply it again. + R.volume -= amount_to_transfer//Remove from reagent volume. Don't want to delete the reagent now since we need to perserve the name. + reagents.add_reagent(reagent_id, amount_to_transfer)//Add to suit. Reactions are not important. + total_reagent_transfer += amount_to_transfer//Add to total reagent trans. + U << "Added [amount_to_transfer] units of [R.name]."//Reports on the specific reagent added. + I.reagents.update_total()//Now we manually update the total to make sure everything is properly shoved under the rug. + + U << "Replenished a total of [total_reagent_transfer ? total_reagent_transfer : "zero"] chemical units."//Let the player know how much total volume was added. + return + + else if(istype(I, /obj/item/weapon/stock_parts/cell)) + var/obj/item/weapon/stock_parts/cell/CELL + if(CELL.maxcharge > cell.maxcharge && n_gloves && n_gloves.candrain) + U << "Higher maximum capacity detected.\nUpgrading..." + if (n_gloves && n_gloves.candrain && do_after(U,s_delay)) + U.drop_item() + CELL.loc = src + CELL.charge = min(CELL.charge+cell.charge, CELL.maxcharge) + var/obj/item/weapon/stock_parts/cell/old_cell = cell + old_cell.charge = 0 + U.put_in_hands(old_cell) + old_cell.add_fingerprint(U) + old_cell.corrupt() + old_cell.updateicon() + cell = CELL + U << "Upgrade complete. Maximum capacity: [round(cell.maxcharge/100)]%" + else + U << "Procedure interrupted. Protocol terminated." + return + + else if(istype(I, /obj/item/weapon/disk/tech_disk))//If it's a data disk, we want to copy the research on to the suit. + var/obj/item/weapon/disk/tech_disk/TD = I + if(TD.stored)//If it has something on it. + U << "Research information detected, processing..." + if(do_after(U,s_delay)) + for(var/datum/tech/current_data in stored_research) + if(current_data.id==TD.stored.id) + if(current_data.levelData analyzed and updated. Disk erased." + else + U << "ERROR: Procedure interrupted. Process terminated." + else + I.loc = src + t_disk = I + U << "You slot \the [I] into \the [src]." + return + ..() \ No newline at end of file diff --git a/code/modules/ninja/suit/suit_initialisation.dm b/code/modules/ninja/suit/suit_initialisation.dm new file mode 100644 index 00000000000..967f6e3871e --- /dev/null +++ b/code/modules/ninja/suit/suit_initialisation.dm @@ -0,0 +1,102 @@ + +//Verbs link to procs because verb-like procs have a bug which prevents their use if the arguments are not readily referenced. +//^ Old coder words may be false these days, Not taking the risk for now. + +/obj/item/clothing/suit/space/space_ninja/proc/init() + set name = "Initialize Suit" + set desc = "Initializes the suit for field operation." + set category = "Ninja Equip" + + ninitialize() + +/obj/item/clothing/suit/space/space_ninja/proc/deinit() + set name = "De-Initialize Suit" + set desc = "Begins procedure to remove the suit." + set category = "Ninja Equip" + + if(!s_busy) + deinitialize() + else + affecting << "The function did not trigger!" + + +/obj/item/clothing/suit/space/space_ninja/proc/ninitialize(delay = s_delay, mob/living/carbon/human/U = loc) + if(U.mind && U.mind.assigned_role=="MODE" && !s_initialized && !s_busy)//Shouldn't be busy... but anything is possible I guess. + s_busy = 1 + for(var/i,i<7,i++) + switch(i) + if(0) + U << "Now initializing..." + if(1) + if(!lock_suit(U))//To lock the suit onto wearer. + break + U << "Securing external locking mechanism...\nNeural-net established." + if(2) + U << "Extending neural-net interface...\nNow monitoring brain wave pattern..." + if(3) + if(U.stat==2||U.health<=0) + U << "FĆAL �Rr�R: 344--93#�&&21 BR��N |/|/aV� PATT$RN RED\nA-A-aB�rT�NG..." + unlock_suit() + break + lock_suit(U,1)//Check for icons. + U.regenerate_icons() + U << " Linking neural-net interface...\nPattern\green GREEN, continuing operation." + if(4) + U << "VOID-shift device status: ONLINE.\nCLOAK-tech device status: ONLINE." + if(5) + U << "Primary system status: ONLINE.\nBackup system status: ONLINE.\nCurrent energy capacity: [cell.charge]." + if(6) + U << "All systems operational. Welcome to SpiderOS, [U.real_name]." + grant_ninja_verbs() + grant_equip_verbs() + ntick() + sleep(delay) + s_busy = 0 + else + if(!U.mind||U.mind.assigned_role!="MODE")//Your run of the mill persons shouldn't know what it is. Or how to turn it on. + U << "You do not understand how this suit functions. Where the heck did it even come from?" + else if(s_initialized) + U << "The suit is already functioning. Please report this bug." + else + U << "ERROR: You cannot use this function at this time." + return + + + +/obj/item/clothing/suit/space/space_ninja/proc/deinitialize(delay = s_delay) + if(affecting==loc&&!s_busy) + var/mob/living/carbon/human/U = affecting + if(!s_initialized) + U << "The suit is not initialized. Please report this bug." + return + if(alert("Are you certain you wish to remove the suit? This will take time and remove all abilities.",,"Yes","No")=="No") + return + if(s_busy) + U << "ERROR: You cannot use this function at this time." + return + s_busy = 1 + for(var/i = 0,i<7,i++) + switch(i) + if(0) + U << "Now de-initializing..." + spideros = 0//Spideros resets. + if(1) + U << "Logging off, [U:real_name]. Shutting down SpiderOS." + remove_ninja_verbs() + if(2) + U << "Primary system status: OFFLINE.\nBackup system status: OFFLINE." + if(3) + U << "VOID-shift device status: OFFLINE.\nCLOAK-tech device status: OFFLINE." + cancel_stealth()//Shutdowns stealth. + if(4) + U << "Disconnecting neural-net interface...\greenSuccess." + if(5) + U << "Disengaging neural-net interface...\greenSuccess." + if(6) + U << "Unsecuring external locking mechanism...\nNeural-net abolished.\nOperation status: FINISHED." + remove_equip_verbs() + unlock_suit() + U.regenerate_icons() + sleep(delay) + s_busy = 0 + return \ No newline at end of file diff --git a/code/modules/ninja/suit/suit_process.dm b/code/modules/ninja/suit/suit_process.dm new file mode 100644 index 00000000000..6440ffc71c9 --- /dev/null +++ b/code/modules/ninja/suit/suit_process.dm @@ -0,0 +1,28 @@ + + +/obj/item/clothing/suit/space/space_ninja/proc/ntick(mob/living/carbon/human/U = affecting) + set background = BACKGROUND_ENABLED + + //Runs in the background while the suit is initialized. + spawn while(cell.charge) + + //Let's check for some safeties. + if(s_initialized && !affecting) + terminate()//Kills the suit and attached objects. + if(!s_initialized) + return//When turned off the proc stops. + + //Now let's do the normal processing. + if(s_coold) + s_coold--//Checks for ability s_cooldown first. + + var/A = s_cost//s_cost is the default energy cost each ntick, usually 5. + if(s_active)//If stealth is active. + A += s_acost + cell.charge-=A + + if(!cell.charge) + cell.charge=0 + cancel_stealth() + + sleep(10)//Checks every second. diff --git a/code/modules/ninja/suit/suit_verbs_handlers.dm b/code/modules/ninja/suit/suit_verbs_handlers.dm new file mode 100644 index 00000000000..17ba1ca3910 --- /dev/null +++ b/code/modules/ninja/suit/suit_verbs_handlers.dm @@ -0,0 +1,52 @@ +/* + +Contents: +- Procs that add ninja verbs to ninjas +- Procs that remove ninja verbs from ninjas +- Procs that add ninjasuit verbs to ninjas +- Procs that remove ninjasuit verbs from ninjas + +*/ + +/obj/item/clothing/suit/space/space_ninja/proc/grant_equip_verbs() + verbs -= /obj/item/clothing/suit/space/space_ninja/proc/init + verbs += /obj/item/clothing/suit/space/space_ninja/proc/deinit + verbs += /obj/item/clothing/suit/space/space_ninja/proc/spideros + verbs += /obj/item/clothing/suit/space/space_ninja/proc/stealth + n_gloves.verbs += /obj/item/clothing/gloves/space_ninja/proc/toggled + + s_initialized = 1 + + +/obj/item/clothing/suit/space/space_ninja/proc/remove_equip_verbs() + verbs += /obj/item/clothing/suit/space/space_ninja/proc/init + verbs -= /obj/item/clothing/suit/space/space_ninja/proc/deinit + verbs -= /obj/item/clothing/suit/space/space_ninja/proc/spideros + verbs -= /obj/item/clothing/suit/space/space_ninja/proc/stealth + if(n_gloves) + n_gloves.verbs -= /obj/item/clothing/gloves/space_ninja/proc/toggled + + s_initialized = 0 + + +/obj/item/clothing/suit/space/space_ninja/proc/grant_ninja_verbs() + verbs += /obj/item/clothing/suit/space/space_ninja/proc/ninjashift + verbs += /obj/item/clothing/suit/space/space_ninja/proc/ninjajaunt + verbs += /obj/item/clothing/suit/space/space_ninja/proc/ninjasmoke + verbs += /obj/item/clothing/suit/space/space_ninja/proc/ninjaboost + verbs += /obj/item/clothing/suit/space/space_ninja/proc/ninjapulse + verbs += /obj/item/clothing/suit/space/space_ninja/proc/ninjastar + verbs += /obj/item/clothing/suit/space/space_ninja/proc/ninjanet + + s_initialized=1 + slowdown=0 + + +/obj/item/clothing/suit/space/space_ninja/proc/remove_ninja_verbs() + verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjashift + verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjajaunt + verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjasmoke + verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjaboost + verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjapulse + verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjastar + verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjanet diff --git a/code/modules/paperwork/paper.dm b/code/modules/paperwork/paper.dm index e6ed40a2164..5d4d98b84a8 100644 --- a/code/modules/paperwork/paper.dm +++ b/code/modules/paperwork/paper.dm @@ -26,6 +26,7 @@ var/list/stamped var/rigged = 0 var/spam_flag = 0 + var/burning = 0 //Whether or not the paper is on fire /obj/item/weapon/paper/New() @@ -88,6 +89,15 @@ spam_flag = 0 +/obj/item/weapon/paper/attack_hand() + var/mob/living/carbon/M = usr + if(burning) + M << "Picking up a burning paper seems awfully stupid." + return //Doesn't make any sense to pick up a burning paper + else //Probably isn't necessary but it's safer + ..() + + /obj/item/weapon/paper/attack_ai(mob/living/silicon/ai/user) var/dist if(istype(user) && user.current) //is AI @@ -268,6 +278,9 @@ /obj/item/weapon/paper/attackby(obj/item/weapon/P, mob/living/carbon/human/user, params) ..() + if(burning) + return + if(is_blind(user)) return @@ -298,8 +311,39 @@ user << "You stamp the paper with your rubber stamp." + if(is_hot(P)) + if(user.disabilities & CLUMSY && prob(10)) + user.visible_message("[user] accidentally ignites themselves!", \ + "You miss the paper and accidentally light yourself on fire!") + user.unEquip(P) + user.adjust_fire_stacks(1) + user.IgniteMob() + return + + if(!(in_range(user, src))) //to prevent issues as a result of telepathically lighting a paper + return + + user.unEquip(src) + user.visible_message("[user] lights [src] ablaze with [P]!", "You light [src] on fire!") + burn(0, 100) + + + add_fingerprint(user) +/obj/item/weapon/paper/fire_act() + burn(1, 50) + +/obj/item/weapon/paper/proc/burn(var/showmsg, var/burntime) + if(showmsg) + src.visible_message("[src] catches on fire!") + burning = 1 + icon_state = "paper_onfire" + info = "[stars(info)]" + sleep(burntime) //7 seconds + src.visible_message("[src] burns away, leaving behind a pile of ashes.") + new /obj/effect/decal/cleanable/ash(src.loc) + qdel(src) /* * Premade paper @@ -354,4 +398,4 @@ /obj/item/weapon/paper/crumpled/bloody - icon_state = "scrap_bloodied" \ No newline at end of file + icon_state = "scrap_bloodied" diff --git a/code/modules/paperwork/photocopier.dm b/code/modules/paperwork/photocopier.dm index f49516e8f76..6822c9b65f4 100644 --- a/code/modules/paperwork/photocopier.dm +++ b/code/modules/paperwork/photocopier.dm @@ -132,6 +132,8 @@ temp_img = icon("icons/ass/assfemale.png") else //In case anyone ever makes the generic ass. For now I'll be using male asses. temp_img = icon("icons/ass/assmale.png") + else if(isdrone (ass) || istype(ass,/mob/living/simple_animal/drone)) //Drones are hot + temp_img = icon("icons/ass/assdrone.png") else break var/obj/item/weapon/photo/p = new /obj/item/weapon/photo (loc) diff --git a/code/modules/power/cell.dm b/code/modules/power/cell.dm index 97fa83a7f47..a73e924ee08 100644 --- a/code/modules/power/cell.dm +++ b/code/modules/power/cell.dm @@ -57,15 +57,6 @@ else user << "The charge meter reads [round(src.percent() )]%." -/obj/item/weapon/stock_parts/cell/attack_self(mob/user as mob) - src.add_fingerprint(user) - if(ishuman(user)) - var/mob/living/carbon/human/H = user - var/obj/item/clothing/gloves/space_ninja/SNG = H.gloves - if(!istype(SNG) || !SNG.candrain || SNG.draining) return - - SNG.drain("CELL",src,H.wear_suit) - return /obj/item/weapon/stock_parts/cell/attackby(obj/item/W, mob/user, params) ..() diff --git a/code/modules/projectiles/ammunition/energy.dm b/code/modules/projectiles/ammunition/energy.dm index e7c81acfbcf..c6f8fbf6eba 100644 --- a/code/modules/projectiles/ammunition/energy.dm +++ b/code/modules/projectiles/ammunition/energy.dm @@ -59,7 +59,7 @@ select_name = "stun" fire_sound = 'sound/weapons/taser.ogg' e_cost = 200 - delay = 20 + delay = 15 /obj/item/ammo_casing/energy/electrode/gun fire_sound = 'sound/weapons/gunshot.ogg' diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index 722d6289a68..9b14f51bf4d 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -33,6 +33,11 @@ var/semicd = 0 //cooldown handler var/heavy_weapon = 0 + var/unique_rename = 0 //allows renaming with a pen + var/unique_reskin = 0 //allows one-time reskinning + var/reskinned = 0 //whether or not the gun has been reskinned + var/list/options = list() + lefthand_file = 'icons/mob/inhands/guns_lefthand.dmi' righthand_file = 'icons/mob/inhands/guns_righthand.dmi' @@ -251,6 +256,11 @@ S.update_brightness(user) update_icon() verbs -= /obj/item/weapon/gun/proc/toggle_gunlight + + if(unique_rename) + if(istype(A, /obj/item/weapon/pen)) + rename_gun(user) + ..() return @@ -305,3 +315,32 @@ if(F.on) user.AddLuminosity(-F.brightness_on) SetLuminosity(F.brightness_on) + + +/obj/item/weapon/gun/attack_hand(mob/user as mob) + if(unique_reskin && !reskinned && loc == user) + reskin_gun(user) + return + ..() + +/obj/item/weapon/gun/proc/reskin_gun(var/mob/M) + var/choice = input(M,"Warning, you can only reskin your weapon once!","Reskin Gun") in options + + if(src && choice && !M.stat && in_range(M,src) && !M.restrained() && M.canmove) + if(options[choice] == null) + return + if(sawn_state == SAWN_OFF) + icon_state = options[choice] + "-sawn" + else + icon_state = options[choice] + M << "Your gun is now skinned as [choice]. Say hello to your new friend." + reskinned = 1 + return + +/obj/item/weapon/gun/proc/rename_gun(var/mob/M) + var/input = stripped_input(M,"What do you want to name the gun?", ,"", MAX_NAME_LEN) + + if(src && input && !M.stat && in_range(M,src) && !M.restrained() && M.canmove) + name = input + M << "You name the gun [input]. Say hello to your new friend." + return \ No newline at end of file diff --git a/code/modules/projectiles/guns/energy/nuclear.dm b/code/modules/projectiles/guns/energy/nuclear.dm index f83123bf7c7..5f374dcfefb 100644 --- a/code/modules/projectiles/guns/energy/nuclear.dm +++ b/code/modules/projectiles/guns/energy/nuclear.dm @@ -13,7 +13,7 @@ update_icon() /obj/item/weapon/gun/energy/gun/hos - desc = "This is a modern recreation of the antique laser gun. This gun has several unique firemodes, but lacks the ability to recharge over time, its also expensive." + desc = "This is a expensive, modern recreation of a antique laser gun. This gun has several unique firemodes, but lacks the ability to recharge over time." icon_state = "hoslaser" item_state = null force = 10 @@ -126,4 +126,4 @@ trigger_guard = 0 obj/item/weapon/gun/energy/gun/turret/update_icon() - icon_state = initial(icon_state) + icon_state = initial(icon_state) diff --git a/code/modules/projectiles/guns/energy/special.dm b/code/modules/projectiles/guns/energy/special.dm index 9b8bb0f23ae..96822335fce 100644 --- a/code/modules/projectiles/guns/energy/special.dm +++ b/code/modules/projectiles/guns/energy/special.dm @@ -128,7 +128,7 @@ var/range_add = 0 var/overheat_time = 20 upgrades = list("diamond" = 0, "screwdriver" = 0, "plasma" = 0) - + unique_rename = 1 /obj/item/weapon/gun/energy/kinetic_accelerator/newshot() ..() @@ -161,6 +161,8 @@ power_supply.rigged = 1 // This is dangerous! S.use(1) + ..() + /obj/item/weapon/gun/energy/kinetic_accelerator/shoot_live_shot() overheat = 1 spawn(overheat_time) @@ -192,6 +194,7 @@ origin_tech = "combat=2;magnets=2;syndicate=5" suppressed = 1 ammo_type = list(/obj/item/ammo_casing/energy/bolt) + unique_rename = 0 /obj/item/weapon/gun/energy/kinetic_accelerator/crossbow/large name = "energy crossbow" diff --git a/code/modules/projectiles/guns/projectile/revolver.dm b/code/modules/projectiles/guns/projectile/revolver.dm index e96d6494e8f..fe5eab9f33e 100644 --- a/code/modules/projectiles/guns/projectile/revolver.dm +++ b/code/modules/projectiles/guns/projectile/revolver.dm @@ -22,6 +22,10 @@ update_icon() chamber_round() + if(unique_rename) + if(istype(A, /obj/item/weapon/pen)) + rename_gun(user) + /obj/item/weapon/gun/projectile/revolver/attack_self(mob/living/user as mob) var/num_unloaded = 0 while (get_ammo() > 0) @@ -57,6 +61,17 @@ icon_state = "detective" origin_tech = "combat=2;materials=2" mag_type = /obj/item/ammo_box/magazine/internal/cylinder/rev38 + unique_rename = 1 + unique_reskin = 1 + +/obj/item/weapon/gun/projectile/revolver/detective/New() + ..() + options["Default"] = "detective" + options["Leopard Spots"] = "detective_leopard" + options["Black Panther"] = "detective_panther" + options["Gold Trim"] = "detective_gold" + options["The Peacemaker"] = "detective_peacemaker" + options["Cancel"] = null /obj/item/weapon/gun/projectile/revolver/detective/process_fire(atom/target as mob|obj|turf, mob/living/user as mob|obj, var/message = 1, params) if(magazine.caliber != initial(magazine.caliber)) @@ -69,39 +84,6 @@ return 0 ..() - -/obj/item/weapon/gun/projectile/revolver/detective/verb/rename_gun() - set name = "Name Gun" - set category = "Object" - set desc = "Click to rename your gun." - - var/mob/M = usr - var/input = stripped_input(M,"What do you want to name the gun?", ,"", MAX_NAME_LEN) - - if(src && input && !M.stat && in_range(M,src) && !M.restrained() && M.canmove) - name = input - M << "You name the gun [input]. Say hello to your new friend." - return 1 - -/obj/item/weapon/gun/projectile/revolver/detective/verb/reskin_gun() - set name = "Reskin gun" - set category = "Object" - set desc = "Click to reskin your gun." - - var/mob/M = usr - var/list/options = list() - options["The Original"] = "detective" - options["Leopard Spots"] = "detective_leopard" - options["Black Panther"] = "detective_panther" - options["Gold Trim"] = "detective_gold" - options["The Peacemaker"] = "detective_peacemaker" - var/choice = input(M,"What do you want to skin the gun to?","Reskin Gun") in options - - if(src && choice && !M.stat && in_range(M,src) && !M.restrained() && M.canmove) - icon_state = options[choice] - M << "Your gun is now skinned as [choice]. Say hello to your new friend." - return 1 - /obj/item/weapon/gun/projectile/revolver/detective/attackby(var/obj/item/A as obj, mob/user as mob, params) ..() if(istype(A, /obj/item/weapon/screwdriver)) diff --git a/code/modules/projectiles/guns/projectile/shotgun.dm b/code/modules/projectiles/guns/projectile/shotgun.dm index 8301d638c28..b4de0731b06 100644 --- a/code/modules/projectiles/guns/projectile/shotgun.dm +++ b/code/modules/projectiles/guns/projectile/shotgun.dm @@ -139,6 +139,18 @@ origin_tech = "combat=3;materials=1" mag_type = /obj/item/ammo_box/magazine/internal/cylinder/dualshot sawn_desc = "Omar's coming!" + unique_rename = 1 + unique_reskin = 1 + +/obj/item/weapon/gun/projectile/revolver/doublebarrel/New() + ..() + options["Default"] = "dshotgun" + options["Dark Red Finish"] = "dshotgun-d" + options["Ash"] = "dshotgun-f" + options["Faded Grey"] = "dshotgun-g" + options["Maple"] = "dshotgun-l" + options["Rosewood"] = "dshotgun-p" + options["Cancel"] = null /obj/item/weapon/gun/projectile/revolver/doublebarrel/attackby(var/obj/item/A as obj, mob/user as mob, params) ..() @@ -179,6 +191,8 @@ origin_tech = "combat=2;materials=2" mag_type = /obj/item/ammo_box/magazine/internal/cylinder/improvised sawn_desc = "I'm just here for the gasoline." + unique_rename = 0 + unique_reskin = 0 /obj/item/weapon/gun/projectile/revolver/doublebarrel/improvised/attackby(var/obj/item/A as obj, mob/user as mob, params) ..() @@ -193,7 +207,8 @@ user << "You need at least ten lengths of cable if you want to make a sling." return -//Sawing guns related procs +// Sawing guns related procs // + /obj/item/weapon/gun/projectile/proc/blow_up(mob/user as mob) . = 0 for(var/obj/item/ammo_casing/AC in magazine.stored_ammo) @@ -228,7 +243,7 @@ user.visible_message("[user] shortens \the [src]!", "You shorten \the [src]!") name = "sawn-off [src.name]" desc = sawn_desc - icon_state = initial(icon_state) + "-sawn" + icon_state = "[icon_state]-sawn" w_class = 3.0 item_state = "gun" slot_flags &= ~SLOT_BACK //you can't sling it on your back @@ -240,6 +255,8 @@ sawn_state = SAWN_INTACT +// Bulldog shotgun // + /obj/item/weapon/gun/projectile/automatic/shotgun/bulldog name = "syndicate shotgun" desc = "A semi-auto, mag-fed shotgun for combat in narrow corridors, nicknamed 'Bulldog' by boarding parties. Compatible only with specialized 8-round drum magazines." diff --git a/code/modules/reagents/Chemistry-Goon-Medicine.dm b/code/modules/reagents/Chemistry-Goon-Medicine.dm index 347451b4972..e9961c019cc 100644 --- a/code/modules/reagents/Chemistry-Goon-Medicine.dm +++ b/code/modules/reagents/Chemistry-Goon-Medicine.dm @@ -13,14 +13,16 @@ datum/reagent/goonchem/silver_sulfadiazine metabolization_rate = 2 datum/reagent/goonchem/silver_sulfadiazine/reaction_mob(var/mob/living/M as mob, var/method=TOUCH, var/volume, var/show_message = 1) - if(method == TOUCH) - M.adjustFireLoss(-volume) - if(show_message) - M << "You feel your burns healing!" - if(method == INGEST) - M.adjustToxLoss(0.5*volume) - if(show_message) - M << "You probably shouldn't have eaten that. Maybe you should of splashed it on, or applied a patch?" + if(iscarbon(M)) + if(method == TOUCH) + M.adjustFireLoss(-volume) + if(show_message) + M << "You feel your burns healing!" + M.emote("scream") + if(method == INGEST) + M.adjustToxLoss(0.5*volume) + if(show_message) + M << "You probably shouldn't have eaten that. Maybe you should of splashed it on, or applied a patch?" ..() return @@ -39,15 +41,16 @@ datum/reagent/goonchem/styptic_powder metabolization_rate = 2 datum/reagent/goonchem/styptic_powder/reaction_mob(var/mob/living/M as mob, var/method=TOUCH, var/volume, var/show_message = 1) - if(method == TOUCH) - M.adjustBruteLoss(-volume) - if(show_message) - M << "You feel your wounds knitting back together!" - M.emote("scream") - if(method == INGEST) - M.adjustToxLoss(0.5*volume) - if(show_message) - M << "You probably shouldn't have eaten that. Maybe you should of splashed it on, or applied a patch?" + if(iscarbon(M)) + if(method == TOUCH) + M.adjustBruteLoss(-volume) + if(show_message) + M << "You feel your wounds knitting back together!" + M.emote("scream") + if(method == INGEST) + M.adjustToxLoss(0.5*volume) + if(show_message) + M << "You probably shouldn't have eaten that. Maybe you should of splashed it on, or applied a patch?" ..() return @@ -82,11 +85,12 @@ datum/reagent/goonchem/synthflesh datum/reagent/goonchem/synthflesh/reaction_mob(var/mob/living/M, var/method=TOUCH, var/volume,var/show_message = 1) if(!M) M = holder.my_atom - if(method == TOUCH) - M.adjustBruteLoss(-1.5*volume) - M.adjustFireLoss(-1.5*volume) - if(show_message) - M << "You feel your burns healing and your flesh knitting together!" + if(iscarbon(M)) + if(method == TOUCH) + M.adjustBruteLoss(-1.5*volume) + M.adjustFireLoss(-1.5*volume) + if(show_message) + M << "You feel your burns healing and your flesh knitting together!" ..() return diff --git a/code/modules/reagents/Chemistry-Machinery.dm b/code/modules/reagents/Chemistry-Machinery.dm index a23de90b69c..496b6467887 100644 --- a/code/modules/reagents/Chemistry-Machinery.dm +++ b/code/modules/reagents/Chemistry-Machinery.dm @@ -922,6 +922,7 @@ obj/machinery/computer/pandemic/proc/replicator_cooldown(var/waittime) /obj/item/weapon/reagent_containers/food/snacks/grown/wheat = list("flour" = -5), /obj/item/weapon/reagent_containers/food/snacks/grown/oat = list("flour" = -5), /obj/item/weapon/reagent_containers/food/snacks/grown/cherries = list("cherryjelly" = 0), + /obj/item/weapon/reagent_containers/food/snacks/egg = list("eggyolk" = -5), //Grinder stuff, but only if dry /obj/item/weapon/reagent_containers/food/snacks/grown/coffee/arabica = list("coffeepowder" = 0), diff --git a/code/modules/reagents/Chemistry-Reagents/Consumable-Reagents/Drink-Reagents/Drinks.dm b/code/modules/reagents/Chemistry-Reagents/Consumable-Reagents/Drink-Reagents/Drinks.dm index 1afce1eda78..87496ff1a82 100644 --- a/code/modules/reagents/Chemistry-Reagents/Consumable-Reagents/Drink-Reagents/Drinks.dm +++ b/code/modules/reagents/Chemistry-Reagents/Consumable-Reagents/Drink-Reagents/Drinks.dm @@ -164,6 +164,11 @@ datum/reagent/consumable/coffee description = "Coffee is a brewed drink prepared from roasted seeds, commonly called coffee beans, of the coffee plant." color = "#482000" // rgb: 72, 32, 0 nutriment_factor = 0 + overdose_threshold = 80 + +datum/reagent/consumable/coffee/overdose_process(var/mob/living/M as mob) + M.Jitter(5) + ..() datum/reagent/consumable/coffee/on_mob_life(var/mob/living/M as mob) M.dizziness = max(0,M.dizziness-5) @@ -171,11 +176,9 @@ datum/reagent/consumable/coffee/on_mob_life(var/mob/living/M as mob) M.sleeping = max(0,M.sleeping - 2) if (M.bodytemperature < 310)//310 is the normal bodytemp. 310.055 M.bodytemperature = min(310, M.bodytemperature + (25 * TEMPERATURE_DAMAGE_COEFFICIENT)) - M.Jitter(5) if(holder.has_reagent("frostoil")) holder.remove_reagent("frostoil", 5) ..() - return datum/reagent/consumable/tea name = "Tea" diff --git a/code/modules/reagents/Chemistry-Reagents/Consumable-Reagents/Food-Reagents.dm b/code/modules/reagents/Chemistry-Reagents/Consumable-Reagents/Food-Reagents.dm index af9142cc216..42480f5a7ef 100644 --- a/code/modules/reagents/Chemistry-Reagents/Consumable-Reagents/Food-Reagents.dm +++ b/code/modules/reagents/Chemistry-Reagents/Consumable-Reagents/Food-Reagents.dm @@ -397,3 +397,9 @@ datum/reagent/consumable/vanilla reagent_state = SOLID nutriment_factor = 5 * REAGENTS_METABOLISM color = "#FFFACD" + +datum/reagent/consumable/eggyolk + name = "Egg Yolk" + id = "eggyolk" + description = "It's full of protein." + color = "#FFB500" diff --git a/code/modules/reagents/Chemistry-Recipes.dm b/code/modules/reagents/Chemistry-Recipes.dm index 1ee9283e34b..f5b4b6ed5fd 100644 --- a/code/modules/reagents/Chemistry-Recipes.dm +++ b/code/modules/reagents/Chemistry-Recipes.dm @@ -779,7 +779,7 @@ datum/chemical_reaction/pestkiller required_other = 1 /datum/chemical_reaction/slimeppotion/on_reaction(var/datum/reagents/holder) feedback_add_details("slime_cores_used","[replacetext(name," ","_")]") - var/obj/item/weapon/slimepotion/P = new /obj/item/weapon/slimepotion + var/obj/item/slimepotion/P = new /obj/item/slimepotion P.loc = get_turf(holder.my_atom) @@ -822,7 +822,7 @@ datum/chemical_reaction/pestkiller required_other = 1 /datum/chemical_reaction/slimepotion2/on_reaction(var/datum/reagents/holder) feedback_add_details("slime_cores_used","[replacetext(name," ","_")]") - var/obj/item/weapon/slimepotion2/P = new /obj/item/weapon/slimepotion2 + var/obj/item/slimepotion2/P = new /obj/item/slimepotion2 P.loc = get_turf(holder.my_atom) //Adamantine /datum/chemical_reaction/slimegolem diff --git a/code/modules/reagents/reagent_containers.dm b/code/modules/reagents/reagent_containers.dm index c0051eb3b8a..4803a311e33 100644 --- a/code/modules/reagents/reagent_containers.dm +++ b/code/modules/reagents/reagent_containers.dm @@ -77,21 +77,3 @@ return 0 return 1 - -/obj/item/weapon/reagent_containers/attackby(obj/item/weapon/W as obj, mob/user as mob, params) - if(istype(W,/obj/item/weapon/reagent_containers/food/snacks/egg)) //making dough - var/obj/item/weapon/reagent_containers/food/snacks/egg/E = W - if(flags & OPENCONTAINER) - if(reagents) - if(reagents.has_reagent("flour")) - if(reagents.get_reagent_amount("flour") >= 15) - var/obj/item/weapon/reagent_containers/food/snacks/S = new /obj/item/weapon/reagent_containers/food/snacks/dough(get_turf(src)) - user << "You mix egg and flour to make some dough." - reagents.remove_reagent("flour", 15) - if(E.reagents) - E.reagents.trans_to(S,E.reagents.total_volume) - qdel(E) - else - user << "Not enough flour to make dough." - return - ..() \ No newline at end of file diff --git a/code/modules/reagents/reagent_containers/glass.dm b/code/modules/reagents/reagent_containers/glass.dm index 7079ae6bf26..365ce4e9b70 100644 --- a/code/modules/reagents/reagent_containers/glass.dm +++ b/code/modules/reagents/reagent_containers/glass.dm @@ -80,6 +80,7 @@ user << "You transfer [trans] unit\s of the solution to [target]." //Safety for dumping stuff into a ninja suit. It handles everything through attackby() and this is unnecessary. //gee thanks noize + //NINJACODE else if(istype(target, /obj/item/clothing/suit/space/space_ninja)) return @@ -101,6 +102,17 @@ reagents.handle_reactions() else user << "[src] is already hotter than [I]." + + if(istype(I,/obj/item/weapon/reagent_containers/food/snacks/egg)) //breaking eggs + var/obj/item/weapon/reagent_containers/food/snacks/egg/E = I + if(reagents) + if(reagents.total_volume >= reagents.maximum_volume) + user << "[src] is full." + else + user << "You break [E] in [src]." + reagents.add_reagent("eggyolk", 5) + qdel(E) + return ..() diff --git a/code/modules/recycling/disposal.dm b/code/modules/recycling/disposal.dm index f70795a8737..b4d951cc78e 100644 --- a/code/modules/recycling/disposal.dm +++ b/code/modules/recycling/disposal.dm @@ -115,10 +115,6 @@ else return - if(istype(I, /obj/item/weapon/melee/energy/blade)) - user << "You can't place \the [I] into \the [src]." - return - if(istype(I, /obj/item/weapon/storage/bag/trash)) var/obj/item/weapon/storage/bag/trash/T = I user << " You empty the bag." @@ -131,15 +127,13 @@ var/obj/item/weapon/grab/G = I if(istype(G)) // handle grabbed mob if(ismob(G.affecting)) - stuff_mob_in(G.affecting, usr) + stuff_mob_in(G.affecting, user) return if(!I) return user.drop_item() - if(I) - I.loc = src - + I.loc = src user.visible_message("[user.name] places \the [I] into \the [src].", \ "You place \the [I] into \the [src].") @@ -147,12 +141,15 @@ // mouse drop another mob or self // -/obj/machinery/disposal/MouseDrop_T(mob/target, mob/user) - if(istype(target)) +/obj/machinery/disposal/MouseDrop_T(mob/living/target, mob/living/user) + if(istype(target) && user == target) stuff_mob_in(target, user) -/obj/machinery/disposal/proc/stuff_mob_in(mob/target, mob/user) - if (!user.canUseTopic(target) || istype(user, /mob/living/silicon/ai)) +/obj/machinery/disposal/proc/stuff_mob_in(mob/living/target, mob/living/user) + if(!iscarbon(user) && !user.ventcrawler) //only carbon and ventcrawlers can climb into disposal by themselves. + return + if(target.mob_size > 1) + user << "[target] doesn't fit inside [src]." return src.add_fingerprint(user) if(user == target) @@ -161,7 +158,7 @@ else target.visible_message("[user] starts putting [target] into [src].", \ "[user] starts putting [target] into [src]!") - if(do_mob(usr, target, 20)) + if(do_mob(user, target, 20)) if (target.client) target.client.perspective = EYE_PERSPECTIVE target.client.eye = src @@ -203,14 +200,12 @@ return -// monkeys can only pull the flush lever +// monkeys and xenos can only pull the flush lever /obj/machinery/disposal/attack_paw(mob/user as mob) if(stat & BROKEN) return - flush = !flush update() - return // ai as human but can't flush /obj/machinery/disposal/attack_ai(mob/user as mob) @@ -485,7 +480,6 @@ var/active = 0 // true if the holder is moving, otherwise inactive dir = 0 var/count = 1000 //*** can travel 1000 steps before going inactive (in case of loops) - var/has_fat_guy = 0 // true if contains a fat person var/destinationTag = 0 // changes if contains a delivery container var/tomail = 0 //changes if contains wrapped package var/hasmob = 0 //If it contains a mob @@ -502,7 +496,7 @@ //Check for any living mobs trigger hasmob. //hasmob effects whether the package goes to cargo or its tagged destination. for(var/mob/living/M in D) - if(M && M.stat != 2) + if(M && M.stat != DEAD) hasmob = 1 //Checks 1 contents level deep. This means that players can be sent through disposals... @@ -510,17 +504,13 @@ for(var/obj/O in D) if(O.contents) for(var/mob/living/M in O.contents) - if(M && M.stat != 2) + if(M && M.stat != DEAD) hasmob = 1 // now everything inside the disposal gets put into the holder // note AM since can contain mobs or objs for(var/atom/movable/AM in D) AM.loc = src - if(istype(AM, /mob/living/carbon/human)) - var/mob/living/carbon/human/H = AM - if(H.disabilities & FAT) // is a human and fat? - has_fat_guy = 1 // set flag on holder if(istype(AM, /obj/structure/bigDelivery) && !hasmob) var/obj/structure/bigDelivery/T = AM src.destinationTag = T.sortTag @@ -587,9 +577,6 @@ var/mob/M = AM if(M.client) // if a client mob, update eye to follow this holder M.client.eye = src - - if(other.has_fat_guy) - has_fat_guy = 1 qdel(other) @@ -869,14 +856,15 @@ // called when pipe is cut with welder /obj/structure/disposalpipe/Deconstruct() - var/turf/T = loc - stored.loc = T - transfer_fingerprints_to(stored) - stored.dir = dir - stored.density = 0 - stored.anchored = 1 - stored.update() - ..() + if(stored) + var/turf/T = loc + stored.loc = T + transfer_fingerprints_to(stored) + stored.dir = dir + stored.density = 0 + stored.anchored = 1 + stored.update() + ..() /obj/structure/disposalpipe/singularity_pull(S, current_size) if(current_size >= STAGE_FIVE) @@ -1212,13 +1200,10 @@ update() return -// called when welded -// for broken pipe, remove and turn into scrap +// the disposal outlet machine /obj/structure/disposalpipe/broken/Deconstruct() - ..() - -// the disposal outlet machine + qdel(src) /obj/structure/disposaloutlet name = "disposal outlet" diff --git a/code/modules/research/designs/machine_designs.dm b/code/modules/research/designs/machine_designs.dm index ff5e33b0ef3..120963be22c 100644 --- a/code/modules/research/designs/machine_designs.dm +++ b/code/modules/research/designs/machine_designs.dm @@ -6,7 +6,7 @@ name = "Machine Design (SMES Board)" desc = "The circuit board for a SMES." id = "smes" - req_tech = list("programming" = 4, "power" = 5, "engineering" = 4) + req_tech = list("programming" = 4, "powerstorage" = 5, "engineering" = 4) build_type = IMPRINTER materials = list("$glass" = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/smes @@ -16,7 +16,7 @@ name = "Computer Design (Power Turbine Console Board)" desc = "The circuit board for a power turbine console." id = "power_turbine_console" - req_tech = list("programming" = 4, "power" = 4, "engineering" = 4) + req_tech = list("programming" = 4, "powerstorage" = 4, "engineering" = 4) build_type = IMPRINTER materials = list("$glass" = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/turbine_computer @@ -26,7 +26,7 @@ name = "Machine Design (Power Compressor Board)" desc = "The circuit board for a power compressor." id = "power_compressor" - req_tech = list("programming" = 4, "power" = 5, "engineering" = 4) + req_tech = list("programming" = 4, "powerstorage" = 5, "engineering" = 4) build_type = IMPRINTER materials = list("$glass" = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/power_compressor @@ -36,7 +36,7 @@ name = "Machine Design (Power Turbine Board)" desc = "The circuit board for a power turbine." id = "power_turbine" - req_tech = list("programming" = 4, "power" = 4, "engineering" = 5) + req_tech = list("programming" = 4, "powerstorage" = 4, "engineering" = 5) build_type = IMPRINTER materials = list("$glass" = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/power_turbine diff --git a/code/modules/research/designs/mechfabricator_designs.dm b/code/modules/research/designs/mechfabricator_designs.dm index b04f53bdff7..6c08a097ce2 100644 --- a/code/modules/research/designs/mechfabricator_designs.dm +++ b/code/modules/research/designs/mechfabricator_designs.dm @@ -640,7 +640,7 @@ id = "borg_upgrade_disablercooler" build_type = MECHFAB build_path = /obj/item/borg/upgrade/disablercooler - req_tech = list("combat" = 5, "power" = 4) + req_tech = list("combat" = 5, "powerstorage" = 4) materials = list("$metal"=80000 , "$glass"=6000 , "$gold"= 2000, "$diamond" = 500) construction_time = 120 category = list("Cyborg Upgrade Modules") @@ -650,7 +650,7 @@ id = "borg_upgrade_jetpack" build_type = MECHFAB build_path = /obj/item/borg/upgrade/jetpack - req_tech = list("engineering" = 4, "power" = 4) + req_tech = list("engineering" = 4, "powerstorage" = 4) materials = list("$metal"=10000, "$plasma"=5000, "$uranium" = 6000) construction_time = 120 category = list("Cyborg Upgrade Modules") diff --git a/code/modules/research/designs/weapon_designs.dm b/code/modules/research/designs/weapon_designs.dm index 62aca6fca2a..42fcc6c1b1f 100644 --- a/code/modules/research/designs/weapon_designs.dm +++ b/code/modules/research/designs/weapon_designs.dm @@ -16,7 +16,7 @@ name = "loyalty firing pin" desc = "This is a security firing pin which only authorizes users who are loyalty-implanted." id = "pin_loyalty" - req_tech = list("combat" = 10, "materials" = 3, "powerstorage" = 3) + req_tech = list("combat" = 6, "materials" = 6, "powerstorage" = 3) build_type = PROTOLATHE materials = list("$silver" = 600, "$diamond" = 600, "$uranium" = 200) build_path = /obj/item/device/firing_pin/implant/loyalty diff --git a/code/modules/surgery/cavity_implant.dm b/code/modules/surgery/cavity_implant.dm index 72223b4716f..289dadeec2d 100644 --- a/code/modules/surgery/cavity_implant.dm +++ b/code/modules/surgery/cavity_implant.dm @@ -25,7 +25,7 @@ /datum/surgery_step/handle_cavity/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) if(tool) - if(IC || tool.w_class > 3 || tool.GetTypeInAllContents(/obj/item/weapon/disk/nuclear) || istype(tool, /obj/item/weapon/disk/nuclear) || istype(tool, /obj/item/organ)) + if(IC || tool.w_class > 3 || NODROP in tool.flags || tool.GetTypeInAllContents(/obj/item/weapon/disk/nuclear) || istype(tool, /obj/item/weapon/disk/nuclear) || istype(tool, /obj/item/organ)) user.visible_message("[user] can't seem to fit [tool] in [target]'s [target_zone].") return 0 else diff --git a/code/modules/surgery/organs/organ.dm b/code/modules/surgery/organs/organ.dm index 264f6482ca0..df88239994d 100644 --- a/code/modules/surgery/organs/organ.dm +++ b/code/modules/surgery/organs/organ.dm @@ -170,7 +170,7 @@ return 0 //Returns a display name for the organ -/obj/item/organ/limb/proc/getDisplayName() //Added "Chest" and "Head" just in case, this may not be needed - RR. +/obj/item/organ/limb/proc/getDisplayName() //Added "Chest" and "Head" just in case, this may not be needed switch(name) if("l_leg") return "left leg" if("r_leg") return "right leg" @@ -181,3 +181,11 @@ else return name +//Remove all embedded objects from all limbs on the human mob +/mob/living/carbon/human/proc/remove_all_embedded_objects() + var/turf/T = get_turf(src) + + for(var/obj/item/organ/limb/L in organs) + for(var/obj/item/I in L.embedded_objects) + L.embedded_objects -= I + I.loc = T \ No newline at end of file diff --git a/code/world.dm b/code/world.dm index 1b0a3d17072..182130a4ce2 100644 --- a/code/world.dm +++ b/code/world.dm @@ -129,11 +129,11 @@ if(input["key"] != global.comms_key) return "Bad Key" else - #define CHAT_PULLR 2048 +#define CHAT_PULLR 64 //for some reason this has to be here, not sure why. Look in preferences.dm for the "proper" definition. for(var/client/C in clients) - if(C.prefs && (C.prefs.toggles & CHAT_PULLR)) + if(C.prefs && (C.prefs.chat_toggles & CHAT_PULLR)) C << "PR: [input["announce"]]" - #undef CHAT_PULLR +#undef CHAT_PULLR /world/Reboot(var/reason) #ifdef dellogging diff --git a/config/admins.txt b/config/admins.txt index e263284f00a..aff7eb7fb37 100644 --- a/config/admins.txt +++ b/config/admins.txt @@ -78,4 +78,5 @@ xerux = Game Master dannno = Game Master allura = Game Master lo6a4evskiy = Game Master -vekter = Game Master \ No newline at end of file +vekter = Game Master +Ahammer18 = Game Master \ No newline at end of file diff --git a/config/game_options.txt b/config/game_options.txt index 5eb663273b2..84b6750c697 100644 --- a/config/game_options.txt +++ b/config/game_options.txt @@ -226,4 +226,12 @@ ASSISTANT_CAP -1 STARLIGHT ## Uncomment to bring back old grey suit assistants instead of the now default rainbow colored assistants. -#GREY_ASSISTANTS \ No newline at end of file +#GREY_ASSISTANTS + +### Midround Antag (aka Mulligan antag) config options ### + +## A time, in minutes, after which the midround antag system stops attempting to run and continuous rounds end immediately upon completion. +MIDROUND_ANTAG_TIME_CHECK 60 + +## A ratio of living to total crew members, the lower this is, the more people will have to die in order for midround antag to be skipped +MIDROUND_ANTAG_LIFE_CHECK 0.7 \ No newline at end of file diff --git a/html/changelog.html b/html/changelog.html index b5402b795e0..4978c9b7418 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -55,6 +55,57 @@ -->
      +

      11 March 2015

      +

      MMMiracles updated:

      +
        +
      • Adds a new vending machine, the Liberation Station. Consult your local patriot for more details.
      • +
      • Adds a patriotic jumpsuit and freedom sheets. Consult your local patriot for more details.
      • +
      +

      Miauw updated:

      +
        +
      • Added a toggle for ghosts that allows them to hear radio chatter without having to hover near intercoms/over people with headsets.
      • +
      + +

      10 March 2015

      +

      Ahammer18 updated:

      +
        +
      • Adds the Slimecake and Slimecake slice.
      • +
      +

      AnturK updated:

      +
        +
      • Non-player Alien Queens/Drones now spread weeds. Can also lay eggs when enabled.
      • +
      +

      Incoming5643 updated:

      +
        +
      • Nanotrasen scientists have recently reported mutations within the pink family line of slimes. Station scientists are encouraged to investigate.
      • +
      +

      Paprika updated:

      +
        +
      • Reworked reskinning and renaming guns, and added the ability to reskin the bartender's shotgun. Click it with an empty active hand to reskin. Warning, you can only do this once! Rename by hitting it with a pen. This also works with miner shotguns now.
      • +
      +

      RemieRichards updated:

      +
        +
      • Embedding from explosions has been tweaked, they will always throw objects fast enough to get embedded if they can.
      • +
      • Damage taken when embedded spears and throwing stars fall out has been increased.
      • +
      • Damage dealt by objects getting embedded has been decreased.
      • +
      +

      Sometinyprick updated:

      +
        +
      • The Horsemask spell has now been altered, instead of just a horse mask it will now choose between three animal masks including the horse mask.
      • +
      +

      Xhuis updated:

      +
        +
      • You can now burn papers using lighters, welders, or matches. Useful for secret messages.
      • +
      +

      phil235 updated:

      +
        +
      • Airlocks with their safety on no longer closes on dense objects (like mechs or tables).
      • +
      • Aliens, slimes, monkeys and ventcrawler mobs can now climb into disposal. Cyborgs and very large mobs can no longer climb into it.
      • +
      • Stuffing another mob in a disposal unit is now only done via grabbing.
      • +
      • Coffee now causes jittering only when you overdose on it.
      • +
      • Turrets now target occupied mechs and don't target drones.
      • +
      +

      08 March 2015

      Dannno updated:

        diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml index 4f25bdf7b6b..b91c3d3fa55 100644 --- a/html/changelogs/.all_changelog.yml +++ b/html/changelogs/.all_changelog.yml @@ -1694,3 +1694,46 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py. - imageadd: Updated the sprite for Fire extinguishers. xxalpha: - imageadd: Disposable lighters now come in more colors of the rainbow. +2015-03-10: + Ahammer18: + - rscadd: Adds the Slimecake and Slimecake slice. + AnturK: + - rscadd: Non-player Alien Queens/Drones now spread weeds. Can also lay eggs when + enabled. + Incoming5643: + - rscadd: Nanotrasen scientists have recently reported mutations within the pink + family line of slimes. Station scientists are encouraged to investigate. + Paprika: + - tweak: Reworked reskinning and renaming guns, and added the ability to reskin + the bartender's shotgun. Click it with an empty active hand to reskin. Warning, + you can only do this once! Rename by hitting it with a pen. This also works + with miner shotguns now. + RemieRichards: + - wip: Embedding from explosions has been tweaked, they will always throw objects + fast enough to get embedded if they can. + - tweak: Damage taken when embedded spears and throwing stars fall out has been + increased. + - tweak: Damage dealt by objects getting embedded has been decreased. + Sometinyprick: + - rscadd: The Horsemask spell has now been altered, instead of just a horse mask + it will now choose between three animal masks including the horse mask. + Xhuis: + - rscadd: You can now burn papers using lighters, welders, or matches. Useful for + secret messages. + phil235: + - rscadd: Airlocks with their safety on no longer closes on dense objects (like + mechs or tables). + - tweak: Aliens, slimes, monkeys and ventcrawler mobs can now climb into disposal. + Cyborgs and very large mobs can no longer climb into it. + - tweak: Stuffing another mob in a disposal unit is now only done via grabbing. + - rscadd: Coffee now causes jittering only when you overdose on it. + - bugfix: Turrets now target occupied mechs and don't target drones. +2015-03-11: + MMMiracles: + - rscadd: Adds a new vending machine, the Liberation Station. Consult your local + patriot for more details. + - rscadd: Adds a patriotic jumpsuit and freedom sheets. Consult your local patriot + for more details. + Miauw: + - rscadd: Added a toggle for ghosts that allows them to hear radio chatter without + having to hover near intercoms/over people with headsets. diff --git a/html/changelogs/Ahammer18 - Droneasses.yml b/html/changelogs/Ahammer18 - Droneasses.yml new file mode 100644 index 00000000000..fdb0a277acd --- /dev/null +++ b/html/changelogs/Ahammer18 - Droneasses.yml @@ -0,0 +1,5 @@ +author: Ahammer18 +delete-after: true + +changes: + - rscadd: "added drone asses" diff --git a/html/changelogs/Gun_Hog-LoyaltyPins.yml b/html/changelogs/Gun_Hog-LoyaltyPins.yml new file mode 100644 index 00000000000..1d310521b39 --- /dev/null +++ b/html/changelogs/Gun_Hog-LoyaltyPins.yml @@ -0,0 +1,7 @@ + +author: Gun Hog + +delete-after: True + +changes: + - rscadd: "Nanotrasen has approved distribution of Loyalty Implant Firing Pin designs. They can be fabricated with sufficient research into weapons technology. If inserted into a firearm, it will only fire upon successful interface with a user's Loyalty Implant." diff --git a/html/changelogs/Incoming5643-magicmirror.yml b/html/changelogs/Incoming5643-magicmirror.yml new file mode 100644 index 00000000000..aad4ce79883 --- /dev/null +++ b/html/changelogs/Incoming5643-magicmirror.yml @@ -0,0 +1,9 @@ +################################ + + +author: Incoming5643 + +delete-after: True + +changes: + - rscadd: "Utilizing a new magic mirror found in the den, wizards can now customize their appearance to a high degree before descending upon the station." diff --git a/html/changelogs/phil235-DoughChange.yml b/html/changelogs/phil235-DoughChange.yml new file mode 100644 index 00000000000..db83d37a729 --- /dev/null +++ b/html/changelogs/phil235-DoughChange.yml @@ -0,0 +1,6 @@ +author: phil235 +delete-after: True +changes: + - rscadd: "Adds egg yolk reagent. You can break eggs in open reagent containers or blend them to get egg yolk." + - tweak: "Changes how doughs are made. 10water+15flour chem reaction for dough. 15flour+15eggyolk+5sugar for cake batter (or alternatively soymilk instead of the eggyolk for vegans)." + - tweak: "Change customizable snack max volume to 60 and buffs nutriment amount in doughs." \ No newline at end of file diff --git a/html/changelogs/phil235-TablecraftFix.yml b/html/changelogs/phil235-TablecraftFix.yml new file mode 100644 index 00000000000..123f9e75f55 --- /dev/null +++ b/html/changelogs/phil235-TablecraftFix.yml @@ -0,0 +1,6 @@ +author: phil235 + +delete-after: True + +changes: + - rscadd: "The tablecrafting window now also shows partial recipes in grey, if there's some of the things required for the recipe on the table. Recipe requirements are now also shown next to the names of recipes listed in the window." diff --git a/html/create_object.html b/html/create_object.html index aa36cad8163..f4e0aa8644c 100644 --- a/html/create_object.html +++ b/html/create_object.html @@ -27,7 +27,7 @@
        - Type
        + Type
        Offset: A diff --git a/icons/Chrono_Legionairre.dmi b/icons/Chrono_Legionairre.dmi deleted file mode 100644 index 77f8bdfeeeb..00000000000 Binary files a/icons/Chrono_Legionairre.dmi and /dev/null differ diff --git a/icons/ass/assdrone.png b/icons/ass/assdrone.png new file mode 100644 index 00000000000..748d207ff93 Binary files /dev/null and b/icons/ass/assdrone.png differ diff --git a/icons/mob/back.dmi b/icons/mob/back.dmi index 4570042ccba..b35a33aa5c4 100644 Binary files a/icons/mob/back.dmi and b/icons/mob/back.dmi differ diff --git a/icons/mob/belt.dmi b/icons/mob/belt.dmi index 459051e1c73..140bca9a4b2 100644 Binary files a/icons/mob/belt.dmi and b/icons/mob/belt.dmi differ diff --git a/icons/mob/inhands/items_lefthand.dmi b/icons/mob/inhands/items_lefthand.dmi index b7eb6f96670..ed3c4def4d4 100644 Binary files a/icons/mob/inhands/items_lefthand.dmi and b/icons/mob/inhands/items_lefthand.dmi differ diff --git a/icons/mob/inhands/items_righthand.dmi b/icons/mob/inhands/items_righthand.dmi index d6492bd957e..4263a4a40a6 100644 Binary files a/icons/mob/inhands/items_righthand.dmi and b/icons/mob/inhands/items_righthand.dmi differ diff --git a/icons/mob/mask.dmi b/icons/mob/mask.dmi index 8459b715b44..1fab40186a8 100644 Binary files a/icons/mob/mask.dmi and b/icons/mob/mask.dmi differ diff --git a/icons/mob/suit.dmi b/icons/mob/suit.dmi index 5df1911eb35..ead9c0f14ba 100644 Binary files a/icons/mob/suit.dmi and b/icons/mob/suit.dmi differ diff --git a/icons/mob/uniform.dmi b/icons/mob/uniform.dmi index 1d690ffd463..271ef078024 100644 Binary files a/icons/mob/uniform.dmi and b/icons/mob/uniform.dmi differ diff --git a/icons/obj/bureaucracy.dmi b/icons/obj/bureaucracy.dmi index 9c293950b7e..5ad94298551 100644 Binary files a/icons/obj/bureaucracy.dmi and b/icons/obj/bureaucracy.dmi differ diff --git a/icons/obj/clothing/suits.dmi b/icons/obj/clothing/suits.dmi index a3be493d9c3..d94332944a2 100644 Binary files a/icons/obj/clothing/suits.dmi and b/icons/obj/clothing/suits.dmi differ diff --git a/icons/obj/clothing/uniforms.dmi b/icons/obj/clothing/uniforms.dmi index 417d6049b2c..dcdb7691b5c 100644 Binary files a/icons/obj/clothing/uniforms.dmi and b/icons/obj/clothing/uniforms.dmi differ diff --git a/icons/obj/food.dmi b/icons/obj/food.dmi index 9b05ea1d2ce..780b0bcc06e 100644 Binary files a/icons/obj/food.dmi and b/icons/obj/food.dmi differ diff --git a/icons/obj/guns/projectile.dmi b/icons/obj/guns/projectile.dmi index fe8cd6434d3..39b46c7806e 100644 Binary files a/icons/obj/guns/projectile.dmi and b/icons/obj/guns/projectile.dmi differ diff --git a/icons/obj/items.dmi b/icons/obj/items.dmi index 368336a106d..ab9b69c469f 100644 Binary files a/icons/obj/items.dmi and b/icons/obj/items.dmi differ diff --git a/icons/obj/library.dmi b/icons/obj/library.dmi index a1610b9e284..e15935f6ff3 100644 Binary files a/icons/obj/library.dmi and b/icons/obj/library.dmi differ diff --git a/icons/obj/vending.dmi b/icons/obj/vending.dmi index 2d23a9a9b4d..91d53ce1dfd 100644 Binary files a/icons/obj/vending.dmi and b/icons/obj/vending.dmi differ diff --git a/icons/obj/watercloset.dmi b/icons/obj/watercloset.dmi index 2b0a66d9ac5..e31bb79d247 100644 Binary files a/icons/obj/watercloset.dmi and b/icons/obj/watercloset.dmi differ diff --git a/icons/obj/weapons.dmi b/icons/obj/weapons.dmi index 3bedbd10ad3..3ffe470d625 100644 Binary files a/icons/obj/weapons.dmi and b/icons/obj/weapons.dmi differ diff --git a/icons/turf/floors.dmi b/icons/turf/floors.dmi index 75a11015b5f..9894e89c626 100644 Binary files a/icons/turf/floors.dmi and b/icons/turf/floors.dmi differ diff --git a/tgstation.dme b/tgstation.dme index a74a3ce7694..1e275010267 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -217,6 +217,7 @@ #include "code\datums\helper_datums\teleport.dm" #include "code\datums\helper_datums\topic_input.dm" #include "code\datums\spells\area_teleport.dm" +#include "code\datums\spells\barnyard.dm" #include "code\datums\spells\charge.dm" #include "code\datums\spells\conjure.dm" #include "code\datums\spells\construct_spells.dm" @@ -225,7 +226,6 @@ #include "code\datums\spells\ethereal_jaunt.dm" #include "code\datums\spells\explosion.dm" #include "code\datums\spells\genetic.dm" -#include "code\datums\spells\horsemask.dm" #include "code\datums\spells\inflict_handler.dm" #include "code\datums\spells\knock.dm" #include "code\datums\spells\mime.dm" @@ -850,7 +850,6 @@ #include "code\modules\clothing\gloves\boxing.dm" #include "code\modules\clothing\gloves\color.dm" #include "code\modules\clothing\gloves\miscellaneous.dm" -#include "code\modules\clothing\gloves\ninja.dm" #include "code\modules\clothing\head\collectable.dm" #include "code\modules\clothing\head\hardhat.dm" #include "code\modules\clothing\head\helmet.dm" @@ -869,7 +868,6 @@ #include "code\modules\clothing\spacesuits\chronosuit.dm" #include "code\modules\clothing\spacesuits\hardsuit.dm" #include "code\modules\clothing\spacesuits\miscellaneous.dm" -#include "code\modules\clothing\spacesuits\ninja.dm" #include "code\modules\clothing\spacesuits\syndi.dm" #include "code\modules\clothing\suits\armor.dm" #include "code\modules\clothing\suits\bio.dm" @@ -919,7 +917,6 @@ #include "code\modules\events\mass_hallucination.dm" #include "code\modules\events\meateor_wave.dm" #include "code\modules\events\meteor_wave.dm" -#include "code\modules\events\ninja.dm" #include "code\modules\events\prison_break.dm" #include "code\modules\events\radiation_storm.dm" #include "code\modules\events\shuttle_loan.dm" @@ -985,7 +982,6 @@ #include "code\modules\food&drinks\recipes\tablecraft\recipes_bread.dm" #include "code\modules\food&drinks\recipes\tablecraft\recipes_burger.dm" #include "code\modules\food&drinks\recipes\tablecraft\recipes_cake.dm" -#include "code\modules\food&drinks\recipes\tablecraft\recipes_dough.dm" #include "code\modules\food&drinks\recipes\tablecraft\recipes_egg.dm" #include "code\modules\food&drinks\recipes\tablecraft\recipes_meat.dm" #include "code\modules\food&drinks\recipes\tablecraft\recipes_misc.dm" @@ -1230,6 +1226,30 @@ #include "code\modules\nano\nanoexternal.dm" #include "code\modules\nano\nanomanager.dm" #include "code\modules\nano\nanoui.dm" +#include "code\modules\ninja\__ninjaDefines.dm" +#include "code\modules\ninja\admin_ninja_verbs.dm" +#include "code\modules\ninja\energy_katana.dm" +#include "code\modules\ninja\ninja_event.dm" +#include "code\modules\ninja\Ninja_Readme.dm" +#include "code\modules\ninja\suit\gloves.dm" +#include "code\modules\ninja\suit\head.dm" +#include "code\modules\ninja\suit\mask.dm" +#include "code\modules\ninja\suit\shoes.dm" +#include "code\modules\ninja\suit\SpiderOS.dm" +#include "code\modules\ninja\suit\suit.dm" +#include "code\modules\ninja\suit\suit_attackby.dm" +#include "code\modules\ninja\suit\suit_initialisation.dm" +#include "code\modules\ninja\suit\suit_process.dm" +#include "code\modules\ninja\suit\suit_verbs_handlers.dm" +#include "code\modules\ninja\suit\n_suit_verbs\energy_net_nets.dm" +#include "code\modules\ninja\suit\n_suit_verbs\ninja_adrenaline.dm" +#include "code\modules\ninja\suit\n_suit_verbs\ninja_cost_check.dm" +#include "code\modules\ninja\suit\n_suit_verbs\ninja_empulse.dm" +#include "code\modules\ninja\suit\n_suit_verbs\ninja_net.dm" +#include "code\modules\ninja\suit\n_suit_verbs\ninja_smoke.dm" +#include "code\modules\ninja\suit\n_suit_verbs\ninja_stars.dm" +#include "code\modules\ninja\suit\n_suit_verbs\ninja_stealth.dm" +#include "code\modules\ninja\suit\n_suit_verbs\ninja_teleporting.dm" #include "code\modules\paperwork\clipboard.dm" #include "code\modules\paperwork\filingcabinet.dm" #include "code\modules\paperwork\folders.dm"
Syndicates