Merge pull request #8 from quotefox/master

a
This commit is contained in:
shellspeed1
2019-12-20 21:59:43 -08:00
committed by GitHub
120 changed files with 2414 additions and 334 deletions
+9 -10
View File
@@ -614,7 +614,7 @@
"alP" = (/obj/machinery/light/small{dir = 8},/obj/machinery/button/door{desc = "A remote control switch for the medbay foyer."; id = "outerbrig"; name = "Brig Exterior Doors Control"; normaldoorcontrol = 1; pixel_x = -26; pixel_y = -5; req_access_txt = "63"},/obj/machinery/button/door{desc = "A remote control switch for the medbay foyer."; id = "innerbrig"; name = "Brig Interior Doors Control"; normaldoorcontrol = 1; pixel_x = -26; pixel_y = 5; req_access_txt = "63"},/obj/structure/cable{icon_state = "1-2"},/turf/open/floor/plasteel/dark,/area/security/brig)
"alQ" = (/obj/structure/chair/office/dark{dir = 4},/turf/open/floor/plasteel/dark,/area/security/brig)
"alR" = (/obj/structure/table/reinforced,/obj/machinery/door/poddoor/shutters/preopen{id = "briggate"; name = "security shutters"},/obj/machinery/door/window/eastright{name = "Brig Desk"; req_access_txt = "2"},/obj/item/restraints/handcuffs,/obj/item/radio/off,/turf/open/floor/plasteel/dark,/area/security/brig)
"alS" = (/obj/effect/turf_decal/tile/blue{dir = 4},/obj/effect/turf_decal/loading_area{dir = 1; icon_state = "drain"; name = "drain"},/obj/structure/medkit_cabinet{pixel_y = 27},/obj/effect/turf_decal/loading_area{name = "steel pannel"; icon_state = "steel_panel"; dir = 10},/turf/open/floor/plasteel,/area/hallway/primary/central)
"alS" = (/obj/machinery/door/airlock/public/glass{dir = 4; name = "Cryogenics "},/obj/structure/cable{icon_state = "4-8"},/obj/machinery/door/firedoor,/turf/open/floor/plasteel,/area/crew_quarters/cryopod)
"alT" = (/obj/structure/closet/secure_closet/brig{id = "Cell 4"; name = "Cell 4 Locker"},/turf/open/floor/plasteel,/area/security/brig)
"alU" = (/obj/machinery/atmospherics/components/unary/vent_scrubber/on{dir = 1},/turf/open/floor/plasteel,/area/security/brig)
"alV" = (/obj/structure/bed,/obj/item/bedsheet,/obj/item/radio/intercom{desc = "Talk through this. It looks like it has been modified to not broadcast."; dir = 2; name = "Prison Intercom (General)"; pixel_x = 25; pixel_y = -2; prison_radio = 1},/turf/open/floor/plasteel,/area/security/brig)
@@ -1520,7 +1520,7 @@
"aDl" = (/obj/machinery/cryopod{dir = 4},/turf/open/floor/carpet,/area/crew_quarters/cryopod)
"aDm" = (/obj/machinery/atmospherics/components/unary/vent_scrubber/on{dir = 4},/turf/open/floor/carpet,/area/crew_quarters/cryopod)
"aDn" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/turf/open/floor/carpet,/area/crew_quarters/cryopod)
"aDo" = (/obj/machinery/door/airlock/public/glass{name = "Cryogenics "},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/obj/machinery/door/firedoor,/obj/machinery/door/firedoor,/turf/open/floor/plasteel,/area/crew_quarters/cryopod)
"aDo" = (/obj/machinery/door/airlock/public/glass{dir = 4; name = "Cryogenics "},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/obj/machinery/door/firedoor,/obj/machinery/door/firedoor,/turf/open/floor/plasteel,/area/crew_quarters/cryopod)
"aDp" = (/obj/machinery/atmospherics/pipe/manifold4w/scrubbers/hidden,/obj/effect/turf_decal/tile/neutral,/obj/effect/turf_decal/tile/neutral{dir = 4},/obj/machinery/camera{c_tag = "Dormitory South"; dir = 8},/turf/open/floor/plasteel,/area/crew_quarters/dorms)
"aDq" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/turf/closed/wall,/area/crew_quarters/toilet)
"aDr" = (/obj/structure/sink{dir = 8; pixel_x = -12; pixel_y = 2},/obj/structure/sink{dir = 8; pixel_x = -12; pixel_y = 2},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/obj/structure/cable{icon_state = "2-4"},/obj/effect/turf_decal/loading_area{dir = 8; icon_state = "drain"; name = "drain"},/turf/open/floor/plasteel/freezer,/area/crew_quarters/toilet)
@@ -1588,7 +1588,7 @@
"aEB" = (/obj/machinery/light/small{dir = 8},/turf/open/floor/plasteel/dark,/area/ai_monitored/storage/eva)
"aEC" = (/obj/structure/cable{icon_state = "2-4"},/turf/open/floor/carpet,/area/crew_quarters/cryopod)
"aED" = (/obj/structure/cable{icon_state = "4-8"},/turf/open/floor/carpet,/area/crew_quarters/cryopod)
"aEE" = (/obj/machinery/door/airlock/public/glass{name = "Cryogenics "},/obj/structure/cable{icon_state = "4-8"},/obj/machinery/door/firedoor,/turf/open/floor/plasteel,/area/crew_quarters/cryopod)
"aEE" = (/obj/effect/turf_decal/tile/blue{dir = 4},/obj/effect/turf_decal/loading_area{dir = 1; icon_state = "drain"; name = "drain"},/obj/structure/medkit_cabinet{pixel_y = 27},/turf/open/floor/plasteel,/area/hallway/primary/central)
"aEF" = (/obj/machinery/atmospherics/pipe/manifold/supply/hidden{dir = 8},/obj/effect/turf_decal/tile/neutral{dir = 1},/obj/effect/turf_decal/tile/neutral{dir = 8},/obj/structure/cable{icon_state = "4-8"},/turf/open/floor/plasteel,/area/crew_quarters/dorms)
"aEG" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/obj/effect/turf_decal/tile/neutral,/obj/effect/turf_decal/tile/neutral{dir = 4},/obj/structure/cable{icon_state = "4-8"},/turf/open/floor/plasteel,/area/crew_quarters/dorms)
"aEH" = (/obj/machinery/door/airlock{dir = 4; name = "Unisex Restrooms"},/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/obj/structure/cable{icon_state = "4-8"},/turf/open/floor/plasteel/freezer,/area/crew_quarters/toilet)
@@ -1881,7 +1881,7 @@
"aKi" = (/obj/effect/turf_decal/tile/red,/obj/effect/turf_decal/tile/blue{dir = 8},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 9},/turf/open/floor/plasteel,/area/crew_quarters/theatre)
"aKj" = (/obj/effect/turf_decal/tile/red,/obj/effect/turf_decal/tile/blue{dir = 8},/obj/machinery/atmospherics/pipe/simple/supply/hidden,/turf/open/floor/plasteel,/area/crew_quarters/theatre)
"aKk" = (/obj/effect/turf_decal/tile/red,/obj/effect/turf_decal/tile/blue{dir = 8},/obj/structure/cable{icon_state = "1-2"},/obj/machinery/vending/autodrobe,/turf/open/floor/plasteel,/area/crew_quarters/theatre)
"aKl" = (/obj/effect/turf_decal/loading_area{name = "steel pannel"; icon_state = "steel_panel"; dir = 10},/turf/open/floor/plasteel,/area/hallway/primary/central)
"aKl" = (/obj/effect/turf_decal/loading_area{dir = 2; icon_state = "drain"; name = "drain"},/obj/structure/cable{icon_state = "4-8"},/turf/open/floor/plasteel,/area/hallway/primary/central)
"aKm" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/obj/effect/turf_decal/bot{dir = 2},/obj/structure/cable{icon_state = "1-2"},/turf/closed/wall,/area/maintenance/starboard/fore)
"aKn" = (/obj/structure/table/reinforced,/obj/item/storage/secure/briefcase,/obj/item/storage/box/PDAs{pixel_x = 4; pixel_y = 4},/obj/item/storage/box/ids,/turf/open/floor/plasteel,/area/bridge)
"aKo" = (/obj/machinery/light{dir = 1; pixel_y = 16},/turf/open/floor/wood,/area/crew_quarters/bar)
@@ -2544,7 +2544,6 @@
"aWV" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 5},/turf/open/floor/carpet,/area/chapel/main)
"aWW" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/obj/machinery/atmospherics/pipe/simple/supply/hidden,/turf/open/floor/carpet,/area/chapel/main)
"aWX" = (/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{dir = 1},/turf/open/floor/carpet,/area/chapel/main)
"aWY" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/public/glass{dir = 4; name = "Chapel"},/turf/open/floor/carpet,/area/chapel/main)
"aWZ" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/obj/effect/turf_decal/tile/red{dir = 8},/turf/open/floor/plasteel/white/corner{dir = 1},/area/hallway/secondary/exit)
"aXa" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/turf/open/floor/plasteel,/area/hallway/secondary/exit)
"aXb" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/obj/machinery/atmospherics/pipe/simple/supply/hidden,/obj/effect/landmark/event_spawn,/turf/open/floor/plasteel,/area/hallway/secondary/exit)
@@ -7059,20 +7058,20 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaauSaAaauSaAbaxyayUaAcaAdaAeaAfayUaxyaAbayUauSaAgaAhalzaAiaAjaAkaAkaAkaAlazcaAmaAnaAoaApaAqaAraAmazcaAsaAtaAuaAvaAvaAvaAvaAvaAwarYaxSaadaAxaAxaAyaAxaAzaAxaAxaadaxYaxZayaaCXaABaACaADaCYayaaAEaAFaAGaAHaAIaAJaAKaALaAMaANaAOaAPayoayoayoaAQazwanbaARahfafmaASaASaASaASaASaATatuazFazFazFazFazFazFaAUaAVaAWazFaqGaqGaqGaqGaJgaJhaltayJaqKaqKaqKaqKaqKayJaltaltamIamIamIaltaAYayKaAZaBaayKamIarPaltamIasNaltamIamIaltarPasOaltamIamIaltaBbamIaxnayMaqTarUarUarUarUarUarUarUarUarUarVarVarVarVarVaadaoBaoBaoBaoBaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaayUaBcayUayUayUayUayUayUaBcayUaaaauSaBdazbaBeaBfaBgaBeaBeaBeaBhazcaAmaBiaBjaBkaBlaBmaAmazcaBnaBoaBnaBnaBnaBnaBnaBnaBpaBnaBqaaaaAxaBraBsaBtaBuaBvaAxaaaaxYaxZayaaCXaBwaBxaByaCYayaaqsaBzaydaBAaBBaBCaBDaBEaAPaBFaBGayoayoaBHayoaAQazwanbazxahfafmaASaBIaBJaBKaBLayuatuazFaBMaBNaBOaBOazFaBSaBPaAWazFaBQaZMaBRaqGaAXauJaltaBVaBWaBWaBWaBWaBWaBXaltaltaBYaBZaCaaltaltayKaCbaCcayKaCdaCealtaltaltaltaltaltaCfaCgaChaCiaCiaCiaCjaCkaClaCmaCnaCoaCpaCqaCraCsaCtaCuaCvaCwaCwaCwaadaadaadaadaadaadaadaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaauSayWaCxaBeaCyaCzaCAaCBaCCaCDazcaAmaCEaCFaCGaCFaCFaAmazcaCHaCIaCJaCKaCLaCMaCNaCOaCPaCQaBqaadaAxaCRaCSaCTaCUaCVaAxaadaxYaxZayaaCZaDabiybizbiAayaaqsaDbaydaDcaDdaDeayoaDfaDgaDhaDiaDjaAQayqaDkayqazwanbazxahfafmaASaDlaDmaDnaDoasxaDpaDqaDraDsaDtaDtaDuaDvaDwaDBaDxaBUaDyaDzaDAaDCaDDaltaHwaltaHwaltaHwaltaHwaltaltaBYaDEaDFaDGaDHayKaDIaDJayKarPamIaltaaaaltaDKaDLaDLaDMaDNaDOaDOaDOaDOaDOaDPaDQaDRaDSaDTaDTaDTaDUaVqaDWaDXaDYaDZaEaaEbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaayUayWaEcaBeaEdaEeaEfaEgaEhaEiazcaEjaCFaCFaCFaCFaCFaCFaEkaElaCIaElaEmaElaElaElaElaCPaElaBqaaaaAxaEnaEoaEoaEpaEqaAxaaaaxYaxZayaaEraEsaEtaEuaEvayaaqsaEwaydaydaDiaExaEyaEzaEAaydaydayoayoayqaEBayqazwanbazxahfafmaASaDlaECaEDaEEaEFaEGaEHaEIaEJaEKaEKaEKaEKaEKaELazFaEMaEOaFHaqGaHCaHDaltaltaltaltaltaltaltaltaltaltaltaltaltaEPaltayKaEQaERaESaETaEUaEVaEWaEVaEXaEYaDOaEZaFaaFbaFbaFbaFbaFcaFdaFeaFcaFcaFcaFcaFcaFcaFcaFfaFgaFhaCwaCwaCwaadaadaadaadaadaadaadaadaadaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaayUayWaEcaBeaEdaEeaEfaEgaEhaEiazcaEjaCFaCFaCFaCFaCFaCFaEkaElaCIaElaEmaElaElaElaElaCPaElaBqaaaaAxaEnaEoaEoaEpaEqaAxaaaaxYaxZayaaEraEsaEtaEuaEvayaaqsaEwaydaydaDiaExaEyaEzaEAaydaydayoayoayqaEBayqazwanbazxahfafmaASaDlaECaEDalSaEFaEGaEHaEIaEJaEKaEKaEKaEKaEKaELazFaEMaEOaFHaqGaHCaHDaltaltaltaltaltaltaltaltaltaltaltaltaltaEPaltayKaEQaERaESaETaEUaEVaEWaEVaEXaEYaDOaEZaFaaFbaFbaFbaFbaFcaFdaFeaFcaFcaFcaFcaFcaFcaFcaFfaFgaFhaCwaCwaCwaadaadaadaadaadaadaadaadaadaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaayUayWaFiaBeaFjaFkaFlaFmaFnaFoazcaFpaCFaCFaCFaCFaCFaFqazcaFraFsaFtaFuaElaElaElaFvaFwaFxaBqaadaAxaFyaFzaFAaFBaFCaAxaadaxYaFDayaaFEaFFaEtaFGaENayaaqsaFIayqaFJayoaFKaFLaFMayoaFNayqaFOaFPayqaFLayqaFQaoNaFRahfafmaASaDlaFSaFTaFUattatuazFaFVaFWazFaFXazFaFZazFaFYaZMaZMaWIaGbaGcaGeaGfaGgaHHaGiaGiaGjaGkaHyaHzaGkaGlaGmaGkaGkaGnaGiaGoaGpaCnaGqaGraGsaGtaGuaGtaGvaGwaFbaGxaGyaFbaGzaGAaGBaFcaGCaGDaFcaGEaGFaGGaGHaGIaGJaGKaGLaGMaGNaGOaGPaaaaaaaaaaaaaaaaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaoBaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaGQayUayWaGRaBeaBeaGSaGTaGUaGTaBeazcazcazcazcaGVaCFaGWaGXazcaGYaCIaElaElaElaGZaElaElaCPaHaaBqaaaaAxaAxaHbaHcaHbaAxaAxaaaaxYaxZayaaHdaHeaHfaHgaHhayaaqsaHiayqaHjayoaHkaFLaHlayoaHmayqaAQaAQayqaHnayqaHoaHpaHqahfanDaASaASaASaASaASaHraHsazFaHtaHuazFaHvazFaHxazFaGdaGhaHJaGhaHAaHGbiBbiCaHEaHFaHIaHIaIYaIZaJcaKmaHIaHKaHLaHMaxpaxpaxpaHNaHOaHPaHQaHRamIaHSaHSaHSaHTaHUaFbaHVaHWaHXaHYaHZaIaaFcaIbaIcaFcaIdaIeaIfaIgaGIaIhaFfaFgaDYaIiaIjaGPaaaaaaaaaaaaaaaaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaayUayWaxBaIkaIlaImaIlaInaxBaIoaIpaIqaIrazcaIsaCFaCFaItazcaIuaCIaElaIvaIwaIxaIyaIzaIAaIBaBqaaaaadaaaaICaIDaICaaaaadaaaaxYaxZayaaIEaIFaIGaFGaIHayaaqsapyayqaIIayoaFLaFLaFLaIJaIKayqaaaaaaaILaIMaINaIOaIPaIQaIRaISaILaaaaaaaITaIUaIVaIWazFaIXaHuaHuaHuaHuaHuazFaJaaJbaJdaJeaJdaJdaNtaPQbiDaBTaBTaJfaKhaKiaKjaKkaJiaJiaJjaJkaJlaJiaJmaHSaHSaJnaHTaHSaHSaHSaJoaJpaHTaHUaFbaJqaJraJsaJtaJuaJvaFcaJwaJxaJyaJzaJAaJBaJCaJDaIhaFfaJEaDYaGNaJFaGPaaaaaaaaaaaaaaaaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaayUayWaxBaJGaJHaJIaJHaJJaJHaJHaJHaJKaxBazcaJLaJMaJLazcazcaJNaJOaJNaBnaBnaBnaBnaJNaJPaJQaBqaJRaJSaJSaJTaJUaJVaJSaJSaJWaxYaJXayaaJYayaaJZaKaaKbayaarjaoJayqayqayqaAQaKcaAQayqayqayqaILaILaILaKdaIPaIPaIPaIPaIPaKeaILaILaILaITaKfaIVaKgazFaLMazFazFazFazFazFaJdaGaaKsbiEaKtbgUaKoaMcaLQaLcaLTaBTaKpaKraKraKjaLSaJiaLUaKuaKvaKwaJiaKxaKyaKzaKAaKBaKCaKDaKEaKFaKGaHTaHUaFbaKHaKIaKJaJtaJuaKKaFcaKLaKMaKNaKOaKPaKQaKRaFcaFcaKSaFgaDYaIiaIjaGPaaaaadaadaadaadaadaadaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaauSaKTaxBaKUaKVaKWaKXaKYaKZaweaLaaLbaxBaLjaLdaLeaLeaLfaLeaLeaLgaLeaLeaLeaLeaLeaLeaLhaLiaLqaLkaLlaLmaLmaLnaLmaLmaLmaLmaLoaLpaLxaLraLmaLsaLmaLtaMWaLuaLvaLwaLRalSaIRaIRaIRaLNaLPaLPbiFaLPaLPaLAaLBaLCaLDaLEaLFaLGaLPaLPbiFaLHaLIaLJaLKaPJbcXaNKbiGaLPbiHbiIaOCaLVaKsaLWaWHaLXaLYaOvaNjaNlaNnaBTaLZaMaaMbaNkaNmaJiaMdaKuaMeaMfaJiaJiaMgaMhaMiaMjaMkaMlaMmaMnaMoaHTaHUaFbaMpaMpaMqaMraMpaMpaFcaMsaMtaFcaMuaKRaKRaKRaFcaMvaMwaMxaDYaCwaCwaCwaMyaMyaMyaMzaMzaMzaadaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaayUayVayUayUayUayUayUayUayVayUaaaauSaBdaMAaKUaMBaMCaMDaMEaMFaweaMGaLbaMHaIkaLdaMIaMJaMKaMLaMLaMMaLeaLeaLeaLeaLeaLeaLeaLiaLeaLdaMNaLeaLeaMOaMPaMQaMQaMQaMRaMSaMQaMTaMQaMUaMQaMVaOnaMXaMYaMZaIPaKlaIPaIPaIPaIPaIPaIPaLzaIPaIPaNaaNbaNcaNdaNeaNfaNgaIPaIPaLzaIPaNhaIPaIPaIPaIPaIPaIPaIPaNiaIPaOCaNoaNpaNqaNraStaNsbiJaOwaOxaOyaBTaNuaOuaOuaHBaOzaJiaNvaKuaNwaNxaNyaJiaHSaHSaNzaHSaHSaHSaNAaNBaNAaHTaHUaFbaNCaMpaMpaNDaMpaNEaFcaFcaFcaFcaFcaFcaFcaNFaFcaFfaFfaFgaDYaNGaNHaCwaNIaNJaRkaNLaNMaMzaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaauSaKTaxBaKUaKVaKWaKXaKYaKZaweaLaaLbaxBaLjaLdaLeaLeaLfaLeaLeaLgaLeaLeaLeaLeaLeaLeaLhaLiaLqaLkaLlaLmaLmaLnaLmaLmaLmaLmaLoaLpaLxaLraLmaLsaLmaLtaMWaLuaLvaLwaLRaEEaIRaIRaIRaLNaLPaLPbiFaLPaLPaLAaLBaLCaLDaLEaLFaLGaLPaLPbiFaLHaLIaLJaLKaPJbcXaNKbiGaLPbiHbiIaOCaLVaKsaLWaWHaLXaLYaOvaNjaNlaNnaBTaLZaMaaMbaNkaNmaJiaMdaKuaMeaMfaJiaJiaMgaMhaMiaMjaMkaMlaMmaMnaMoaHTaHUaFbaMpaMpaMqaMraMpaMpaFcaMsaMtaFcaMuaKRaKRaKRaFcaMvaMwaMxaDYaCwaCwaCwaMyaMyaMyaMzaMzaMzaadaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaayUayVayUayUayUayUayUayUayVayUaaaauSaBdaMAaKUaMBaMCaMDaMEaMFaweaMGaLbaMHaIkaLdaMIaMJaMKaMLaMLaMMaLeaLeaLeaLeaLeaLeaLeaLiaLeaLdaMNaLeaLeaMOaMPaMQaMQaMQaMRaMSaMQaMTaMQaMUaMQaMVaOnaMXaMYaMZaIPaIPaIPaIPaIPaIPaIPaIPaLzaIPaIPaNaaNbaNcaNdaNeaNfaNgaIPaIPaLzaIPaNhaIPaIPaIPaIPaIPaIPaIPaNiaIPaOCaNoaNpaNqaNraStaNsbiJaOwaOxaOyaBTaNuaOuaOuaHBaOzaJiaNvaKuaNwaNxaNyaJiaHSaHSaNzaHSaHSaHSaNAaNBaNAaHTaHUaFbaNCaMpaMpaNDaMpaNEaFcaFcaFcaFcaFcaFcaFcaNFaFcaFfaFfaFgaDYaNGaNHaCwaNIaNJaRkaNLaNMaMzaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaauSaAaauSayUaxyayUaNNaNOaNPaNQayUaxyayUayUauSayWaxBaKUaNRaNSaMDaMEaMFaweaNTaLbaxBaIkaLdaLeaNUaNVaNVaNVaNWaNXaNYaNVaNZaNVaNVaNVaOaaNVaObaNVaNVaNVaOcaOdaOeaOfaOfaOfaOgaOhaOiaOjaOkaOlaOmaWUaOoaOpaIPaOqaOqaOqaOraOqaOqaOqaOqaOsaOqaOqaOqaOqaOqaOqaOtaOqaOqaOqaOqaPPaOqaOqaOqaOqaOqaOqaOtaOqaIPaIPaIPaJdaPLaStaStaStaStaRiaMcaLQaPOaNnaBTaBTaPKaBTaBTaBTaJiaOAaOBaODaWFaOEaJiaHSaOFaOGaOHaOIaOHaOHaOJaOKaHTaHUaFbaOLaOLaOMaONaOOaOOaOPaFbaOQaORaOSaCwaFfaGNaOTaFfaFfaOUaOVaCwaOWaCwaOXaOYaOZaPaaPbaMzaMzaMzaMzaMzaMzaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaweawfaweayUaBcayUayWaxBaxBayXayUaBcayUaPcaPdaPeaxBaKUaPfaPgaKXaPhaKZaweaPiaLbaxBaPjaPjaPjaPkaPlaPlaPlaPlaPlaPlaPmaPnaPlaPoaPlaPlaPlaPpaPqaPraPqaPsaPtaPuaLeaLeaPvaPwaPxaLeaPyaPzaLeaPAaPAaPMaRgaRmaILaILaILaILaILaILaILaILaPCaPDaPEaPFaPEaPEaPEaPGaPEaPHaPEaPIaPCaILaILaILaILaILaILaILaILaPMaTSaUTaJdaVjaRiaRiaRiaRiaKsaMcaLQaRjaKsaRsaKsaKsaVnaJiaRnaJiaJiaPRaJkaJiaJiaJiaJiaOHaPSaPTaPTaPTaPTaPUaOHaHTaHUaFbaPVaMpaOMaONaMpaMpaPWaFbaPXaPYaPZaCwaFfaIiaQaaQbaQbaQcaQdaQeaQfaCwaQgaQhaQiaQjaQjaQkaQlaQlaQmaQlaQnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaoBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaQoaaaaaaaaaaxwaXfaxyaxzaQpaxBaQqaPeaxBaxBaQraQqaxBaQpaPeaxBaxBaxBaQsaQtaQuaQvaQwaQxaQxaQyaQzaxBaPjaQAaPjaQBaPlaQCbiKaQEaQFaQGaQDaQHaQIaQJaQKaQLaQMaPpaQNaQOaQPaPsaQQaPuaPuaQRaPuaPuaPAaPAaQSaQTaPAaPAaPAaQUbiLbbeaILaaaaaaaaaaaaaaaaaaaaaaPCaKnaQVaQWaQXaQYaQZaRaaRbaRcaRdaReaPCaaaaaaaaaaaaaaaaaaaaaaILaIOaIPaIPbiMaKsaKsaKsaRlaKsaKsaRfaSfaRjaKsaSraKsaKsaKsbaEaSBaRoaRpaRqaRraRtaRuaSuaJiaOHaRvaVsbiNbiNbiOaRxaOHaHTaRyaFbaRzaRzaOMaONaRAaRAaRBaFbaFbaRCaFbaCwaRDaGNaOTaREaRFaOUaOVaCwaCwaCwaMzaRGaRHaMzaMzaMzaMzaMzaMzaMzaRIaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaweaRJawgaRKaRLaRLaRLaRLaRLaRLaRLaRLaRKaRLaRMaxBaxBaIkaxBaRNaROaxBaRPaxBaRQaRRaRSaPjaRTaPjaQBaPlaRUaQDaQDaQDaQDaQDaQHaQDaQDaQDaQDaQMaPpaRVaQOaQOaPsaQQaPuaRWaRXaRXaRYaPAaRZaSaaSbaScaSdaSeaIPbiLbbeaILaaaaaaaaaaaaaPCaPCaPCaPCaSgaShaSiaSjaSkaSlaSmaSnaSoaSpaSvaPCaPCaPCaPCaaaaaaaaaaaaaILaIOaIPaIPaSqaKsaKsaSsaStaSwbiPaSzaSAaRjaSsaTTaSwaKsaTUaJiaWKaSCaSDaSEaSFaSGaSHaSBaSIaSJaSKbiQaSLaSMbiRaSNaOHaHTaHUaFbaMpaMpaOMaONaRAaRAaMpaSOaSPaMpaSQaCwaKSaSRaSSaREaREaSTaSUaSVaCwaSWaSXaQhaQiaQjaQjaSYaQlaQlaQlaQlaSZaTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaauSauSauSauSayUayUayUayUayUayUayUayUauSauSaweaIkaTbaTcaTcaTdaTcaTcaTcaTcaTeaTcaTcaPjaRTaTfaTgaPlaThaQDaTiaTjaTkaTlaTmaTnaToaQDaQDaTpaPpaTqaTraTsaPsaQQaPuaTtaTuaTvaTwaPAaTxaTyaSbaTzaTAaSeaIPaPBbbeaILaILaTBaPCaPCaPCaTCaTDaTEaTFaTGaTHaTIaTJaTHaTKaTHaTLaTMaTNaTOaTPaTQaPCaPCaPCaTBaILaILaLzaLzbbfaJdaKsaKsaSsaVmaSwbiSaWIaTVaKqaSsbiTaSwaKsaKsaVoaSBaSBaWJaTXaTYaTZaUaaSBaUbaUcaUdbiQaUeaUfbiRaUgaUhaHTaHUaFbaUiaUiaOMaONaUjaMpaMpaUkaMpaUlaUmaCwaUnaUoaUpaREaREaUqaUraFfaCwaUsaQjaQhaQiaQjaPbaMzaMzaMzaMzaMzaMzaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaayUaAcazaaUtaTcaUuaUvaUwaUxaUwaUyaUzaUwaTcaRTaRTaUAaUBaPlaUCaUDaUEaUFaUGaUHaUIaUJaUKaULaUMaQMaPpaPpaPpaPpaPsaQQaPuaPuaPuaPuaPuaPAaUNaUOaUPaTzaUQaSeaIPaIPaLyaIRaIRaURaUSaZQaPCaUUaUVaUWaUXaUYaUXaUZaVaaVbaVcaVdaVeaVfaVdaVgaVhaViaPCaZRaUSaVkaVlaIRaIOaIPaxxaJdaSyaKsaSsbiUaSwaKsaZMaZMaKsaSsaStaSwaKsaKsaVoaSBaSBbgZbiVaVpaVpaUaaWLaJiaVraUdbiWbiXbiXbiYaUgaVtaHTaVuaFbaFbaFbaOMaONaVvaVwaMpaVxaVyaKJaVzaCwaFfaSRaSSaREaREaVAaSUaVBaCwaVCaQjaQhaQiaQjaPbaMzaZNaZOaZPaMzaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaVDayUayUayWaxBaTcaVEaVFaVGaUuaVHaVIaUzaUwaTcaVJaVKaVLaPjaPlaVMaVNaVOaVPaVQaVQaVRaVQaVQaVQaVSaVTaPlaVUaVVaVWaVXaVYaVZaWaaWbaWcaWdaWdaWdaWdaWdaWdaWdaWdbbVaIPaIPaIPaIPaWeaWfaWgaWhaWiaWjaWkaWlaWmaWnaWoaWpaWqaWraWsaWtaWuaWvaWkaWwaWxaWyaWzaWAaWBaWCaWDaWEaIPaIPbbXbiZaKsaKsaKsaKsbjaaZMaZMaKsaSsaStaSwaKsaKsaVoaSBaSBaSBaSBaSBaSBaUaaYoaJiaOHaUdaRwaRwaRwaRwaUgaOHaHTaWMaWNaWOaWPaWQaWRaWSaWSaWTaOMaOMaOMaOMaWYaREaREaREaREaREaWVaWWaWXaYIaWZaXaaXbaXcaPaaXdaMzaZPaZOaZOaMzaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaVDayUayUayWaxBaTcaVEaVFaVGaUuaVHaVIaUzaUwaTcaVJaVKaVLaPjaPlaVMaVNaVOaVPaVQaVQaVRaVQaVQaVQaVSaVTaPlaVUaVVaVWaVXaVYaVZaWaaWbaWcaWdaWdaWdaWdaWdaWdaWdaWdbbVaIPaIPaIPaIPaWeaWfaWgaWhaWiaWjaWkaWlaWmaWnaWoaWpaWqaWraWsaWtaWuaWvaWkaWwaWxaWyaWzaWAaWBaWCaWDaWEaIPaIPbbXbiZaKsaKsaKsaKsbjaaZMaZMaKsaSsaStaSwaKsaKsaVoaSBaSBaSBaSBaSBaSBaUaaYoaJiaOHaUdaRwaRwaRwaRwaUgaOHaHTaWMaWNaWOaWPaWQaWRaWSaWSaWTaOMaOMaOMaOMbegaREaREaREaREaREaWVaWWaWXaYIaWZaXaaXbaXcaPaaXdaMzaZPaZOaZOaMzaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaXeaXgaxybhaaxBaxBaTcaXhaXiaXjaXkaXkaXlaXmaXnaTcaXoaRTaVLaXpaXpaXpaXqaXraXpaXsaXtaXuaXvaXwaXwaXxaXyaPlaXzaXAaXBaXCaXDaXEaXBaXFaXGaXGaXHaXIaXJaXKaXLaXMaWdbbVaIPaXNaXOaXPaXQaXRaXSaPCaXTaXUaXVaXWaXXaXYaXYaXZaYaaYbaYcaYdaYeaYfaXVaYgaXTaPCaXSaXRaYhaYiaXOaYjaIPaIPbebbbXbiZaKsaKsaKsaKsaKsaKsaKsaRlbjbaKsaKsaKsaJiaYpaYqaSBaSBaYraSBaYXbhyaJiaYsaYtaRwaYuaYuaYvaYtaYwaYxaYyaYzaYzaYAaYBaYCaOMaOMaYDaOMaOMaOMaOMbegaYEaYFaYFaYFaYFaYFaYGaYHbjsaYJaYKaYLaYMaQjaYNaMzbjhaZOaZNaMzaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaayUayUayUayWaYOaYPaYQaYRaYSaYSaYSaYSaYTaUuaTcaYUaYVaVLaXpaYWbaKaYYaYZaXpaZaaZbaZcaPlaZdaZeaZfaZgaPlaZhaZiaZjaZkaZjaZlaZmaZnaWdaZoaZpaZpaZqaZraZsaZtaWdbbYaLzaZuaZvaZvaZvaZvaZvaZvaZwaZxaZyaXXaXZaZzaZAaZAaZBaZAaZAaZCaYbaYeaZDaZEaZFaZDaZDaZDaZDaZDaZDbjiaIPaIPbgTbjjbbXbiZbjkaSwbjlaKsaKsaKsaWGaKsaKsbjmaYkaJibjnaJiaZSaYlaZTaZTaJiaJiaJiaZUaRwaRwaZVaZWaZXaZYaZWaHTaZZbaababaFbbacbadbaeaVwaMpbafaUkaVwbagaCwbahaFfbaiaREaREbaiaFfbajaCwbakbalbamaQiaQjaPbaMzaMzaMzaMzaMzaMzaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaayUbanaPebaoaTcaUwaVFaUwaUubapaUwbaqaUwaTcbarbasbataXpaXpaXpbaubavaXpaZbbawaZbaPlaZdaZeaZfaZgaPlaZhaZibaxbayaZjbazaZmaZnaWdbaAaZpaZpaZGbaBaZpbaDbbxaIPaIPbbZaZvbaFbaGbaHbaIbaJbcebaLbaMbaNbaOaZAaZAbaPbaQbaPaZAaZAbaRbaSbaCbaTbaUbaXbaYbbzbaVbaWaZDbjoaIPaIPbgTbgTbjpbbXaJdaJdaJdbbbaSqbbbaJdbbcaJdaJdaJdaJibcbbdZbbdbbdbbdbbdbcfbdHaJiaZWbbgbbgaZWbaabaabaabaaaHTaZZbaababaFbaFbaFbbbhaFbbbhaFbbbhaFbaFbaCwaCwbbibbibbibbibbibbiaCwaCwbbjaQjbbkaQiaQjaQjbblaQlaQlaQlaQlaSZaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
@@ -7095,7 +7094,7 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqFbnFbnFbnFbhYbnFbnFbnFbzpbzpbzpbzpbzqbzrbzrbzpbzpbzsbztbzubzvbxWbzwbzxbzybzzbxWbzAbpAbbeaTBaTBbobbobbobbobbobbzBbobaILaILaILbtSbzCbzDbzEbtYaILaILaILbsHbsHbsHbsHbsHbsHbsHbsHbsHbzFaIPbzGbxabxabzHbzIbxabxabxabzJbyubzKbyubzLbzMbzNbzObzPbzQbzLbhcbyCbvVbzRbzSbzTbzUbzVbzWbzXbzUbzUbzYbzZbAabAbbAcbAcbAcbAcbAdbAcbAcbAcbAebAebAfbAgbAhbAhbtrbAibtsbxybsabsbbsAbAmbAnbAobApbsebsebAqbAqbAqbsebArbsebxFbhIbAsbzmbAtblYaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaaaaaaaaaaaabzpbAubAvbAwbAxbAybAzbzrbAAbABbACbADbxXbAEbAFbAGbAHbxWbzAbpAaIPaLPbAIbAJbAKaLPbiFbALbAMbANaWDaWDaWDbAObAPbAQbARbASaIPaIPaIPaIPaLOaIPaLzbATaIPaIPbAUaIPbAVaIPbAWbxabAXbAYbAZbBabBbbxabBcbyubBdbyubzLbzMbzMbBebBfbBgbzLbhcbBhbvVbuBbBibBjbBkbBlbBmbBnbBobBpbrGbrGbBqbBrbAcbBsbBtbBubBvbBwbBxbAcbBybBzbBAbBBbBCbAhbtrbAibBDbBEbsBbsVbtPbBIbBJbBKbApbBLbBLbBLbBLbBLbBLbBLbsebxFbhIbBMbBNbBOblYaadaadaadaadaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaoBaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaaaaaaaaaaaabzrbBPbBQbBRbBSbBTbBUbBVbBWbBXbBYbBZbCabCbbAGbCcbCdbxWbzAbCeaIPaIPaIPaIPaIPaIPbCfaIPbpAaIPaIPaIPaIPaIPbCgbChbCiaIPaIPaIPaIPaIPaIPaIPaLzaIPaIPaIPaIPaNhbAVbCjbjDbxabCkbClbCmbCnbCobxabCpbyubyvbCqbxabCrbCsbCtbCubCvbxabhcbyCbvVbvVbvVbvVbvVbrGbrGbrGbrGbrGbrGbCwbCxbCybAcbCzbCAbCBbCCbCDbCEbAcbCFbCGbCHbCIbCJbAhbtrbCKbCLbCMbtQbyybyybyZbzabzbbApbBLbBLbCSbCTbBLbBLbBLbsebxFbhIbCUbzmbCVblYaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabzpbCWbCXbCYbCZbDabDbbDcbDdbDebDfbDdbDgbDhbDibDjbDkbxWbDlbDmbDnbfQbDnbDobDnbDnbDpbDnbDqbfQbDrbDsbfQbDtbDubDvbDwbDxbDybDzbDAbDAbDBbDAbDCbDDbDAbDEbDFbDGbDHbfQbDIbxabDJbDKbDLbxbbxbbxabxbbDMbxbbxabxabxabxabxabxabxabxabhcbhcbDNbDObDPbwZbDQbDRbAjbAkbAlbBFbDRbDWbDXbDYbAcbBsbDZbEabEbbEcbEdbAcbEebEfbEgbEhbEibAhbtrbEjbEkbxzbBGbBHbCNbCObCPbCQbApbBLbBLbBLbErbBLbBLbBLbsebEsbEtbEubzmbznblYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabzpbCWbCXbCYbCZbDabDbbDcbDdbDebDfbDdbDgbDhbDibDjbDkbxWbDlbDmbDnaKlbDnbDobDnbDnbDpbDnbDqbfQbDrbDsbfQbDtbDubDvbDwbDxbDybDzbDAbDAbDBbDAbDCbDDbDAbDEbDFbDGbDHbfQbDIbxabDJbDKbDLbxbbxbbxabxbbDMbxbbxabxabxabxabxabxabxabxabhcbhcbDNbDObDPbwZbDQbDRbAjbAkbAlbBFbDRbDWbDXbDYbAcbBsbDZbEabEbbEcbEdbAcbEebEfbEgbEhbEibAhbtrbEjbEkbxzbBGbBHbCNbCObCPbCQbApbBLbBLbBLbErbBLbBLbBLbsebEsbEtbEubzmbznblYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabzpbzpbzrbzrbzrbzrbzpbzpbEvbEwbACaTRbxWbxWbxWbxWbxWbxWbExbEyaITaITaITaITbEzbEzbEzbEzbEzbEzbEzbEzbEzbEzbEAaHpbEBbECbECbECbECbECbEDbECbECbECbECbEEbEFbEEaIUaKfbEGbxabEHbEIbEJbEKbELbxabEMbyubENbEObEPbEQbERbESbETbEUbEOblDbhcbhcbhcbhcbhcbsWbEVbCRbDSbCRbDTbDRbEZbCxbFabFabFabFabFabFabFabFabFabFbbFbbFbbFbbFbbFbbFcbFdbFebxzbxzbxzbxzbxzbxzbxzbApbsebsebsebsebsebsebsebsebxFbhIbFfbFgblYblYaadaadaadaaeaaeaaeaaeaaeaaeaaeaaeaadaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabFhaaaaaaaaaaadaaaaaabzsbFibFjbFkbFlbFlbFmbFnbFobFpbFqbFrbEyaaaaaaaadaaabEzbFsbFtbFubFvbFwbFxbFybFzbEzbFAbFBbFCbECbFDbFEbFFbFGbFHbFIbFJbFKbFLbFMbFNbEEbEEbEEbEEbxabFObFPbFQbFRbFSbFTbFUbFVbFWbFXbFVbFVbFVbFYbyubFZbGabGbbGcbGcbGdbGebGfbGgbEVbDUbDVbElbEmbDRbEZbCxbFabGlbGlbGlbGmbGlbGlbGlbFabGnbGnbGobGnbGnbFbbGpbGqbGrbGsbGtbGubGvbGwbGxbGybGzbGAbGBbGCbGDbGEbGFbGGbGGbGHbGIbGtbGtblYaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaadaadaadaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaaabzsbzsbGJbGKbGLbDdbGMbGNbGObGObGPbGQbGRbGSaadbGTbGUbGVbGWbGXbFzbGYbFzbGZbFzbFzbFzbEzbHabHbbHcbECbHdbHebHfbHgbHhbHibHjbECbECbHkbHlbHmbHnbHobHpbHqbHrbHsbHtbHubHvbHwbHxbHybHzbHAbHBbHCbyubyubyubHDbjEbjEbjEbjEbjEbHEbHFbwYbEVbEnbEobCRbEpbDRbEZbCxbFabGlbGlbGlbGlbGlbGlbGlbFabHJbHKbHLbHMbHNbHObHPbHQbGrbHRbHSbHTbHTbHTbHTbHTbHTbHUbHVbHWbGDblYbHXbHYbHZbHZbIabIbbIcbGtatJaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaadbIdbIebIdaadaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+6
View File
@@ -185,6 +185,12 @@ GLOBAL_LIST_INIT(shove_disarming_types, typecacheof(list(
//We will round to this value in damage calculations.
#define DAMAGE_PRECISION 0.1
//bullet_act() return values
#define BULLET_ACT_HIT "HIT" //It's a successful hit, whatever that means in the context of the thing it's hitting.
#define BULLET_ACT_BLOCK "BLOCK" //It's a blocked hit, whatever that means in the context of the thing it's hitting.
#define BULLET_ACT_FORCE_PIERCE "PIERCE" //It pierces through the object regardless of the bullet being piercing by default.
#define BULLET_ACT_TURF "TURF" //It hit us but it should hit something on the same turf too. Usually used for turfs.
//items total mass, used to calculate their attacks' stamina costs. If not defined, the cost will be (w_class * 1.25)
#define TOTAL_MASS_TINY_ITEM 1.25
#define TOTAL_MASS_SMALL_ITEM 2.5
+6
View File
@@ -1,10 +1,16 @@
// simple is_type and similar inline helpers
#if DM_VERSION < 513
#define islist(L) (istype(L, /list))
#endif
#define in_range(source, user) (get_dist(source, user) <= 1 && (get_step(source, 0)?:z) == (get_step(user, 0)?:z))
#if DM_VERSION < 513
#define ismovableatom(A) (istype(A, /atom/movable))
#else
#define ismovableatom(A) ismovable(A)
#endif
#define isatom(A) (isloc(A))
+2
View File
@@ -35,6 +35,7 @@
#define LOG_GAME (1 << 12)
#define LOG_ADMIN_PRIVATE (1 << 13)
#define LOG_ASAY (1 << 14)
#define LOG_CLONING (1 << 15)
//Individual logging panel pages
#define INDIVIDUAL_ATTACK_LOG (LOG_ATTACK)
@@ -47,3 +48,4 @@
#define LOGSRC_CLIENT "Client"
#define LOGSRC_MOB "Mob"
+5
View File
@@ -100,6 +100,11 @@
#define NUKE_ON_TIMING 2
#define NUKE_ON_EXPLODING 3
//cloning defines. These are flags.
#define CLONING_SUCCESS (1<<0)
#define CLONING_DELETE_RECORD (1<<1)
//these flags are used to tell the DNA modifier if a plant gene cannot be extracted or modified.
#define PLANT_GENE_REMOVABLE (1<<0)
#define PLANT_GENE_EXTRACTABLE (1<<1)
+8
View File
@@ -30,7 +30,11 @@
// round() acts like floor(x, 1) by default but can't handle other values
#define FLOOR(x, y) ( round((x) / (y)) * (y) )
#if DM_VERSION < 513
#define CLAMP(CLVALUE,CLMIN,CLMAX) ( max( (CLMIN), min((CLVALUE), (CLMAX)) ) )
#else
#define CLAMP(CLVALUE,CLMIN,CLMAX) clamp(CLVALUE,CLMIN,CLMAX)
#endif
// Similar to clamp but the bottom rolls around to the top and vice versa. min is inclusive, max is exclusive
#define WRAP(val, min, max) ( min == max ? min : (val) - (round(((val) - (min))/((max) - (min))) * ((max) - (min))) )
@@ -39,7 +43,11 @@
#define MODULUS(x, y) ( (x) - (y) * round((x) / (y)) )
// Tangent
#if DM_VERSION < 513
#define TAN(x) (sin(x) / cos(x))
#else
#define TAN(x) tan(x)
#endif
// Cotangent
#define COT(x) (1 / TAN(x))
+1 -1
View File
@@ -476,7 +476,7 @@ GLOBAL_LIST_INIT(pda_reskins, list(PDA_SKIN_CLASSIC = 'icons/obj/pda.dmi', PDA_S
#define PDAIMG(what) {"<span class="pda16x16 [#what]"></span>"}
//Filters
#define AMBIENT_OCCLUSION list("type"="drop_shadow","x"=0,"y"=-2,"size"=4,"border"=4,"color"="#04080FAA")
#define AMBIENT_OCCLUSION list("type"="drop_shadow","x"=0,"y"=-2,"size"=4,"color"="#04080FAA")
#define EYE_BLUR(size) list("type"="blur", "size"=size)
#define GRAVITY_MOTION_BLUR list("type"="motion_blur","x"=0,"y"=0)
+3 -3
View File
@@ -24,9 +24,9 @@
#define REACTION_OPPRESSION_THRESHOLD 5
#define NOBLIUM_FORMATION_ENERGY 2e9 //1 Mole of Noblium takes the planck energy to condense.
//Research point amounts
#define NOBLIUM_RESEARCH_AMOUNT 1000
#define BZ_RESEARCH_AMOUNT 150
#define MIASMA_RESEARCH_AMOUNT 160
#define NOBLIUM_RESEARCH_AMOUNT 100
#define BZ_RESEARCH_AMOUNT 15
#define MIASMA_RESEARCH_AMOUNT 16
#define STIMULUM_RESEARCH_AMOUNT 50
//Plasma fusion properties
#define FUSION_ENERGY_THRESHOLD 3e9 //Amount of energy it takes to start a fusion reaction
+1 -1
View File
@@ -2,7 +2,7 @@
#define TYPEID_NULL "0"
#define TYPEID_NORMAL_LIST "f"
//helper macros
#define GET_TYPEID(ref) ( ( (lentext(ref) <= 10) ? "TYPEID_NULL" : copytext(ref, 4, lentext(ref)-6) ) )
#define GET_TYPEID(ref) ( ( (length(ref) <= 10) ? "TYPEID_NULL" : copytext(ref, 4, length(ref)-6) ) )
#define IS_NORMAL_LIST(L) (GET_TYPEID("\ref[L]") == TYPEID_NORMAL_LIST)
+1 -1
View File
@@ -514,7 +514,7 @@
used_key_list[input_key] = 1
return input_key
#if DM_VERSION > 512
#if DM_VERSION > 513
#error Remie said that lummox was adding a way to get a lists
#error contents via list.values, if that is true remove this
#error otherwise, update the version and bug lummox
+5
View File
@@ -58,6 +58,10 @@
if (CONFIG_GET(flag/log_game))
WRITE_LOG(GLOB.world_game_log, "GAME: [text]")
/proc/log_cloning(text, mob/initiator)
if(CONFIG_GET(flag/log_cloning))
WRITE_LOG(GLOB.world_cloning_log, "CLONING: [text]")
/proc/log_access(text)
if (CONFIG_GET(flag/log_access))
WRITE_LOG(GLOB.world_game_log, "ACCESS: [text]")
@@ -261,3 +265,4 @@
return "([AREACOORD(T)])"
else if(A.loc)
return "(UNKNOWN (?, ?, ?))"
+11 -11
View File
@@ -305,9 +305,9 @@
//is in the other string at the same spot (assuming it is not a replace char).
//This is used for fingerprints
var/newtext = text
if(lentext(text) != lentext(compare))
if(length(text) != length(compare))
return 0
for(var/i = 1, i < lentext(text), i++)
for(var/i = 1, i < length(text), i++)
var/a = copytext(text,i,i+1)
var/b = copytext(compare,i,i+1)
//if it isn't both the same letter, or if they are both the replacement character
@@ -327,7 +327,7 @@
if(!text || !character)
return 0
var/count = 0
for(var/i = 1, i <= lentext(text), i++)
for(var/i = 1, i <= length(text), i++)
var/a = copytext(text,i,i+1)
if(a == character)
count++
@@ -608,8 +608,8 @@ GLOBAL_LIST_INIT(binary, list("0","1"))
continue
var/buffer = ""
var/early_culling = TRUE
for(var/pos = 1, pos <= lentext(string), pos++)
var/let = copytext(string, pos, (pos + 1) % lentext(string))
for(var/pos = 1, pos <= length(string), pos++)
var/let = copytext(string, pos, (pos + 1) % length(string))
if(early_culling && !findtext(let,GLOB.is_alphanumeric))
continue
early_culling = FALSE
@@ -617,9 +617,9 @@ GLOBAL_LIST_INIT(binary, list("0","1"))
if(!findtext(buffer,GLOB.is_alphanumeric))
continue
var/punctbuffer = ""
var/cutoff = lentext(buffer)
for(var/pos = lentext(buffer), pos >= 0, pos--)
var/let = copytext(buffer, pos, (pos + 1) % lentext(buffer))
var/cutoff = length(buffer)
for(var/pos = length(buffer), pos >= 0, pos--)
var/let = copytext(buffer, pos, (pos + 1) % length(buffer))
if(findtext(let,GLOB.is_alphanumeric))
break
if(findtext(let,GLOB.is_punctuation))
@@ -629,8 +629,8 @@ GLOBAL_LIST_INIT(binary, list("0","1"))
var/exclaim = FALSE
var/question = FALSE
var/periods = 0
for(var/pos = lentext(punctbuffer), pos >= 0, pos--)
var/punct = copytext(punctbuffer, pos, (pos + 1) % lentext(punctbuffer))
for(var/pos = length(punctbuffer), pos >= 0, pos--)
var/punct = copytext(punctbuffer, pos, (pos + 1) % length(punctbuffer))
if(!exclaim && findtext(punct,"!"))
exclaim = TRUE
if(!question && findtext(punct,"?"))
@@ -652,7 +652,7 @@ GLOBAL_LIST_INIT(binary, list("0","1"))
buffer = copytext(buffer, 1, cutoff) + punctbuffer
if(!findtext(buffer,GLOB.is_alphanumeric))
continue
if(!buffer || lentext(buffer) > 280 || lentext(buffer) <= cullshort || buffer in accepted)
if(!buffer || length(buffer) > 280 || length(buffer) <= cullshort || buffer in accepted)
continue
accepted += buffer
+2 -2
View File
@@ -9,8 +9,8 @@
return t
proc/TextPreview(var/string,var/len=40)
if(lentext(string) <= len)
if(!lentext(string))
if(length(string) <= len)
if(!length(string))
return "\[...\]"
else
return string
+6 -1
View File
@@ -451,10 +451,15 @@ Turf and target are separate in case you want to teleport some distance from a t
var/y = min(world.maxy, max(1, A.y + dy))
return locate(x,y,A.z)
#if DM_VERSION > 513
#warn if you're getting this warning it means 513 is stable
#warn and you should remove this tidbit
#endif
#if DM_VERSION < 513
/proc/arctan(x)
var/y=arcsin(x/sqrt(1+x*x))
return y
#endif
/*
Gets all contents of contents and returns them all in a list.
*/
+2
View File
@@ -26,6 +26,8 @@ GLOBAL_VAR(query_debug_log)
GLOBAL_PROTECT(query_debug_log)
GLOBAL_VAR(world_job_debug_log)
GLOBAL_PROTECT(world_job_debug_log)
GLOBAL_VAR(world_cloning_log)
GLOBAL_PROTECT(world_cloning_log)
GLOBAL_LIST_EMPTY(bombers)
GLOBAL_PROTECT(bombers)
@@ -39,6 +39,8 @@
/datum/config_entry/flag/log_game // log game events
/datum/config_entry/flag/log_cloning // log cloning actions.
/datum/config_entry/flag/log_vote // log voting
/datum/config_entry/flag/log_whisper // log client whisper
@@ -76,6 +78,16 @@
config_entry_value = 600
min_val = 0
/datum/config_entry/number/vote_autotransfer_initial //length of time before the first autotransfer vote is called (deciseconds, default 2 hours)
config_entry_value = 72000
integer = FALSE
min_val = 0
/datum/config_entry/number/vote_autotransfer_interval //length of time to wait before subsequent autotransfer votes (deciseconds, default 30 minutes)
config_entry_value = 18000
integer = FALSE
min_val = 0
/datum/config_entry/flag/default_no_vote // vote does not default to nochange/norestart
/datum/config_entry/flag/no_dead_vote // dead people can't vote
@@ -419,3 +431,4 @@
/datum/config_entry/flag/log_pictures
/datum/config_entry/flag/picture_logging_camera
@@ -0,0 +1,17 @@
SUBSYSTEM_DEF(autotransfer)
name = "Autotransfer Vote"
flags = SS_KEEP_TIMING | SS_BACKGROUND
wait = 1 MINUTES
var/starttime
var/targettime
/datum/controller/subsystem/autotransfer/Initialize(timeofday)
starttime = world.time
targettime = starttime + CONFIG_GET(number/vote_autotransfer_initial)
return ..()
/datum/controller/subsystem/autotransfer/fire()
if (world.time > targettime)
SSvote.initiate_vote("transfer",null) //TODO figure out how to not use null as the user
targettime = targettime + CONFIG_GET(number/vote_autotransfer_interval)
-2
View File
@@ -205,8 +205,6 @@ SUBSYSTEM_DEF(ticker)
mode.process(wait * 0.1)
check_queue()
check_maprotate()
scripture_states = scripture_unlock_alert(scripture_states)
SSshuttle.autoEnd()
if(!roundend_check_paused && mode.check_finished(force_ending) || force_ending)
current_state = GAME_STATE_FINISHED
+26 -1
View File
@@ -76,6 +76,21 @@ SUBSYSTEM_DEF(vote)
choices[GLOB.master_mode] += non_voters.len
if(choices[GLOB.master_mode] >= greatest_votes)
greatest_votes = choices[GLOB.master_mode]
else if(mode == "transfer") // austation begin -- Crew autotransfer vote
var/factor = 1
switch(world.time / (1 MINUTES ))
if(0 to 60)
factor = 0.5
if(61 to 120)
factor = 0.8
if(121 to 240)
factor = 1
if(241 to 300)
factor = 1.2
else
factor = 1.4
choices["Initiate Crew Transfer"] += round(non_voters.len * factor) // austation end
//get all options with that many votes and return them in a list
. = list()
if(greatest_votes)
@@ -152,6 +167,13 @@ SUBSYSTEM_DEF(vote)
log_admin("The map has been voted for and will change to: [VM.map_name]")
if(SSmapping.changemap(config.maplist[.]))
to_chat(world, "<span class='boldannounce'>The map vote has chosen [VM.map_name] for next round!</span>")
if("transfer") // austation begin -- Crew autotransfer vote
if(. == "Initiate Crew Transfer")
//TODO find a cleaner way to do this
SSshuttle.requestEvac(null,"Crew transfer requested.")
var/obj/machinery/computer/communications/C = locate() in GLOB.machines
if(C)
C.post_status("shuttle") // austation end
if(restart)
var/active_admins = 0
for(var/client/C in GLOB.admins)
@@ -200,6 +222,7 @@ SUBSYSTEM_DEF(vote)
to_chat(usr, "<span class='warning'>A vote was initiated recently, you must wait [DisplayTimeText(next_allowed_time-world.time)] before a new vote can be started!</span>")
return 0
SEND_SOUND(world, sound('sound/misc/notice2.ogg'))
reset()
obfuscated = hideresults //CIT CHANGE - adds obfuscated votes
switch(vote_type)
@@ -211,6 +234,8 @@ SUBSYSTEM_DEF(vote)
choices.Add(config.maplist)
for(var/i in choices)//this is necessary because otherwise we'll end up with a bunch of /datum/map_config's as the default vote value instead of 0 as intended
choices[i] = 0
if("transfer") // austation begin -- Crew autotranfer vote
choices.Add("Initiate Crew Transfer","Continue Playing") // austation end
if("roundtype") //CIT CHANGE - adds the roundstart secret/extended vote
choices.Add("secret", "extended")
if("custom")
@@ -225,7 +250,7 @@ SUBSYSTEM_DEF(vote)
else
return 0
mode = vote_type
initiator = initiator_key
initiator = initiator_key ? initiator_key : "the Server" // austation -- Crew autotransfer vote
started_time = world.time
var/text = "[capitalize(mode)] vote started by [initiator]."
if(mode == "custom")
+2 -2
View File
@@ -37,9 +37,9 @@
if(O.status == BODYPART_ROBOTIC)
return
var/feetCover = (H.wear_suit && (H.wear_suit.body_parts_covered & FEET)) || (H.w_uniform && (H.w_uniform.body_parts_covered & FEET))
var/feetCover = (H.wear_suit && (H.wear_suit.body_parts_covered & FEET)) || (H.w_uniform && (H.w_uniform.body_parts_covered & FEET) || (H.shoes && (H.shoes.body_parts_covered & FEET)))
if(!(flags & CALTROP_BYPASS_SHOES) && (H.shoes || feetCover))
if(!(flags & CALTROP_BYPASS_SHOES) && feetCover)
return
if((H.movement_type & FLYING) || H.buckled)
+3 -3
View File
@@ -89,19 +89,19 @@
return
if(ishuman(LM)) //for proper humans, they're special
var/mob/living/carbon/human/H = LM
var/feetCover = (H.wear_suit && (H.wear_suit.body_parts_covered & FEET)) || (H.w_uniform && (H.w_uniform.body_parts_covered & FEET))
var/feetCover = (H.wear_suit && (H.wear_suit.body_parts_covered & FEET)) || (H.w_uniform && (H.w_uniform.body_parts_covered & FEET) || (H.shoes && (H.shoes.body_parts_covered & FEET)))
if (H.dna.features["taur"] == "Naga" || H.dna.features["taur"] == "Tentacle") //are we a naga or tentacle taur creature
playsound(T, 'sound/effects/footstep/crawl1.ogg', 15 * v)
return
if(H.shoes || feetCover) //are we wearing shoes
if(feetCover) //are we wearing shoes
playsound(T, pick(GLOB.footstep[T.footstep][1]),
GLOB.footstep[T.footstep][2] * v,
TRUE,
GLOB.footstep[T.footstep][3] + e)
if((!H.shoes && !feetCover)) //are we NOT wearing shoes
if(!feetCover) //are we NOT wearing shoes
playsound(T, pick(GLOB.barefootstep[T.barefootstep][1]),
GLOB.barefootstep[T.barefootstep][2] * v,
TRUE,
+2 -2
View File
@@ -371,7 +371,7 @@
updateappearance(icon_update=0)
if(LAZYLEN(mutation_index))
dna.mutation_index = mutation_index
dna.mutation_index = mutation_index.Copy()
domutcheck()
if(mrace || newfeatures || ui)
@@ -616,4 +616,4 @@
else
gib()
else
set_species(/datum/species/dullahan)
set_species(/datum/species/dullahan)
+3
View File
@@ -62,6 +62,9 @@
var/unconvertable = FALSE
var/late_joiner = FALSE
var/last_death = 0
var/force_escaped = FALSE // Set by Into The Sunset command of the shuttle manipulator
var/list/learned_recipes //List of learned recipe TYPES.
+8
View File
@@ -598,6 +598,14 @@
/atom/proc/multitool_act(mob/living/user, obj/item/I)
return
///Check if the multitool has an item in it's data buffer
/atom/proc/multitool_check_buffer(user, obj/item/I, silent = FALSE)
if(!istype(I, /obj/item/multitool))
if(user && !silent)
to_chat(user, "<span class='warning'>[I] has no data buffer!</span>")
return FALSE
return TRUE
/atom/proc/screwdriver_act(mob/living/user, obj/item/I)
SEND_SIGNAL(src, COMSIG_ATOM_SCREWDRIVER_ACT, user, I)
+91 -37
View File
@@ -19,7 +19,7 @@
circuit = /obj/item/circuitboard/machine/clonepod
var/heal_level //The clone is released once its health reaches this level.
var/obj/machinery/computer/cloning/connected = null //So we remember the connected clone machine.
var/obj/machinery/computer/cloning/connected //So we remember the connected clone machine.
var/mess = FALSE //Need to clean out it if it's full of exploded clone.
var/attempting = FALSE //One clone attempt at a time thanks
var/speed_coeff
@@ -53,7 +53,10 @@
update_icon()
/obj/machinery/clonepod/Destroy()
var/mob/living/mob_occupant = occupant
go_out()
if(mob_occupant)
log_cloning("[key_name(mob_occupant)] ejected from [src] at [AREACOORD(src)] due to Destroy().")
QDEL_NULL(radio)
QDEL_NULL(countdown)
if(connected)
@@ -74,6 +77,23 @@
if(heal_level > 100)
heal_level = 100
/obj/machinery/clonepod/attack_hand(mob/user)
. = ..()
if(.)
return
user.examinate(src)
/obj/machinery/clonepod/attack_ai(mob/user)
return attack_hand(user)
/obj/machinery/clonepod/examine(mob/user)
. = ..()
. += "<span class='notice'>The <i>linking</i> device can be <i>scanned<i> with a multitool.</span>"
if(in_range(user, src) || isobserver(user))
. += "<span class='notice'>The status display reads: Cloning speed at <b>[speed_coeff*50]%</b>.<br>Predicted amount of cellular damage: <b>[100-heal_level]%</b>.</span>"
if(efficiency > 5)
. += "<span class='notice'>Pod has been upgraded to support autoprocessing and apply beneficial mutations.</span>"
//The return of data disks?? Just for transferring between genetics machine/cloning machine.
//TO-DO: Make the genetics machine accept them.
/obj/item/disk/data
@@ -102,7 +122,7 @@
//Clonepod
/obj/machinery/clonepod/examine(mob/user)
..()
. = ..()
var/mob/living/mob_occupant = occupant
if(mess)
to_chat(user, "It's filled with blood and viscera. You swear you can see it moving...")
@@ -129,44 +149,54 @@
return examine(user)
//Start growing a human clone in the pod!
/obj/machinery/clonepod/proc/growclone(ckey, clonename, ui, mutation_index, mindref, datum/species/mrace, list/features, factions, list/quirks)
/obj/machinery/clonepod/proc/growclone(clonename, ui, mutation_index, mindref, last_death, blood_type, datum/species/mrace, list/features, factions, list/quirks, empty)
if(panel_open)
return FALSE
if(mess || attempting)
return FALSE
clonemind = locate(mindref) in SSticker.minds
if(!istype(clonemind)) //not a mind
return FALSE
if(!QDELETED(clonemind.current))
if(clonemind.current.stat != DEAD) //mind is associated with a non-dead body
if(!empty) //Doesn't matter if we're just making a copy
clonemind = locate(mindref) in SSticker.minds
if(!istype(clonemind)) //not a mind
return FALSE
if(clonemind.current.suiciding) // Mind is associated with a body that is suiciding.
if(clonemind.last_death != last_death) //The soul has advanced, the record has not.
return FALSE
if(clonemind.active) //somebody is using that mind
if( ckey(clonemind.key)!=ckey )
if(!QDELETED(clonemind.current))
if(clonemind.current.stat != DEAD) //mind is associated with a non-dead body
return NONE
if(clonemind.current.suiciding) // Mind is associated with a body that is suiciding.
return NONE
if(!clonemind.active)
// get_ghost() will fail if they're unable to reenter their body
var/mob/dead/observer/G = clonemind.get_ghost()
if(!G)
return NONE
if(G.suiciding) // The ghost came from a body that is suiciding.
return NONE
if(clonemind.damnation_type) //Can't clone the damned.
INVOKE_ASYNC(src, .proc/horrifyingsound)
mess = TRUE
icon_state = "pod_g"
update_icon()
return FALSE
else
// get_ghost() will fail if they're unable to reenter their body
var/mob/dead/observer/G = clonemind.get_ghost()
if(!G)
return FALSE
if(G.suiciding) // The ghost came from a body that is suiciding.
return FALSE
if(clonemind.damnation_type) //Can't clone the damned.
INVOKE_ASYNC(src, .proc/horrifyingsound)
mess = TRUE
update_icon()
return FALSE
attempting = TRUE //One at a time!!
countdown.start()
var/mob/living/carbon/human/H = new /mob/living/carbon/human(src)
H.hardset_dna(ui, mutation_index, H.real_name, null, mrace, features)
H.hardset_dna(ui, mutation_index, H.real_name, blood_type, mrace, features)
if(prob(50 - efficiency*10)) //Chance to give a bad mutation.
H.easy_randmut(NEGATIVE+MINOR_NEGATIVE) //100% bad mutation. Can be cured with mutadone.
if(!HAS_TRAIT(H, TRAIT_RADIMMUNE))//dont apply mutations if the species is Mutation proof.
if(efficiency > 2)
var/list/unclean_mutations = (GLOB.not_good_mutations|GLOB.bad_mutations)
H.dna.remove_mutation_group(unclean_mutations)
if(efficiency > 5 && prob(20))
H.easy_randmut(POSITIVE)
if(efficiency < 3 && prob(50))
var/mob/M = H.easy_randmut(NEGATIVE+MINOR_NEGATIVE)
if(ismob(M))
H = M
H.silent = 20 //Prevents an extreme edge case where clones could speak if they said something at exactly the right moment.
occupant = H
@@ -184,15 +214,16 @@
ADD_TRAIT(H, TRAIT_NOCRITDAMAGE, "cloning")
H.Unconscious(80)
clonemind.transfer_to(H)
if(!empty)
clonemind.transfer_to(H)
if(grab_ghost_when == CLONER_FRESH_CLONE)
H.grab_ghost()
to_chat(H, "<span class='notice'><b>Consciousness slowly creeps over you as your body regenerates.</b><br><i>So this is what cloning feels like?</i></span>")
if(grab_ghost_when == CLONER_FRESH_CLONE)
H.grab_ghost()
to_chat(H, "<span class='notice'><b>Consciousness slowly creeps over you as your body regenerates.</b><br><i>So this is what cloning feels like?</i></span>")
if(grab_ghost_when == CLONER_MATURE_CLONE)
H.ghostize(TRUE) //Only does anything if they were still in their old body and not already a ghost
to_chat(H.get_ghost(TRUE), "<span class='notice'>Your body is beginning to regenerate in a cloning pod. You will become conscious when it is complete.</span>")
if(grab_ghost_when == CLONER_MATURE_CLONE)
H.ghostize(TRUE) //Only does anything if they were still in their old body and not already a ghost
to_chat(H.get_ghost(TRUE), "<span class='notice'>Your body is beginning to regenerate in a cloning pod. You will become conscious when it is complete.</span>")
if(H)
H.faction |= factions
@@ -206,7 +237,7 @@
H.suiciding = FALSE
attempting = FALSE
return TRUE
return CLONING_SUCCESS
//Grow clones to maturity then kick them out. FREELOADERS
/obj/machinery/clonepod/process()
@@ -215,16 +246,20 @@
if(!is_operational()) //Autoeject if power is lost
if(mob_occupant)
go_out()
log_cloning("[key_name(mob_occupant)] ejected from [src] at [AREACOORD(src)] due to power loss.")
mob_occupant.apply_vore_prefs()
connected_message("Clone Ejected: Loss of power.")
else if(mob_occupant && (mob_occupant.loc == src))
if((mob_occupant.stat == DEAD) || (mob_occupant.suiciding) || mob_occupant.hellbound) //Autoeject corpses and suiciding dudes.
if(mob_occupant && (mob_occupant.stat == DEAD) || (mob_occupant.suiciding) || mob_occupant.hellbound) //Autoeject corpses and suiciding dudes.
connected_message("Clone Rejected: Deceased.")
if(internal_radio)
SPEAK("The cloning has been \
aborted due to unrecoverable tissue failure.")
go_out()
log_cloning("[key_name(mob_occupant)] ejected from [src] at [AREACOORD(src)] after suiciding.")
mob_occupant.apply_vore_prefs()
else if(mob_occupant.cloneloss > (100 - heal_level))
@@ -272,10 +307,13 @@
BP.attach_limb(mob_occupant)
go_out()
log_cloning("[key_name(mob_occupant)] completed cloning cycle in [src] at [AREACOORD(src)].")
mob_occupant.apply_vore_prefs()
else if (!mob_occupant || mob_occupant.loc != src)
occupant = null
if (!mess && !panel_open)
icon_state = "pod_0"
use_power(200)
update_icon()
@@ -290,6 +328,8 @@
return
if(istype(W, /obj/item/multitool))
if(!multitool_check_buffer(user, W))
return
var/obj/item/multitool/P = W
if(istype(P.buffer, /obj/machinery/computer/cloning))
@@ -316,10 +356,13 @@
to_chat(user, "<span class='danger'>Error: Pod has no occupant.</span>")
return
else
add_fingerprint(user)
connected_message("Emergency Ejection")
SPEAK("An emergency ejection of the current clone has occurred. Survival not guaranteed.")
to_chat(user, "<span class='notice'>You force an emergency ejection. </span>")
go_out()
log_cloning("[key_name(user)] manually ejected [key_name(mob_occupant)] from [src] at [AREACOORD(src)].")
log_combat(user, mob_occupant, "ejected", W, "from [src]")
mob_occupant.apply_vore_prefs()
else
return ..()
@@ -329,6 +372,9 @@
return
to_chat(user, "<span class='warning'>You corrupt the genetic compiler.</span>")
malfunction()
add_fingerprint(user)
log_cloning("[key_name(user)] emagged [src] at [AREACOORD(src)], causing it to malfunction.")
log_combat(user, src, "emagged", null, occupant ? "[occupant] inside, killing them via malfunction." : null)
//Put messages in the connected computer's temp var for display.
/obj/machinery/clonepod/proc/connected_message(message)
@@ -381,6 +427,7 @@
unattached_flesh.Cut()
occupant = null
clonemind = null
/obj/machinery/clonepod/proc/malfunction()
var/mob/living/mob_occupant = occupant
@@ -391,13 +438,14 @@
mess = TRUE
maim_clone(mob_occupant) //Remove every bit that's grown back so far to drop later, also destroys bits that haven't grown yet
update_icon()
if(mob_occupant.mind != clonemind)
if(clonemind && mob_occupant.mind != clonemind)
clonemind.transfer_to(mob_occupant)
mob_occupant.grab_ghost() // We really just want to make you suffer.
flash_color(mob_occupant, flash_color="#960000", flash_time=100)
to_chat(mob_occupant, "<span class='warning'><b>Agony blazes across your consciousness as your body is torn apart.</b><br><i>Is this what dying is like? Yes it is.</i></span>")
playsound(src.loc, 'sound/machines/warning-buzzer.ogg', 50, 0)
SEND_SOUND(mob_occupant, sound('sound/hallucinations/veryfar_noise.ogg',0,1,50))
log_cloning("[key_name(mob_occupant)] destroyed within [src] at [AREACOORD(src)] due to malfunction.")
QDEL_IN(mob_occupant, 40)
/obj/machinery/clonepod/relaymove(mob/user)
@@ -416,11 +464,14 @@
SPEAK(Gibberish("Exposure to electromagnetic fields has caused the ejection of, ERROR: John Doe, prematurely." ,0))
mob_occupant.apply_vore_prefs()
go_out()
log_cloning("[key_name(mob_occupant)] ejected from [src] at [AREACOORD(src)] due to EMP pulse.")
/obj/machinery/clonepod/ex_act(severity, target)
..()
if(!QDELETED(src))
if(!QDELETED(src) && occupant)
var/mob/living/mob_occupant = occupant
go_out()
log_cloning("[key_name(mob_occupant)] ejected from [src] at [AREACOORD(src)] due to explosion.")
/obj/machinery/clonepod/handle_atom_del(atom/A)
if(A == occupant)
@@ -436,7 +487,9 @@
/obj/machinery/clonepod/deconstruct(disassembled = TRUE)
if(occupant)
var/mob/living/mob_occupant = occupant
go_out()
log_cloning("[key_name(mob_occupant)] ejected from [src] at [AREACOORD(src)] due to deconstruction.")
..()
/obj/machinery/clonepod/proc/maim_clone(mob/living/carbon/human/H)
@@ -552,3 +605,4 @@
#undef CLONE_INITIAL_DAMAGE
#undef SPEAK
#undef MINIMUM_HEAL_LEVEL
@@ -31,6 +31,7 @@
/obj/machinery/computer/camera_advanced/syndie
icon_keyboard = "syndie_key"
circuit = /obj/item/circuitboard/computer/advanced_camera
/obj/machinery/computer/camera_advanced/proc/CreateEye()
eyeobj = new()
+123 -63
View File
@@ -7,25 +7,24 @@
icon_keyboard = "med_key"
circuit = /obj/item/circuitboard/computer/cloning
req_access = list(ACCESS_HEADS) //ONLY USED FOR RECORD DELETION RIGHT NOW.
var/obj/machinery/dna_scannernew/scanner = null //Linked scanner. For scanning.
var/obj/machinery/dna_scannernew/scanner //Linked scanner. For scanning.
var/list/pods //Linked cloning pods
var/temp = "Inactive"
var/scantemp_ckey
var/scantemp = "Ready to Scan"
var/menu = 1 //Which menu screen to display
var/list/records = list()
var/datum/data/record/active_record = null
var/obj/item/disk/data/diskette = null //Mostly so the geneticist can steal everything.
var/loading = 0 // Nice loading text
var/autoprocess = 0
var/list/records = list()
light_color = LIGHT_COLOR_BLUE
/obj/machinery/computer/cloning/Initialize()
. = ..()
updatemodules(TRUE)
var/obj/item/circuitboard/computer/cloning/board = circuit
records = board.records
/obj/machinery/computer/cloning/Destroy()
@@ -39,7 +38,7 @@
if(pods)
for(var/P in pods)
var/obj/machinery/clonepod/pod = P
if(pod.occupant && pod.clonemind == mind)
if(pod.occupant && mind && pod.clonemind == mind)
return null
if(pod.is_operational() && !(pod.occupant || pod.mess))
return pod
@@ -60,6 +59,9 @@
else if(!. && pod.is_operational() && !(pod.occupant || pod.mess) && pod.efficiency > 5)
. = pod
/proc/grow_clone_from_record(obj/machinery/clonepod/pod, datum/data/record/R, empty)
return pod.growclone(R.fields["name"], R.fields["UI"], R.fields["SE"], R.fields["mindref"], R.fields["last_death"], R.fields["blood_type"], R.fields["mrace"], R.fields["features"], R.fields["factions"], R.fields["quirks"], empty)
/obj/machinery/computer/cloning/process()
if(!(scanner && LAZYLEN(pods) && autoprocess))
return
@@ -68,16 +70,19 @@
scan_occupant(scanner.occupant)
for(var/datum/data/record/R in records)
var/obj/machinery/clonepod/pod = GetAvailableEfficientPod(R.fields["mind"])
var/obj/machinery/clonepod/pod = GetAvailableEfficientPod(R.fields["mindref"])
if(!pod)
return
if(pod.occupant)
continue //how though?
continue
if(pod.growclone(R.fields["ckey"], R.fields["name"], R.fields["UI"], R.fields["SE"], R.fields["mind"], R.fields["mrace"], R.fields["features"], R.fields["factions"], R.fields["quirks"]))
var/result = grow_clone_from_record(pod, R)
if(result & CLONING_SUCCESS)
temp = "[R.fields["name"]] => <font class='good'>Cloning cycle in progress...</font>"
log_cloning("Cloning of [key_name(R.fields["mindref"])] automatically started via autoprocess - [src] at [AREACOORD(src)]. Pod: [pod] at [AREACOORD(pod)].")
if(result & CLONING_DELETE_RECORD)
records -= R
/obj/machinery/computer/cloning/proc/updatemodules(findfirstcloner)
@@ -132,7 +137,9 @@
to_chat(user, "<span class='notice'>You insert [W].</span>")
playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, 0)
src.updateUsrDialog()
else if(istype(W, /obj/item/multitool))
else if(W.tool_behaviour == TOOL_MULTITOOL)
if(!multitool_check_buffer(user, W))
return
var/obj/item/multitool/P = W
if(istype(P.buffer, /obj/machinery/clonepod))
@@ -201,6 +208,7 @@
if(scanner_occupant)
dat += "<a href='byond://?src=[REF(src)];scan=1'>Start Scan</a>"
dat += "<a href='byond://?src=[REF(src)];scan=1;body_only=1'>Body-Only Scan</a>"
dat += "<br><a href='byond://?src=[REF(src)];lock=1'>[src.scanner.locked ? "Unlock Scanner" : "Lock Scanner"]</a>"
else
dat += "<span class='linkOff'>Start Scan</span>"
@@ -228,8 +236,11 @@
if (!src.active_record)
dat += "<font class='bad'>Record not found.</font>"
else
dat += "<h4>[src.active_record.fields["name"]]</h4>"
dat += "Scan ID [src.active_record.fields["id"]] <a href='byond://?src=[REF(src)];clone=[active_record.fields["id"]]'>Clone</a><br>"
var/body_only = active_record.fields["body_only"]
dat += "<h4>[active_record.fields["name"]][body_only ? " - BODY-ONLY" : ""]</h4>"
dat += "Scan ID [active_record.fields["id"]] \
[!body_only ? "<a href='byond://?src=[REF(src)];clone=[active_record.fields["id"]]'>Clone</a>" : "" ]\
<a href='byond://?src=[REF(src)];clone=[active_record.fields["id"]];empty=TRUE'>Empty Clone</a><br>"
var/obj/item/implant/health/H = locate(src.active_record.fields["imp"])
@@ -239,7 +250,14 @@
dat += "<font class='bad'>Unable to locate Health Implant.</font><br /><br />"
dat += "<b>Unique Identifier:</b><br /><span class='highlight'>[src.active_record.fields["UI"]]</span><br>"
dat += "<b>Structural Enzymes:</b><br /><span class='highlight'>[src.active_record.fields["SE"]]</span><br>"
dat += "<b>Structural Enzymes:</b><br /><span class='highlight'>"
for(var/key in active_record.fields["SE"])
if(key != RACEMUT)
var/val = active_record.fields["SE"][key]
var/alias = GLOB.all_mutations[key].alias
dat +="[alias]: [val]<br />"
dat += "</span><br />"
if(diskette && diskette.fields)
dat += "<div class='block'>"
@@ -296,18 +314,13 @@
else if ((href_list["scan"]) && !isnull(scanner) && scanner.is_operational())
scantemp = ""
var/body_only = href_list["body_only"]
loading = 1
src.updateUsrDialog()
playsound(src, 'sound/machines/terminal_prompt.ogg', 50, 0)
say("Initiating scan...")
spawn(20)
src.scan_occupant(scanner.occupant)
loading = 0
src.updateUsrDialog()
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
addtimer(CALLBACK(src, .proc/do_scan, usr, body_only), 2 SECONDS)
//No locking an open scanner.
@@ -323,34 +336,42 @@
playsound(src, "terminal_type", 25, 0)
src.active_record = find_record("id", href_list["view_rec"], records)
if(active_record)
if(!active_record.fields["ckey"])
records -= active_record
active_record = null
src.temp = "<font class='bad'>Record Corrupt</font>"
else
src.menu = 3
menu = 3
else
src.temp = "Record missing."
temp = "Record missing."
else if (href_list["del_rec"])
if ((!src.active_record) || (src.menu < 3))
return
if (src.menu == 3) //If we are viewing a record, confirm deletion
src.temp = "Delete record?"
src.menu = 4
playsound(src, 'sound/machines/terminal_prompt.ogg', 50, 0)
var/has_access = FALSE
if(ishuman(usr))
var/mob/living/carbon/human/user = usr
var/obj/item/card/id/C = user.get_idcard(TRUE)
if(C)
if(check_access(C))
has_access = TRUE
if(active_record.fields["body_only"]) //Body-only scans are not as important and can be deleted freely
has_access = TRUE
if(has_access)
temp = "Delete record?"
menu = 4
playsound(src, 'sound/machines/terminal_prompt.ogg', 50, 0)
else
temp = "Access Denied"
menu = 2
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
else if (src.menu == 4)
var/obj/item/card/id/C = usr.get_active_held_item()
if (istype(C)||istype(C, /obj/item/pda))
if(src.check_access(C))
log_cloning("[key_name(usr)] deleted [key_name(active_record.fields["mindref"])]'s cloning records from [src] at [AREACOORD(src)].")
src.temp = "[src.active_record.fields["name"]] => Record deleted."
src.records.Remove(active_record)
active_record = null
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
src.menu = 2
var/obj/item/circuitboard/computer/cloning/board = circuit
board.records = records
else
src.temp = "<font class='bad'>Access Denied.</font>"
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
@@ -400,9 +421,14 @@
else if (href_list["clone"])
var/datum/data/record/C = find_record("id", href_list["clone"], records)
var/empty = href_list["empty"]
//Look for that player! They better be dead!
if(C)
if(C.fields["body_only"] && !empty)
temp = "<font class='bad'>Cannot initiate regular cloning with body-only scans.</font>"
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
var/obj/machinery/clonepod/pod = GetAvailablePod()
var/success = FALSE
//Can't clone without someone to clone. Or a pod. Or if the pod is busy. Or full of gibs.
if(!LAZYLEN(pods))
temp = "<font class='bad'>No Clonepods detected.</font>"
@@ -410,20 +436,33 @@
else if(!pod)
temp = "<font class='bad'>No Clonepods available.</font>"
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
else if(!CONFIG_GET(flag/revival_cloning))
else if(!CONFIG_GET(flag/revival_cloning) && !empty)
temp = "<font class='bad'>Unable to initiate cloning cycle.</font>"
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
else if(pod.occupant)
temp = "<font class='bad'>Cloning cycle already in progress.</font>"
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
else if(pod.growclone(C.fields["ckey"], C.fields["name"], C.fields["UI"], C.fields["SE"], C.fields["mind"], C.fields["mrace"], C.fields["features"], C.fields["factions"], C.fields["quirks"]))
temp = "[C.fields["name"]] => <font class='good'>Cloning cycle in progress...</font>"
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
records.Remove(C)
if(active_record == C)
active_record = null
menu = 1
else
var/result = grow_clone_from_record(pod, C, empty)
if(result & CLONING_SUCCESS)
temp = "[C.fields["name"]] => <font class='good'>Cloning cycle in progress...</font>"
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
records.Remove(C)
if(active_record == C)
active_record = null
menu = 1
success = TRUE
if(!empty)
log_cloning("[key_name(usr)] initiated cloning of [key_name(C.fields["mindref"])] via [src] at [AREACOORD(src)]. Pod: [pod] at [AREACOORD(pod)].")
else
log_cloning("[key_name(usr)] initiated EMPTY cloning of [key_name(C.fields["mindref"])] via [src] at [AREACOORD(src)]. Pod: [pod] at [AREACOORD(pod)].")
if(result & CLONING_DELETE_RECORD)
if(active_record == C)
active_record = null
menu = 1
records -= C
if(!success)
temp = "[C.fields["name"]] => <font class='bad'>Initialisation failure.</font>"
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
@@ -439,21 +478,31 @@
src.updateUsrDialog()
return
/obj/machinery/computer/cloning/proc/scan_occupant(occupant)
/obj/machinery/computer/cloning/proc/do_scan(mob/user, body_only)
scan_occupant(scanner.occupant, user, body_only)
loading = FALSE
updateUsrDialog()
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, FALSE)
/obj/machinery/computer/cloning/proc/scan_occupant(occupant, mob/M, body_only)
var/mob/living/mob_occupant = get_mob_or_brainmob(occupant)
var/datum/dna/dna
// Do not use unless you know what they are.
var/mob/living/carbon/C = mob_occupant
var/mob/living/brain/B = mob_occupant
if(ishuman(mob_occupant))
var/mob/living/carbon/C = mob_occupant
dna = C.has_dna()
if(isbrain(mob_occupant))
var/mob/living/brain/B = mob_occupant
dna = B.stored_dna
if(!istype(dna))
scantemp = "<font class='bad'>Unable to locate valid genetic data.</font>"
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
return
if(mob_occupant.suiciding || mob_occupant.hellbound)
if(!body_only && (mob_occupant.suiciding || mob_occupant.hellbound))
scantemp = "<font class='bad'>Subject's brain is not responding to scanning stimuli.</font>"
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
return
@@ -461,14 +510,14 @@
scantemp = "<font class='bad'>Subject no longer contains the fundamental materials required to create a living clone.</font>"
playsound(src, 'sound/machines/terminal_alert.ogg', 50, 0)
return
if ((!mob_occupant.ckey) || (!mob_occupant.client))
if (!body_only && isnull(mob_occupant.mind))
scantemp = "<font class='bad'>Mental interface failure.</font>"
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
return
if (find_record("ckey", mob_occupant.ckey, records))
scantemp = "<font class='average'>Subject already in database.</font>"
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
return
// if (find_record("ckey", mob_occupant.ckey, records))
// scantemp = "<font class='average'>Subject already in database.</font>"
// playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
// return
var/datum/data/record/R = new()
if(dna.species)
@@ -481,7 +530,7 @@
var/datum/species/rando_race = pick(GLOB.roundstart_races)
R.fields["mrace"] = rando_race.type
R.fields["ckey"] = mob_occupant.ckey
//R.fields["ckey"] = mob_occupant.ckey
R.fields["name"] = mob_occupant.real_name
R.fields["id"] = copytext(md5(mob_occupant.real_name), 2, 6)
R.fields["UE"] = dna.unique_enzymes
@@ -495,21 +544,32 @@
var/datum/quirk/T = V
R.fields["quirks"][T.type] = T.clone_data()
if (!isnull(mob_occupant.mind)) //Save that mind so traitors can continue traitoring after cloning.
R.fields["mind"] = "[REF(mob_occupant.mind)]"
R.fields["mindref"] = "[REF(mob_occupant.mind)]"
R.fields["last_death"] = mob_occupant.stat == DEAD ? mob_occupant.mind.last_death : -1
R.fields["body_only"] = body_only
//Add an implant if needed
var/obj/item/implant/health/imp
for(var/obj/item/implant/health/HI in mob_occupant.implants)
imp = HI
break
if(!imp)
imp = new /obj/item/implant/health(mob_occupant)
imp.implant(mob_occupant)
R.fields["imp"] = "[REF(imp)]"
if(!body_only)
//Add an implant if needed
var/obj/item/implant/health/imp
for(var/obj/item/implant/health/HI in mob_occupant.implants)
imp = HI
break
if(!imp)
imp = new /obj/item/implant/health(mob_occupant)
imp.implant(mob_occupant)
R.fields["imp"] = "[REF(imp)]"
var/datum/data/record/old_record = find_record("mindref", REF(mob_occupant.mind), records)
if(body_only)
old_record = find_record("UE", dna.unique_enzymes, records) //Body-only records cannot be identified by mind, so we use the DNA
if(old_record && ((old_record.fields["UI"] != dna.uni_identity) || (!old_record.fields["body_only"]))) //Never overwrite a mind-and-body record if it exists
old_record = null
if(old_record)
records -= old_record
scantemp = "Record updated."
else
scantemp = "Subject successfully scanned."
src.records += R
var/obj/item/circuitboard/computer/cloning/board = circuit
board.records = records
scantemp = "Subject successfully scanned."
log_cloning("[M ? key_name(M) : "Autoprocess"] added the [body_only ? "body-only " : ""]record of [key_name(mob_occupant)] to [src] at [AREACOORD(src)].")
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
+1
View File
@@ -332,6 +332,7 @@
C.bleed(DOOR_CRUSH_DAMAGE)
else
L.add_splatter_floor(location)
for(var/obj/mecha/M in get_turf(src))
M.take_damage(DOOR_CRUSH_DAMAGE)
+4 -3
View File
@@ -9,7 +9,7 @@
internal_radio = FALSE
//Start growing a human clone in the pod!
/obj/machinery/clonepod/experimental/growclone(ckey, clonename, ui, se, datum/species/mrace, list/features, factions)
/obj/machinery/clonepod/experimental/growclone(clonename, ui, mutation_index, mindref, last_death, blood_type, datum/species/mrace, list/features, factions, list/quirks, datum/bank_account/insurance)
if(panel_open)
return FALSE
if(mess || attempting)
@@ -20,7 +20,7 @@
var/mob/living/carbon/human/H = new /mob/living/carbon/human(src)
H.hardset_dna(ui, se, H.real_name, null, mrace, features)
H.hardset_dna(ui, mutation_index, H.real_name, blood_type, mrace, features)
if(efficiency > 2)
var/list/unclean_mutations = (GLOB.not_good_mutations|GLOB.bad_mutations)
@@ -292,6 +292,7 @@
temp = "<font class='bad'>Cloning cycle already in progress.</font>"
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
else
pod.growclone(null, mob_occupant.real_name, dna.uni_identity, dna.mutation_index, clone_species, dna.features, mob_occupant.faction)
pod.growclone(mob_occupant.real_name, dna.uni_identity, dna.mutation_index, null, null, dna.blood_type, clone_species, dna.features, mob_occupant.faction)
temp = "[mob_occupant.real_name] => <font class='good'>Cloning data sent to pod.</font>"
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
+1 -1
View File
@@ -515,7 +515,7 @@ GLOBAL_LIST_EMPTY(allCasters)
if(href_list["set_channel_name"])
channel_name = stripped_input(usr, "Provide a Feed Channel Name", "Network Channel Handler", "", MAX_NAME_LEN)
while (findtext(channel_name," ") == 1)
channel_name = copytext(channel_name,2,lentext(channel_name)+1)
channel_name = copytext(channel_name,2,length(channel_name)+1)
updateUsrDialog()
else if(href_list["set_channel_lock"])
c_locked = !c_locked
+1 -1
View File
@@ -243,7 +243,7 @@
else
line1 = "CARGO"
line2 = SSshuttle.supply.getTimerStr()
if(lentext(line2) > CHARS_PER_LINE)
if(length(line2) > CHARS_PER_LINE)
line2 = "Error"
update_display(line1, line2)
@@ -461,3 +461,56 @@
//NC.mergeConnectedNetworksOnTurf()
last_piece = NC
return 1
//Dunno where else to put this so shrug
/obj/item/mecha_parts/mecha_equipment/ripleyupgrade
name = "Ripley MK-II Conversion Kit"
desc = "A pressurized canopy attachment kit for an Autonomous Power Loader Unit \"Ripley\" MK-I mecha, to convert it to the slower, but space-worthy MK-II design. This kit cannot be removed, once applied."
icon_state = "ripleyupgrade"
/obj/item/mecha_parts/mecha_equipment/ripleyupgrade/can_attach(obj/mecha/working/ripley/M)
if(M.type != /obj/mecha/working/ripley)
to_chat(loc, "<span class='warning'>This conversion kit can only be applied to APLU MK-I models.</span>")
return FALSE
if(M.cargo.len)
to_chat(loc, "<span class='warning'>[M]'s cargo hold must be empty before this conversion kit can be applied.</span>")
return FALSE
if(!M.maint_access) //non-removable upgrade, so lets make sure the pilot or owner has their say.
to_chat(loc, "<span class='warning'>[M] must have maintenance protocols active in order to allow this conversion kit.</span>")
return FALSE
if(M.occupant) //We're actualy making a new mech and swapping things over, it might get weird if players are involved
to_chat(loc, "<span class='warning'>[M] must be unoccupied before this conversion kit can be applied.</span>")
return FALSE
if(!M.cell) //Turns out things break if the cell is missing
to_chat(loc, "<span class='warning'>The conversion process requires a cell installed.</span>")
return FALSE
return TRUE
/obj/item/mecha_parts/mecha_equipment/ripleyupgrade/attach(obj/mecha/M)
var/obj/mecha/working/ripley/mkii/N = new /obj/mecha/working/ripley/mkii(get_turf(M),1)
if(!N)
return
QDEL_NULL(N.cell)
if (M.cell)
N.cell = M.cell
M.cell.forceMove(N)
M.cell = null
N.step_energy_drain = M.step_energy_drain //For the scanning module
N.armor = N.armor.setRating(energy = M.armor["energy"]) //for the capacitor
for(var/obj/item/mecha_parts/E in M.contents)
// if(istype(E, /obj/item/mecha_parts/concealed_weapon_bay)) //why is the bay not just a variable change who did this
// E.forceMove(N)
for(var/obj/item/mecha_parts/mecha_equipment/E in M.equipment) //Move the equipment over...
E.detach()
E.attach(N)
M.equipment -= E
N.dna_lock = M.dna_lock
N.maint_access = M.maint_access
N.strafe = M.strafe
N.obj_integrity = M.obj_integrity //This is not a repair tool
if (M.name != "\improper APLU MK-I \"Ripley\"")
N.name = M.name
M.wreckage = 0
qdel(M)
playsound(get_turf(N),'sound/items/ratchet.ogg',50,1)
return
+73 -35
View File
@@ -18,7 +18,9 @@
var/list/queue = list()
var/processing_queue = 0
var/screen = "main"
var/link_on_init = TRUE
var/temp
var/datum/component/remote_materials/rmat
var/list/part_sets = list(
"Cyborg",
"Ripley",
@@ -33,13 +35,11 @@
"Misc"
)
/obj/machinery/mecha_part_fabricator/Initialize()
var/datum/component/material_container/materials = AddComponent(/datum/component/material_container,
list(MAT_METAL, MAT_GLASS, MAT_SILVER, MAT_GOLD, MAT_DIAMOND, MAT_PLASMA, MAT_URANIUM, MAT_BANANIUM, MAT_TITANIUM, MAT_BLUESPACE), 0,
TRUE, /obj/item/stack, CALLBACK(src, .proc/is_insertion_ready), CALLBACK(src, .proc/AfterMaterialInsert))
materials.precise_insertion = TRUE
stored_research = new
return ..()
/obj/machinery/mecha_part_fabricator/Initialize(mapload)
stored_research = new
rmat = AddComponent(/datum/component/remote_materials, "mechfab", mapload && link_on_init)
RefreshParts() //Recalculating local material sizes if the fab isn't linked
return ..()
/obj/machinery/mecha_part_fabricator/RefreshParts()
var/T = 0
@@ -47,8 +47,7 @@
//maximum stocking amount (default 300000, 600000 at T4)
for(var/obj/item/stock_parts/matter_bin/M in component_parts)
T += M.rating
GET_COMPONENT(materials, /datum/component/material_container)
materials.max_amount = (200000 + (T*50000))
rmat.set_local_size((200000 + (T*50000)))
//resources adjustment coefficient (1 -> 0.85 -> 0.7 -> 0.55)
T = 1.15
@@ -62,6 +61,12 @@
T += Ml.rating
time_coeff = round(initial(time_coeff) - (initial(time_coeff)*(T))/5,0.01)
/obj/machinery/mecha_part_fabricator/examine(mob/user)
. = ..()
if(in_range(user, src) || isobserver(user))
. += "<span class='notice'>The status display reads: Storing up to <b>[rmat.local_size]</b> material units.<br>Material consumption at <b>[component_coeff*100]%</b>.<br>Build time reduced by <b>[100-time_coeff*100]%</b>.<span>"
/obj/machinery/mecha_part_fabricator/emag_act()
if(obj_flags & EMAGGED)
@@ -104,16 +109,22 @@
/obj/machinery/mecha_part_fabricator/proc/output_available_resources()
var/output
GET_COMPONENT(materials, /datum/component/material_container)
for(var/mat_id in materials.materials)
var/datum/material/M = materials.materials[mat_id]
output += "<span class=\"res_name\">[M.name]: </span>[M.amount] cm&sup3;"
if(M.amount >= MINERAL_MATERIAL_AMOUNT)
output += "<span style='font-size:80%;'>- Remove \[<a href='?src=[REF(src)];remove_mat=1;material=[mat_id]'>1</a>\]"
if(M.amount >= (MINERAL_MATERIAL_AMOUNT * 10))
output += " | \[<a href='?src=[REF(src)];remove_mat=10;material=[mat_id]'>10</a>\]"
output += " | \[<a href='?src=[REF(src)];remove_mat=50;material=[mat_id]'>All</a>\]</span>"
output += "<br/>"
var/datum/component/material_container/materials = rmat.mat_container
if(materials)
for(var/mat_id in materials.materials)
var/datum/material/M = mat_id
var/amount = materials.materials[mat_id]
var/ref = REF(M)
output += "<span class=\"res_name\">[M.name]: </span>[amount] cm&sup3;"
if(amount >= MINERAL_MATERIAL_AMOUNT)
output += "<span style='font-size:80%;'>- Remove \[<a href='?src=[REF(src)];remove_mat=1;material=[ref]'>1</a>\]"
if(amount >= (MINERAL_MATERIAL_AMOUNT * 10))
output += " | \[<a href='?src=[REF(src)];remove_mat=10;material=[ref]'>10</a>\]"
output += " | \[<a href='?src=[REF(src)];remove_mat=50;material=[ref]'>50</a>\]</span>"
output += "<br>"
else
output += "<font color='red'>No material storage connected, please contact the quartermaster.</font><br>"
return output
/obj/machinery/mecha_part_fabricator/proc/get_resources_w_coeff(datum/design/D)
@@ -125,18 +136,29 @@
/obj/machinery/mecha_part_fabricator/proc/check_resources(datum/design/D)
if(D.reagents_list.len) // No reagents storage - no reagent designs.
return FALSE
GET_COMPONENT(materials, /datum/component/material_container)
var/datum/component/material_container/materials = rmat.mat_container
if(materials.has_materials(get_resources_w_coeff(D)))
return TRUE
return FALSE
/obj/machinery/mecha_part_fabricator/proc/build_part(datum/design/D)
being_built = D
desc = "It's building \a [initial(D.name)]."
var/list/res_coef = get_resources_w_coeff(D)
GET_COMPONENT(materials, /datum/component/material_container)
var/datum/component/material_container/materials = rmat.mat_container
if (!materials)
say("No access to material storage, please contact the quartermaster.")
return FALSE
if (rmat.on_hold())
say("Mineral access is on hold, please contact the quartermaster.")
return FALSE
if(!check_resources(D))
say("Not enough resources. Queue processing stopped.")
return FALSE
being_built = D
desc = "It's building \a [initial(D.name)]."
materials.use_amount(res_coef)
rmat.silo_log(src, "built", -1, "[D.name]", res_coef)
add_overlay("fab-active")
use_power = ACTIVE_POWER_USE
updateUsrDialog()
@@ -191,13 +213,10 @@
while(D)
if(stat&(NOPOWER|BROKEN))
return FALSE
if(!check_resources(D))
say("Not enough resources. Queue processing stopped.")
temp = {"<span class='alert'>Not enough resources to build next part.</span><br>
<a href='?src=[REF(src)];process_queue=1'>Try again</a> | <a href='?src=[REF(src)];clear_temp=1'>Return</a><a>"}
if(build_part(D))
remove_from_queue(1)
else
return FALSE
remove_from_queue(1)
build_part(D)
D = listgetindex(queue, 1)
say("Queue processing finished successfully.")
@@ -379,16 +398,32 @@
break
if(href_list["remove_mat"] && href_list["material"])
GET_COMPONENT(materials, /datum/component/material_container)
materials.retrieve_sheets(text2num(href_list["remove_mat"]), href_list["material"])
var/datum/material/Mat = locate(href_list["material"])
eject_sheets(Mat, text2num(href_list["remove_mat"]))
updateUsrDialog()
return
/obj/machinery/mecha_part_fabricator/on_deconstruction()
GET_COMPONENT(materials, /datum/component/material_container)
materials.retrieve_all()
..()
/obj/machinery/mecha_part_fabricator/proc/do_process_queue()
if(processing_queue || being_built)
return FALSE
processing_queue = 1
process_queue()
processing_queue = 0
/obj/machinery/mecha_part_fabricator/proc/eject_sheets(eject_sheet, eject_amt)
var/datum/component/material_container/mat_container = rmat.mat_container
if (!mat_container)
say("No access to material storage, please contact the quartermaster.")
return 0
if (rmat.on_hold())
say("Mineral access is on hold, please contact the quartermaster.")
return 0
var/count = mat_container.retrieve_sheets(text2num(eject_amt), eject_sheet, drop_location())
var/list/matlist = list()
matlist[eject_sheet] = text2num(eject_amt)
rmat.silo_log(src, "ejected", -count, "sheets", matlist)
return count
/obj/machinery/mecha_part_fabricator/proc/AfterMaterialInsert(type_inserted, id_inserted, amount_inserted)
var/stack_name = material2name(id_inserted)
@@ -417,3 +452,6 @@
return FALSE
return TRUE
/obj/machinery/mecha_part_fabricator/maint
link_on_init = FALSE
+34 -5
View File
@@ -69,6 +69,12 @@
var/melee_cooldown = 10
var/melee_can_hit = 1
var/silicon_pilot = FALSE //set to true if an AI or MMI is piloting.
var/enter_delay = 40 //Time taken to enter the mech
var/enclosed = TRUE //Set to false for open-cockpit mechs
var/silicon_icon_state = null //if the mech has a different icon when piloted by an AI or MMI
//Action datums
var/datum/action/innate/mecha/mech_eject/eject_action = new
var/datum/action/innate/mecha/mech_toggle_internals/internals_action = new
@@ -116,7 +122,8 @@
icon_state += "-open"
add_radio()
add_cabin()
add_airtank()
if (enclosed)
add_airtank()
spark_system.set_up(2, 0, src)
spark_system.attach(src)
smoke_system.set_up(3, src)
@@ -133,6 +140,11 @@
diag_hud_set_mechcell()
diag_hud_set_mechstat()
/obj/mecha/update_icon()
if (silicon_pilot && silicon_icon_state)
icon_state = silicon_icon_state
. = ..()
/obj/mecha/get_cell()
return cell
@@ -273,6 +285,11 @@
to_chat(user, "It's equipped with:")
for(var/obj/item/mecha_parts/mecha_equipment/ME in equipment)
to_chat(user, "[icon2html(ME, user)] \A [ME].")
if(!enclosed)
if(silicon_pilot)
to_chat(user, "[src] appears to be piloting itself...")
else if(occupant && occupant != user) //!silicon_pilot implied
to_chat(user, "You can see [occupant] inside.")
//processing internal damage, temperature, air regulation, alert updates, lights power use.
/obj/mecha/process()
@@ -392,13 +409,19 @@
diag_hud_set_mechcell()
diag_hud_set_mechstat()
/obj/mecha/fire_act() //Check if we should ignite the pilot of an open-canopy mech
if (occupant && !enclosed && !silicon_pilot)
if (occupant.fire_stacks < 5)
occupant.fire_stacks += 1
occupant.IgniteMob()
/obj/mecha/proc/drop_item()//Derpfix, but may be useful in future for engineering exosuits.
return
/obj/mecha/Hear(message, atom/movable/speaker, message_language, raw_message, radio_freq, list/spans, message_mode)
. = ..()
if(speaker == occupant)
if(radio.broadcasting)
if(radio?.broadcasting)
radio.talk_into(speaker, text, , spans, message_language)
//flick speech bubble
var/list/speech_bubble_recipients = list()
@@ -474,7 +497,7 @@
. = ..()
if(.)
events.fireEvent("onMove",get_turf(src))
if (internal_tank.disconnect()) // Something moved us and broke connection
if (internal_tank?.disconnect()) // Something moved us and broke connection
occupant_message("<span class='warning'>Air port connection teared off!</span>")
log_message("Lost connection to gas port.")
@@ -500,7 +523,7 @@
user.forceMove(get_turf(src))
to_chat(user, "<span class='notice'>You climb out from [src].</span>")
return 0
if(internal_tank.connected_port)
if(internal_tank?.connected_port)
if(world.time - last_message > 20)
occupant_message("<span class='warning'>Unable to move while connected to the air system port!</span>")
last_message = world.time
@@ -688,6 +711,7 @@
AI.disconnect_shell()
RemoveActions(AI, TRUE)
occupant = null
silicon_pilot = FALSE
AI.forceMove(card)
card.AI = AI
AI.controlled_mech = null
@@ -729,7 +753,9 @@
AI.ai_restore_power()
AI.forceMove(src)
occupant = AI
silicon_pilot = TRUE
icon_state = initial(icon_state)
update_icon()
playsound(src, 'sound/machines/windowdoor.ogg', 50, 1)
if(!internal_damage)
SEND_SOUND(occupant, sound('sound/mecha/nominal.ogg',volume=50))
@@ -832,7 +858,7 @@
visible_message("[user] starts to climb into [name].")
if(do_after(user, 40, target = src))
if(do_after(user, enter_delay, target = src))
if(obj_integrity <= 0)
to_chat(user, "<span class='warning'>You cannot get in the [name], it has been destroyed!</span>")
else if(occupant)
@@ -905,6 +931,7 @@
var/mob/living/brainmob = mmi_as_oc.brainmob
mmi_as_oc.mecha = src
occupant = brainmob
silicon_pilot = TRUE
brainmob.forceMove(src) //should allow relaymove
brainmob.reset_perspective(src)
brainmob.remote_control = src
@@ -946,6 +973,7 @@
RemoveActions(occupant)
occupant.gib() //If one Malf decides to steal a mech from another AI (even other Malfs!), they are destroyed, as they have nowhere to go when replaced.
occupant = null
silicon_pilot = FALSE
return
else
if(!AI.linked_core)
@@ -963,6 +991,7 @@
return
var/mob/living/L = occupant
occupant = null //we need it null when forceMove calls Exited().
silicon_pilot = FALSE
if(mob_container.forceMove(newloc))//ejecting mob container
log_message("[mob_container] moved out.")
L << browse(null, "window=exosuit")
+2 -1
View File
@@ -3,7 +3,8 @@
/obj/mecha/proc/GrantActions(mob/living/user, human_occupant = 0)
if(human_occupant)
eject_action.Grant(user, src)
internals_action.Grant(user, src)
if(enclosed)
internals_action.Grant(user, src)
cycle_action.Grant(user, src)
lights_action.Grant(user, src)
stats_action.Grant(user, src)
+7 -14
View File
@@ -171,36 +171,29 @@
list(
"key" = TOOL_WRENCH,
"back_key" = TOOL_CROWBAR,
"desc" = "Internal armor is installed."
"desc" = "Outer plating is installed."
),
//17
list(
"key" = TOOL_WELDER,
"back_key" = TOOL_WRENCH,
"desc" = "Internal armor is wrenched."
"desc" = "Outer Plating is wrenched."
),
//18
list(
"key" = /obj/item/stack/sheet/plasteel,
"amount" = 5,
"key" = /obj/item/stack/rods,
"amount" = 10,
"back_key" = TOOL_WELDER,
"desc" = "Internal armor is welded."
"desc" = "Outer Plating is welded."
),
//19
list(
"key" = TOOL_WRENCH,
"back_key" = TOOL_CROWBAR,
"desc" = "External armor is installed."
),
//20
list(
"key" = TOOL_WELDER,
"back_key" = TOOL_WRENCH,
"desc" = "External armor is wrenched."
"back_key" = TOOL_WIRECUTTER,
"desc" = "Cockpit wire screen is installed."
),
)
+1 -1
View File
@@ -76,7 +76,7 @@
var/answer = {"<b>Name:</b> [M.name]
<b>Integrity:</b> [M.obj_integrity/M.max_integrity*100]%
<b>Cell charge:</b> [isnull(cell_charge)?"Not found":"[M.cell.percent()]%"]
<b>Airtank:</b> [M.return_pressure()]kPa
<b>Airtank:</b> [M.internal_tank?"[round(M.return_pressure(), 0.01)]":"Not Equipped"] kPa<br>
<b>Pilot:</b> [M.occupant||"None"]
<b>Location:</b> [get_area(M)||"Unknown"]
<b>Active equipment:</b> [M.selected||"None"] "}
+3
View File
@@ -114,6 +114,9 @@
/obj/mecha/bullet_act(obj/item/projectile/Proj) //wrapper
if (!enclosed && occupant && !silicon_pilot) //allows bullets to hit the pilot of open-canopy mechs
occupant.bullet_act(Proj) //If the sides are open, the occupant can be hit
return BULLET_ACT_HIT
log_message("Hit by projectile. Type: [Proj.name]([Proj.flag]).", color="red")
. = ..()
+22 -17
View File
@@ -71,19 +71,24 @@
/obj/mecha/proc/get_stats_part()
var/integrity = obj_integrity/max_integrity*100
var/cell_charge = get_charge()
var/datum/gas_mixture/int_tank_air = internal_tank.return_air()
var/tank_pressure = internal_tank ? round(int_tank_air.return_pressure(),0.01) : "None"
var/tank_temperature = internal_tank ? int_tank_air.temperature : "Unknown"
var/cabin_pressure = round(return_pressure(),0.01)
var/datum/gas_mixture/int_tank_air = 0
var/tank_pressure = 0
var/tank_temperature = 0
var/cabin_pressure = 0
if (internal_tank)
int_tank_air = internal_tank.return_air()
tank_pressure = internal_tank ? round(int_tank_air.return_pressure(),0.01) : "None"
tank_temperature = internal_tank ? int_tank_air.temperature : "Unknown"
cabin_pressure = round(return_pressure(),0.01)
. = {"[report_internal_damage()]
[integrity<30?"<span class='userdanger'>DAMAGE LEVEL CRITICAL</span><br>":null]
<b>Integrity: </b> [integrity]%<br>
<b>Powercell charge: </b>[isnull(cell_charge)?"No powercell installed":"[cell.percent()]%"]<br>
<b>Air source: </b>[use_internal_tank?"Internal Airtank":"Environment"]<br>
<b>Airtank pressure: </b>[tank_pressure]kPa<br>
<b>Airtank temperature: </b>[tank_temperature]&deg;K|[tank_temperature - T0C]&deg;C<br>
<b>Cabin pressure: </b>[cabin_pressure>WARNING_HIGH_PRESSURE ? "<span class='danger'>[cabin_pressure]</span>": cabin_pressure]kPa<br>
<b>Cabin temperature: </b> [return_temperature()]&deg;K|[return_temperature() - T0C]&deg;C<br>
<b>Air source: </b>[internal_tank?"[use_internal_tank?"Internal Airtank":"Environment"]":"Environment"]<br>
<b>Airtank pressure: </b>[internal_tank?"[tank_pressure]kPa":"N/A"]<br>
<b>Airtank temperature: </b>[internal_tank?"[tank_temperature]&deg;K|[tank_temperature - T0C]&deg;C":"N/A"]<br>
<b>Cabin pressure: </b>[internal_tank?"[cabin_pressure>WARNING_HIGH_PRESSURE ? "<span class='danger'>[cabin_pressure]</span>": cabin_pressure]kPa":"N/A"]<br>
<b>Cabin temperature: </b> [internal_tank?"[return_temperature()]&deg;K|[return_temperature() - T0C]&deg;C":"N/A"]<br>
[dna_lock?"<b>DNA-locked:</b><br> <span style='font-size:10px;letter-spacing:-1px;'>[dna_lock]</span> \[<a href='?src=[REF(src)];reset_dna=1'>Reset</a>\]<br>":""]<br>
[thrusters_action.owner ? "<b>Thrusters: </b> [thrusters_active ? "Enabled" : "Disabled"]<br>" : ""]
[defense_action.owner ? "<b>Defence Mode: </b> [defence_mode ? "Enabled" : "Disabled"]<br>" : ""]
@@ -100,14 +105,14 @@
<div class='header'>Electronics</div>
<div class='links'>
<b>Radio settings:</b><br>
Microphone: <a href='?src=[REF(src)];rmictoggle=1'><span id="rmicstate">[radio.broadcasting?"Engaged":"Disengaged"]</span></a><br>
Speaker: <a href='?src=[REF(src)];rspktoggle=1'><span id="rspkstate">[radio.listening?"Engaged":"Disengaged"]</span></a><br>
Microphone: [radio? "<a href='?src=[REF(src)];rmictoggle=1'><span id=\"rmicstate\">[radio.broadcasting?"Engaged":"Disengaged"]</span></a>":"Error"]<br>
Speaker: [radio? "<a href='?src=[REF(src)];rspktoggle=1'><span id=\"rspkstate\">[radio.listening?"Engaged":"Disengaged"]</span></a>":"Error"]<br>
Frequency:
<a href='?src=[REF(src)];rfreq=-10'>-</a>
<a href='?src=[REF(src)];rfreq=-2'>-</a>
<span id="rfreq">[format_frequency(radio.frequency)]</span>
<a href='?src=[REF(src)];rfreq=2'>+</a>
<a href='?src=[REF(src)];rfreq=10'>+</a><br>
[radio? "<a href='?src=[REF(src)];rfreq=-10'>-</a>":"-"]
[radio? "<a href='?src=[REF(src)];rfreq=-2'>-</a>":"-"]
<span id="rfreq">[radio?"[format_frequency(radio.frequency)]":"Error"]</span>
[radio? "<a href='?src=[REF(src)];rfreq=2'>+</a>":"+"]
[radio? "<a href='?src=[REF(src)];rfreq=10'>+</a><br>":"+"]
</div>
</div>
<div class='wr'>
@@ -115,7 +120,7 @@
<div class='links'>
<a href='?src=[REF(src)];toggle_id_upload=1'><span id='t_id_upload'>[add_req_access?"L":"Unl"]ock ID upload panel</span></a><br>
<a href='?src=[REF(src)];toggle_maint_access=1'><span id='t_maint_access'>[maint_access?"Forbid":"Permit"] maintenance protocols</span></a><br>
<a href='?src=[REF(src)];toggle_port_connection=1'><span id='t_port_connection'>[internal_tank.connected_port?"Disconnect from":"Connect to"] gas port</span></a><br>
[internal_tank?"<a href='?src=[REF(src)];toggle_port_connection=1'><span id='t_port_connection'>[internal_tank.connected_port?"Disconnect from":"Connect to"] gas port</span></a><br>":""]
<a href='?src=[REF(src)];dna_lock=1'>DNA-lock</a><br>
<a href='?src=[REF(src)];view_log=1'>View internal log</a><br>
<a href='?src=[REF(src)];change_name=1'>Change exosuit name</a><br>
+16
View File
@@ -161,6 +161,22 @@
welder_salvage += part
parts -= part
/obj/structure/mecha_wreckage/ripley/mkii
name = "\improper Ripley MK-II wreckage"
icon_state = "ripleymkii-broken"
/obj/structure/mecha_wreckage/ripley/mkii/Initialize()
. = ..()
var/list/parts = list(/obj/item/mecha_parts/part/ripley_torso,
/obj/item/mecha_parts/part/ripley_left_arm,
/obj/item/mecha_parts/part/ripley_right_arm,
/obj/item/mecha_parts/part/ripley_left_leg,
/obj/item/mecha_parts/part/ripley_right_leg)
for(var/i = 0; i < 2; i++)
if(parts.len && prob(40))
var/part = pick(parts)
welder_salvage += part
parts -= part
/obj/structure/mecha_wreckage/ripley/firefighter
name = "\improper Firefighter wreckage"
+44 -10
View File
@@ -1,10 +1,11 @@
/obj/mecha/working/ripley
desc = "Autonomous Power Loader Unit. This newer model is refitted with powerful armour against the dangers of planetary mining."
name = "\improper APLU \"Ripley\""
desc = "Autonomous Power Loader Unit MK-I. Designed primarily around heavy lifting, the Ripley can be outfitted with utility equipment to fill a number of roles."
name = "\improper APLU MK-I \"Ripley\""
icon_state = "ripley"
step_in = 3 //Move speed, lower is faster.
var/fast_pressure_step_in = 2
var/slow_pressure_step_in = 3
silicon_icon_state = "ripley-empty"
step_in = 1.5 //Move speed, lower is faster.
var/fast_pressure_step_in = 1.5 //step_in while in low pressure conditions
var/slow_pressure_step_in = 2.0 //step_in while in normal pressure conditions
max_temperature = 20000
max_integrity = 200
lights_power = 8
@@ -15,6 +16,9 @@
var/list/cargo = new
var/cargo_capacity = 15
var/hides = 0
enclosed = FALSE //Normal ripley has an open cockpit design
enter_delay = 10 //can enter in a quarter of the time of other mechs
opacity = FALSE //Ripley has a window
/obj/mecha/working/ripley/Move()
. = ..()
@@ -55,18 +59,38 @@
else
add_overlay(occupant ? "ripley-g-full" : "ripley-g-full-open")
/obj/mecha/working/ripley/check_for_internal_damage(list/possible_int_damage,ignore_threshold=null)
if (!enclosed)
possible_int_damage -= (MECHA_INT_TEMP_CONTROL + MECHA_INT_TANK_BREACH) //if we don't even have an air tank, these two doesn't make a ton of sense.
. = ..()
/obj/mecha/working/ripley/Initialize()
. = ..()
AddComponent(/datum/component/armor_plate,3,/obj/item/stack/sheet/animalhide/goliath_hide,list("melee" = 10, "bullet" = 5, "laser" = 5))
/obj/mecha/working/ripley/mkii
desc = "Autonomous Power Loader Unit MK-II. This prototype Ripley is refitted with a pressurized cabin, trading its prior speed for atmospheric protection"
name = "\improper APLU MK-II \"Ripley\""
icon_state = "ripleymkii"
fast_pressure_step_in = 2 //step_in while in low pressure conditions
slow_pressure_step_in = 4 //step_in while in normal pressure conditions
step_in = 4
armor = list("melee" = 40, "bullet" = 20, "laser" = 10, "energy" = 20, "bomb" = 40, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100)
wreckage = /obj/structure/mecha_wreckage/ripley/mkii
enclosed = TRUE
enter_delay = 40
silicon_icon_state = null
opacity = TRUE
/obj/mecha/working/ripley/firefighter
desc = "Autonomous Power Loader Unit. This model is refitted with additional thermal protection."
name = "\improper APLU \"Firefighter\""
desc = "Autonomous Power Loader Unit MK-III. This model is refitted with a pressurized cabin and additional thermal protection."
name = "\improper APLU MK-III \"Firefighter\""
icon_state = "firefighter"
step_in = 4
fast_pressure_step_in = 2
slow_pressure_step_in = 4
fast_pressure_step_in = 2 //step_in while in low pressure conditions
slow_pressure_step_in = 4 //step_in while in normal pressure conditions
step_in = 4
max_temperature = 65000
max_integrity = 250
resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF
@@ -74,6 +98,10 @@
armor = list("melee" = 40, "bullet" = 30, "laser" = 30, "energy" = 30, "bomb" = 60, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100)
max_equip = 5 // More armor, less tools
wreckage = /obj/structure/mecha_wreckage/ripley/firefighter
enclosed = TRUE
enter_delay = 40
silicon_icon_state = null
opacity = TRUE
/obj/mecha/working/ripley/deathripley
@@ -81,11 +109,17 @@
name = "\improper DEATH-RIPLEY"
icon_state = "deathripley"
armor = list("melee" = 40, "bullet" = 30, "laser" = 20, "energy" = 20, "bomb" = 40, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100)
slow_pressure_step_in = 3
fast_pressure_step_in = 2 //step_in while in low pressure conditions
slow_pressure_step_in = 4 //step_in while in normal pressure conditions
step_in = 4
opacity=0
lights_power = 7
wreckage = /obj/structure/mecha_wreckage/ripley/deathripley
step_energy_drain = 0
enclosed = TRUE
enter_delay = 40
silicon_icon_state = null
opacity = TRUE
/obj/mecha/working/ripley/deathripley/Initialize()
. = ..()
+198
View File
@@ -861,3 +861,201 @@ CIGARETTE PACKETS ARE IN FANCY.DM
if(reagents && reagents.total_volume)
hand_reagents()
///////////////
/////BONGS/////
///////////////
/obj/item/bong
name = "bong"
desc = "A water bong used for smoking dried plants."
icon = 'icons/obj/bongs.dmi'
icon_state = null
item_state = null
w_class = WEIGHT_CLASS_NORMAL
light_color = "#FFCC66"
var/icon_off = "bong"
var/icon_on = "bong_lit"
var/chem_volume = 100
var/last_used_time //for cooldown
var/firecharges = 0 //used for counting how many hits can be taken before the flame goes out
var/list/list_reagents = list() //For the base reagents bongs could get
/obj/item/bong/Initialize()
. = ..()
create_reagents(chem_volume, NO_REACT) // so it doesn't react until you light it
reagents.add_reagent_list(list_reagents)
icon_state = icon_off
/obj/item/bong/attackby(obj/item/O, mob/user, params)
. = ..()
//If we're using a dried plant..
if(istype(O,/obj/item/reagent_containers/food/snacks))
var/obj/item/reagent_containers/food/snacks/DP = O
if (DP.dry)
//Nothing if our bong is full
if (reagents.holder_full())
user.show_message("<span class='notice'>The bowl is full!</span>", 1)
return
//Transfer reagents and remove the plant
user.show_message("<span class='notice'>You stuff the [DP] into the [src]'s bowl.</span>", 1)
DP.reagents.trans_to(src, 100)
qdel(DP)
return
else
user.show_message("<span class='warning'>[DP] must be dried first!</span>", 1)
return
if (O.heat > 500)
if (reagents && reagents.total_volume) //if there's stuff in the bong
var/lighting_text = O.ignition_effect(src, user)
if(lighting_text)
//Logic regarding igniting it on
if (firecharges == 0)
user.show_message("<span class='notice'>You light the [src] with the [O]!</span>", 1)
bongturnon()
else
user.show_message("<span class='notice'>You rekindle [src]'s flame with the [O]!</span>", 1)
firecharges = 1
return
else
user.show_message("<span warning='notice'>There's nothing to light up in the bowl.</span>", 1)
return
/obj/item/bong/CtrlShiftClick(mob/user) //empty reagents on alt click
if(!istype(user) || !user.canUseTopic(src, BE_CLOSE, ismonkey(user)))
return
if (reagents && reagents.total_volume)
user.show_message("<span class='notice'>You empty the [src].</span>", 1)
reagents.clear_reagents()
if(firecharges)
firecharges = 0
bongturnoff()
else
user.show_message("<span class='notice'>The [src] is already empty.</span>", 1)
/obj/item/bong/AltClick(mob/user)
if(!istype(user) || !user.canUseTopic(src, BE_CLOSE, ismonkey(user)))
return
if(firecharges)
firecharges = 0
bongturnoff()
user.show_message("<span class='notice'>You quench the flame.</span>", 1)
/obj/item/bong/examine(mob/user)
..()
if(!reagents.total_volume)
to_chat(user, "<span class='notice'>The bowl is empty.</span>")
else if (reagents.total_volume > 80)
to_chat(user, "<span class='notice'>The bowl is filled to the brim.</span>")
else if (reagents.total_volume > 40)
to_chat(user, "<span class='notice'>The bowl has plenty weed in it.</span>")
else
to_chat(user, "<span class='notice'>The bowl has some weed in it.</span>")
to_chat(user, "<span class='notice'>Ctrl+Shift-click to empty.</span>")
to_chat(user, "<span class='notice'>Alt-click to extinguish.</span>")
/obj/item/bong/ignition_effect(atom/A, mob/user)
if(firecharges)
. = "<span class='notice'>[user] lights [A] off of the [src].</span>"
else
. = ""
/obj/item/bong/attack(mob/living/carbon/M, mob/living/carbon/user, obj/target)
//if it's lit up, some stuff in the bowl and the user is a target, and we're not on cooldown
if (!reagents)
return
if (M ==! user)
return
if(user.is_mouth_covered(head_only = 1))
to_chat(user, "<span class='warning'>Remove your headgear first.</span>")
return
if(user.is_mouth_covered(mask_only = 1))
to_chat(user, "<span class='warning'>Remove your mask first.</span>")
return
if (!reagents.total_volume)
to_chat(user, "<span class='warning'>There's nothing in the bowl.</span>")
return
if (!firecharges)
to_chat(user, "<span class='warning'>You have to light it up first.</span>")
return
if (last_used_time + 30 < world.time)
var/hit_strength
var/noise
var/hittext = ""
//if the intent is help then you take a small hit, else a big one
if (user.a_intent == INTENT_HARM)
hit_strength = 2
noise = 100
hittext = "big hit"
else
hit_strength = 1
noise = 70
hittext = "hit"
//bubbling sound
playsound(user.loc,'sound/effects/bonghit.ogg', noise, 1)
last_used_time = world.time
//message
user.visible_message("<span class='notice'>[user] begins to take a "+ hittext +" from the [src]!</span>", \
"<span class='notice'>You begin to take a "+ hittext +" from [src].</span>")
//we take a hit here, after an uninterrupted delay
if(do_after(user, 25, target = user))
if (reagents && reagents.total_volume)
var/fraction = 12 * hit_strength
var/datum/effect_system/smoke_spread/chem/smoke_machine/s = new
s.set_up(reagents, hit_strength, 18, user.loc)
s.start()
reagents.reaction(user, INGEST, fraction)
if(!reagents.trans_to(user, fraction))
reagents.remove_any(fraction)
if (hit_strength == 2 && prob(15))
user.emote("cough")
user.adjustOxyLoss(15)
//playsound(user.loc, 'sound/effects/smoke.ogg', 10, 1, -3)
user.visible_message("<span class='notice'>[user] takes a "+ hittext +" from the [src]!</span>", \
"<span class='notice'>You take a "+ hittext +" from [src].</span>")
firecharges = firecharges - 1
if (firecharges == 0)
bongturnoff()
if (!reagents.total_volume)
firecharges = 0
bongturnoff()
/obj/item/bong/proc/bongturnon()
icon_state = icon_on
set_light(3, 0.8)
/obj/item/bong/proc/bongturnoff()
icon_state = icon_off
set_light(0, 0.0)
/obj/item/bong/coconut
name = "coconut bong"
icon_off = "coconut_bong"
icon_on = "coconut_bong_lit"
desc = "A water bong used for smoking dried plants. This one's made out of a coconut and some bamboo"
@@ -14,6 +14,10 @@
name = "Security Cameras (Computer Board)"
build_path = /obj/machinery/computer/security
/obj/item/circuitboard/computer/advanced_camera
name = "Advanced Camera Console (Computer Board)"
build_path = /obj/machinery/computer/camera_advanced/syndie
/obj/item/circuitboard/computer/xenobiology
name = "circuit board (Xenobiology Console)"
build_path = /obj/machinery/computer/camera_advanced/xenobio
+51
View File
@@ -54,6 +54,21 @@
else
return ..()
/obj/item/kitchen/fork/plastic
name = "plastic fork"
desc = "Really takes you back to highschool lunch."
icon_state = "plastic_fork"
force = 0
w_class = WEIGHT_CLASS_TINY
throwforce = 0
grind_results = list(/datum/material/plastic=80)
var/break_chance = 25
/obj/item/kitchen/fork/plastic/afterattack(mob/living/carbon/user)
.=..()
if(prob(break_chance))
user.visible_message("<span class='danger'>[user]'s fork snaps into tiny pieces in their hand.</span>")
qdel(src)
/obj/item/kitchen/knife
name = "kitchen knife"
@@ -89,6 +104,26 @@
"<span class='suicide'>[user] is slitting [user.p_their()] stomach open with the [src.name]! It looks like [user.p_theyre()] trying to commit seppuku.</span>"))
return (BRUTELOSS)
/obj/item/kitchen/knife/plastic
name = "plastic knife"
icon_state = "plastic_knife"
item_state = "knife"
desc = "A very safe, barely sharp knife made of plastic. Good for cutting food and not much else."
force = 0
w_class = WEIGHT_CLASS_TINY
throwforce = 0
throw_range = 5
grind_results = list(/datum/material/plastic = 100)
attack_verb = list("prodded", "whiffed","scratched", "poked")
sharpness = IS_SHARP
var/break_chance = 25
/obj/item/kitchen/knife/plastic/afterattack(mob/living/carbon/user)
.=..()
if(prob(break_chance))
user.visible_message("<span class='danger'>[user]'s knife snaps into tiny pieces in their hand.</span>")
qdel(src)
/obj/item/kitchen/knife/ritual
name = "ritual knife"
desc = "The unearthly energies that once powered this blade are now dormant."
@@ -175,6 +210,22 @@
return BRUTELOSS
/* Trays moved to /obj/item/storage/bag */
/obj/item/kitchen/spoon/plastic
name = "plastic spoon"
desc = "Just be careful your food doesn't melt the spoon first."
icon_state = "plastic_spoon"
force = 0
w_class = WEIGHT_CLASS_TINY
throwforce = 0
grind_results = list(/datum/material/plastic=120)
var/break_chance = 25
/obj/item/kitchen/knife/plastic/afterattack(mob/living/carbon/user)
.=..()
if(prob(break_chance))
user.visible_message("<span class='danger'>[user]'s spoon snaps into tiny pieces in their hand.</span>")
qdel(src)
/obj/item/kitchen/knife/scimitar
name = "Scimitar knife"
desc = "A knife used to cleanly butcher. Its razor-sharp edge has been honed for butchering, but has been poorly maintained over the years."
@@ -39,6 +39,9 @@ GLOBAL_LIST_INIT(glass_recipes, list ( \
/obj/item/stack/sheet/glass/fifty
amount = 50
/obj/item/stack/sheet/glass/five
amount = 5
/obj/item/stack/sheet/glass/Initialize(mapload, new_amount, merge = TRUE)
recipes = GLOB.glass_recipes
return ..()
@@ -55,6 +55,9 @@ GLOBAL_LIST_INIT(sandstone_recipes, list ( \
/obj/item/stack/sheet/mineral/sandstone/thirty
amount = 30
/obj/item/stack/sheet/mineral/sandstone/twelve
amount = 12
/*
* Sandbags
*/
@@ -235,6 +235,34 @@ GLOBAL_LIST_INIT(wood_recipes, list ( \
/obj/item/stack/sheet/mineral/wood/fifty
amount = 50
/*
* Bamboo
*/
GLOBAL_LIST_INIT(bamboo_recipes, list ( \
new/datum/stack_recipe("punji sticks trap", /obj/structure/punji_sticks, 10, time = 160, one_per_turf = TRUE, on_floor = TRUE), \
new/datum/stack_recipe("blow gun", /obj/item/gun/syringe/blowgun, 10, time = 70), \
))
/obj/item/stack/sheet/mineral/bamboo
name = "bamboo cuttings"
desc = "Finely cut bamboo sticks."
singular_name = "cut bamboo"
icon_state = "sheet-bamboo"
item_state = "sheet-bamboo"
icon = 'icons/obj/stack_objects.dmi'
sheettype = "bamboo"
throwforce = 15
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 0)
resistance_flags = FLAMMABLE
merge_type = /obj/item/stack/sheet/mineral/bamboo
grind_results = list("carbon" = 5)
/obj/item/stack/sheet/mineral/bamboo/Initialize(mapload, new_amount, merge = TRUE)
recipes = GLOB.bamboo_recipes
return ..()
/*
* Cloth
*/
@@ -73,6 +73,15 @@
turf_type = /turf/open/floor/grass
resistance_flags = FLAMMABLE
//Fairygrass
/obj/item/stack/tile/fairygrass
name = "fairygrass tile"
singular_name = "fairygrass floor tile"
desc = "A patch of odd, glowing blue grass."
icon_state = "tile_fairygrass"
item_state = "tile-fairygrass"
turf_type = /turf/open/floor/grass/fairy
resistance_flags = FLAMMABLE
//Wood
/obj/item/stack/tile/wood
+7 -7
View File
@@ -104,12 +104,12 @@
playing = FALSE
hearing_mobs = null
return
if(!lentext(note))
if(!length(note))
continue
var/cur_note = text2ascii(note) - 96
if(cur_note < 1 || cur_note > 7)
continue
for(var/i=2 to lentext(note))
for(var/i=2 to length(note))
var/ni = copytext(note,i,i+1)
if(!text2num(ni))
if(ni == "#" || ni == "b" || ni == "n")
@@ -209,7 +209,7 @@
lines.Cut(MUSIC_MAXLINES + 1)
var/linenum = 1
for(var/l in lines)
if(lentext(l) > MUSIC_MAXLINECHARS)
if(length(l) > MUSIC_MAXLINECHARS)
to_chat(usr, "Line [linenum] too long!")
lines.Remove(l)
else
@@ -236,11 +236,11 @@
if(!in_range(instrumentObj, usr))
return
if(lentext(t) >= MUSIC_MAXLINES * MUSIC_MAXLINECHARS)
if(length(t) >= MUSIC_MAXLINES * MUSIC_MAXLINECHARS)
var/cont = input(usr, "Your message is too long! Would you like to continue editing it?", "", "yes") in list("yes", "no")
if(cont == "no")
break
while(lentext(t) > MUSIC_MAXLINES * MUSIC_MAXLINECHARS)
while(length(t) > MUSIC_MAXLINES * MUSIC_MAXLINECHARS)
ParseSong(t)
else if(href_list["help"])
@@ -272,7 +272,7 @@
return
if(lines.len > MUSIC_MAXLINES)
return
if(lentext(newline) > MUSIC_MAXLINECHARS)
if(length(newline) > MUSIC_MAXLINECHARS)
newline = copytext(newline, 1, MUSIC_MAXLINECHARS)
lines.Add(newline)
@@ -287,7 +287,7 @@
var/content = html_encode(input("Enter your line: ", instrumentObj.name, lines[num]) as text|null)
if(!content || !in_range(instrumentObj, usr))
return
if(lentext(content) > MUSIC_MAXLINECHARS)
if(length(content) > MUSIC_MAXLINECHARS)
content = copytext(content, 1, MUSIC_MAXLINECHARS)
if(num > lines.len || num < 1)
return
@@ -96,6 +96,15 @@
if(..())
return
/turf/open/floor/grass/fairy //like grass but fae-er
name = "fairygrass patch"
desc = "Something about this grass makes you want to frolic. Or get high."
icon_state = "fairygrass"
floor_tile = /obj/item/stack/tile/fairygrass
light_range = 2
light_power = 0.50
light_color = "#33CCFF"
/turf/open/floor/grass/snow
gender = PLURAL
name = "snow"
+2
View File
@@ -100,6 +100,7 @@ GLOBAL_VAR(restart_counter)
GLOB.picture_log_directory = "data/picture_logs/[override_dir]"
GLOB.world_game_log = "[GLOB.log_directory]/game.log"
GLOB.world_cloning_log = "[GLOB.log_directory]/cloning.log"
GLOB.world_attack_log = "[GLOB.log_directory]/attack.log"
GLOB.world_pda_log = "[GLOB.log_directory]/pda.log"
GLOB.world_telecomms_log = "[GLOB.log_directory]/telecomms.log"
@@ -302,3 +303,4 @@ GLOBAL_VAR(restart_counter)
maxz++
SSmobs.MaxZChanged()
SSidlenpcpool.MaxZChanged()
+4 -4
View File
@@ -2152,7 +2152,7 @@
return
src.admincaster_feed_channel.channel_name = stripped_input(usr, "Provide a Feed Channel Name.", "Network Channel Handler", "")
while (findtext(src.admincaster_feed_channel.channel_name," ") == 1)
src.admincaster_feed_channel.channel_name = copytext(src.admincaster_feed_channel.channel_name,2,lentext(src.admincaster_feed_channel.channel_name)+1)
src.admincaster_feed_channel.channel_name = copytext(src.admincaster_feed_channel.channel_name,2,length(src.admincaster_feed_channel.channel_name)+1)
src.access_news_network()
else if(href_list["ac_set_channel_lock"])
@@ -2194,7 +2194,7 @@
return
src.admincaster_feed_message.body = adminscrub(input(usr, "Write your Feed story.", "Network Channel Handler", ""))
while (findtext(src.admincaster_feed_message.returnBody(-1)," ") == 1)
src.admincaster_feed_message.body = copytext(src.admincaster_feed_message.returnBody(-1),2,lentext(src.admincaster_feed_message.returnBody(-1))+1)
src.admincaster_feed_message.body = copytext(src.admincaster_feed_message.returnBody(-1),2,length(src.admincaster_feed_message.returnBody(-1))+1)
src.access_news_network()
else if(href_list["ac_submit_new_message"])
@@ -2255,7 +2255,7 @@
return
src.admincaster_wanted_message.criminal = adminscrub(input(usr, "Provide the name of the Wanted person.", "Network Security Handler", ""))
while(findtext(src.admincaster_wanted_message.criminal," ") == 1)
src.admincaster_wanted_message.criminal = copytext(admincaster_wanted_message.criminal,2,lentext(admincaster_wanted_message.criminal)+1)
src.admincaster_wanted_message.criminal = copytext(admincaster_wanted_message.criminal,2,length(admincaster_wanted_message.criminal)+1)
src.access_news_network()
else if(href_list["ac_set_wanted_desc"])
@@ -2263,7 +2263,7 @@
return
src.admincaster_wanted_message.body = adminscrub(input(usr, "Provide the a description of the Wanted person and any other details you deem important.", "Network Security Handler", ""))
while (findtext(src.admincaster_wanted_message.body," ") == 1)
src.admincaster_wanted_message.body = copytext(src.admincaster_wanted_message.body,2,lentext(src.admincaster_wanted_message.body)+1)
src.admincaster_wanted_message.body = copytext(src.admincaster_wanted_message.body,2,length(src.admincaster_wanted_message.body)+1)
src.access_news_network()
else if(href_list["ac_submit_wanted"])
+5 -5
View File
@@ -307,11 +307,11 @@ GLOBAL_PROTECT(VVpixelmovement)
// the type with the base type removed from the begaining
var/fancytype = types[D.type]
if (findtext(fancytype, types[type]))
fancytype = copytext(fancytype, lentext(types[type])+1)
var/shorttype = copytext("[D.type]", lentext("[type]")+1)
if (lentext(shorttype) > lentext(fancytype))
fancytype = copytext(fancytype, length(types[type])+1)
var/shorttype = copytext("[D.type]", length("[type]")+1)
if (length(shorttype) > length(fancytype))
shorttype = fancytype
if (!lentext(shorttype))
if (!length(shorttype))
shorttype = "/"
.["[D]([shorttype])[REF(D)]#[i]"] = D
@@ -534,7 +534,7 @@ GLOBAL_PROTECT(VVpixelmovement)
if (prompt != "Continue")
return FALSE
return TRUE
/client/proc/modify_variables(atom/O, param_var_name = null, autodetect_class = 0)
if(!check_rights(R_VAREDIT))
+392 -9
View File
@@ -82,7 +82,7 @@
crate_type = /obj/structure/closet/crate/internals
/datum/supply_pack/emergency/radiatione_emergency
name = "Emergenc Radiation Protection Crate"
name = "Emergency Radiation Protection Crate"
desc = "Survive the Nuclear Apocalypse and Supermatter Engine alike with two sets of Radiation suits. Each set contains a helmet, suit, and Geiger counter. We'll even throw in a few pill bottles that are able to handles radiation and the affects of the poisoning."
cost = 2500
contains = list(/obj/item/clothing/head/radiation,
@@ -293,7 +293,7 @@
/datum/supply_pack/medical/anitvirus
name = "Virus Containment Crate"
desc = "Viro let out a death plague Mk II again? Someone didnt wash there hands? Old plagues born anew? Well this crate is for you! Hope you cure it before it brakes out of the station... This crate needs medical access to open and has two bio suits, a box of needles and beakers, five spaceacillin needles, and a medibot."
desc = "Viro let out a death plague Mk II again? Someone didnt wash their hands? Old plagues born anew? Well this crate is for you! Hope you cure it before it breaks out of the station... This crate needs medical access to open and has two bio suits, a box of needles and beakers, five spaceacillin needles, and a medibot."
cost = 3000
access = ACCESS_MEDICAL
contains = list(/mob/living/simple_animal/bot/medbot,
@@ -311,6 +311,56 @@
crate_name = "virus containment unit crate"
crate_type = /obj/structure/closet/crate/secure/plasma
/datum/supply_pack/emergency/medicalemergency
name = "Emergency Medical Supplies"
desc = "Emergency supplies for a front-line medic. Contains two boxes of body bags, a medical HUD, a defib unit, medical belt, toxin bottles, epipens, and several types of medical kits."
cost = 6600
contains = list(/obj/item/storage/box/bodybags,
/obj/item/storage/box/bodybags,
/obj/item/clothing/glasses/hud/health,
/obj/item/defibrillator/loaded,
/obj/item/storage/belt/medical,
/obj/item/storage/firstaid/toxin,
/obj/item/storage/firstaid/o2,
/obj/item/storage/firstaid/brute,
/obj/item/storage/firstaid/fire,
/obj/item/reagent_containers/glass/bottle/toxin,
/obj/item/reagent_containers/glass/bottle/toxin,
/obj/item/storage/box/medipens)
crate_name = "medical emergency crate"
crate_type = /obj/structure/closet/crate/medical
/datum/supply_pack/emergency/medemergencylite
name = "Emergency Medical Supplies (Lite)"
desc = "A less than optimal, but still effective, set of tools for emergency care. Contains a box of bodybags, a medical HUD, healing sprays, charcoal, some gauze, and some spare medipens."
cost = 2800
contains = list(/obj/item/storage/box/bodybags,
/obj/item/stack/medical/gauze,
/obj/item/clothing/glasses/hud/health,
/obj/item/reagent_containers/medspray/styptic,
/obj/item/reagent_containers/medspray/silver_sulf,
/obj/item/reagent_containers/medspray/synthflesh,
/obj/item/reagent_containers/glass/bottle/charcoal,
/obj/item/reagent_containers/glass/bottle/charcoal,
/obj/item/reagent_containers/hypospray/medipen,
/obj/item/reagent_containers/hypospray/medipen,
/obj/item/reagent_containers/hypospray/medipen)
crate_name = "medical emergency crate (lite)"
crate_type = /obj/structure/closet/crate/medical
/datum/supply_pack/emergency/mre
name = "MRE supply kit (emergency rations)"
desc = "The lights are out. Oxygen's running low. You've run out of food except space weevils. Don't let this be you! Order our NT branded MRE kits today! This pack contains 5 MRE packs with a randomized menu and an oxygen tank."
cost = 2000
contains = list(/obj/item/storage/box/mre/menu1/safe,
/obj/item/storage/box/mre/menu1/safe,
/obj/item/storage/box/mre/menu2/safe,
/obj/item/storage/box/mre/menu2/safe,
/obj/item/storage/box/mre/menu3,
/obj/item/storage/box/mre/menu4/safe)
crate_name = "MRE crate (emergency rations)"
//////////////////////////////////////////////////////////////////////////////
//////////////////////////// Security ////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
@@ -813,7 +863,7 @@
/datum/supply_pack/engineering/industrialrcd
name = "Industrial RCD"
desc = "A industrial RCD in case the station has gone through more then one meteor storm and the CE needs to bring out the somthing a bit more reliable. Dose not contain spare ammo for the industrial RCD or any other RCD modles."
desc = "A industrial RCD in case the station has gone through more then one meteor storm and the CE needs to bring out the somthing a bit more reliable. Does not contain spare ammo for the industrial RCD or any other RCD modles."
cost = 4500
access = ACCESS_CE
contains = list(/obj/item/construction/rcd/industrial)
@@ -860,6 +910,18 @@
crate_name = "power cell crate"
crate_type = /obj/structure/closet/crate/engineering/electrical
/datum/supply_pack/engineering/powertools
name = "Power Tools Crate"
desc = "Setting up the aux base? Working out in space? Maybe you just hate doing things by hand. Grab some power tools and slash your workload in half! Contains a hardhat, hazard vest, Hand Drill, and Jaws of Life"
cost = 6500
access = ACCESS_ENGINE
contains = list(/obj/item/clothing/head/hardhat,
/obj/item/clothing/suit/hazardvest,
/obj/item/screwdriver/power,
/obj/item/crowbar/power)
crate_name = "power tools crate"
crate_type = /obj/structure/closet/crate/secure/engineering
/datum/supply_pack/engineering/shuttle_engine
name = "Shuttle Engine Crate"
desc = "Through advanced bluespace-shenanigans, our engineers have managed to fit an entire shuttle engine into one tiny little crate. Requires CE access to open."
@@ -1282,6 +1344,16 @@
group = "Medical"
crate_type = /obj/structure/closet/crate/medical
/datum/supply_pack/medical/bodybags
name = "Bodybags"
desc = "For when the bodies hit the floor. Contains 4 boxes of bodybags."
cost = 1200
contains = list(/obj/item/storage/box/bodybags,
/obj/item/storage/box/bodybags,
/obj/item/storage/box/bodybags,
/obj/item/storage/box/bodybags,)
crate_name = "bodybag crate"
/datum/supply_pack/medical/firstaidbruises
name = "Bruise Treatment Kit Crate"
desc = "Contains three first aid kits focused on healing bruises and broken bones."
@@ -1343,7 +1415,7 @@
/datum/supply_pack/science/adv_surgery_tools
name = "Med-Co Advanced surgery tools"
desc = "A full set of Med-Co advanced surgery tools, this crate also comes with a spay of synth flesh as well as a can of . Requires Surgery access to open."
desc = "A full set of Med-Co advanced surgery tools, this crate both a can of synthflesh and a can of sterilizine. Requires Surgery access to open."
cost = 5000
access = ACCESS_SURGERY
contains = list(/obj/item/storage/belt/medical/surgery_belt_adv,
@@ -1494,6 +1566,37 @@
group = "Science"
crate_type = /obj/structure/closet/crate/science
/datum/supply_pack/science/aliens
name = "Advanced Alien Alloy Crate Crate"
desc = "Hello brothers from the stars!!! Our fellow brethren have made contact at long last and gave us gifts man! They really did build the prymi- Connection Error- Bro well send you a sheet of advanced alien alloy."
cost = 15000
contraband = TRUE
DropPodOnly = TRUE
contains = list(/obj/item/stack/sheet/mineral/abductor)
crate_name = "alien bro alloy crate"
/datum/supply_pack/science/beakers
name = "Chemistry Beakers Crate"
desc = "Glassware for any chemistry lab! Contains four small beakers, three large, two plastic, and one metamaterial. As well as three droppers and two pairs of latex gloves."
cost = 2000
contains = list(/obj/item/reagent_containers/glass/beaker,
/obj/item/reagent_containers/glass/beaker,
/obj/item/reagent_containers/glass/beaker,
/obj/item/reagent_containers/glass/beaker,
/obj/item/reagent_containers/glass/beaker/large,
/obj/item/reagent_containers/glass/beaker/large,
/obj/item/reagent_containers/glass/beaker/large,
/obj/item/reagent_containers/glass/beaker/plastic,
/obj/item/reagent_containers/glass/beaker/plastic,
/obj/item/reagent_containers/glass/beaker/meta,
/obj/item/reagent_containers/glass/beaker/noreact,
/obj/item/reagent_containers/dropper,
/obj/item/reagent_containers/dropper,
/obj/item/reagent_containers/dropper,
/obj/item/clothing/gloves/color/latex,
/obj/item/clothing/gloves/color/latex)
crate_name = "chemistry beaker crate"
/datum/supply_pack/science/robotics/mecha_odysseus
name = "Circuit Crate (Odysseus)"
desc = "Ever wanted to build your own giant medical robot? Well, now you can! Contains the Odysseus main control board and Odysseus peripherals board. Requires Robotics access to open."
@@ -1525,6 +1628,15 @@
/obj/item/integrated_electronics/wirer)
crate_name = "circuitry starter pack crate"
/datum/supply_pack/science/nitrilegloves
name = "Nitrile Gloves Crate"
desc = "Handling toxic chemicals? Well worry not, keep your flesh intact with some nitrile made gloves! Contains three pairs of nitrile gloves."
cost = 1500
contains = list(/obj/item/clothing/gloves/color/latex/nitrile,
/obj/item/clothing/gloves/color/latex/nitrile,
/obj/item/clothing/gloves/color/latex/nitrile)
crate_name = "nitrile gloves crate"
/datum/supply_pack/science/plasma
name = "Plasma Assembly Crate"
desc = "Everything you need to burn something to the ground, this contains three plasma assembly sets. Each set contains a plasma tank, igniter, proximity sensor, and timer! Warranty void if exposed to high temperatures. Requires Toxins access to open."
@@ -1572,10 +1684,19 @@
crate_name = "shield generators crate"
crate_type = /obj/structure/closet/crate/secure/science
/datum/supply_pack/science/slime
name = "Slime Core Crate"
desc = "Ran out of slimes? No problem, contains one gray slime core. Requires Xenobio access to open."
cost = 1000
access = ACCESS_XENOBIOLOGY
contains = list(/obj/item/slime_extract/grey)
crate_name = "slime core crate"
crate_type = /obj/structure/closet/crate/secure/science
/datum/supply_pack/science/tablets
name = "Tablet Crate"
desc = "What's a computer? Contains five cargo tablets."
cost = 5000
cost = 3000
contains = list(/obj/item/modular_computer/tablet/preset/cargo,
/obj/item/modular_computer/tablet/preset/cargo,
/obj/item/modular_computer/tablet/preset/cargo,
@@ -1622,6 +1743,20 @@
crate_name = "advanced lighting crate"
crate_type = /obj/structure/closet/crate/secure
/datum/supply_pack/service/janitor/advanced
name = "Advanced Sanitation Crate"
desc = "Contains all the essentials for an advanced spacefaring cleanup crew. This kit includes a trashbag of holding, an advanced mop, a bottle of space cleaner, a floor buffer, and a holosign projector."
cost = 5000
access = ACCESS_JANITOR
contains = list(/obj/item/storage/bag/trash/bluespace,
/obj/item/reagent_containers/spray/cleaner,
/obj/item/mop/advanced,
/obj/item/lightreplacer,
/obj/item/janiupgrade,
/obj/item/holosign_creator)
crate_name = "advanced santation crate"
crate_type = /obj/structure/closet/crate/secure
/datum/supply_pack/service/cargo_supples
name = "Cargo Supplies Crate"
desc = "Sold everything that wasn't bolted down? You can get right back to work with this crate containing stamps, an export scanner, destination tagger, hand labeler and some package wrapping."
@@ -1658,6 +1793,65 @@
crate_name = "ice cream vat crate"
crate_type = /obj/structure/closet/crate
/datum/supply_pack/service/buildabar
name = "Build a Bar Crate"
desc = "Looking to set up your own little safe haven? Maintenance bar too much of a bummer to work on? Maybe you just want to set up shop right in front of the bartender. Whatever your reasons, get a jump-start on this with this handy kit. Contains circuitboards for bar equipment, some parts, and some basic bartending supplies. (Batteries not Included)"
cost = 3750
contains = list(/obj/item/storage/box/drinkingglasses,
/obj/item/storage/box/drinkingglasses,
/obj/item/stock_parts/matter_bin,
/obj/item/stock_parts/matter_bin,
/obj/item/stock_parts/matter_bin,
/obj/item/stock_parts/matter_bin,
/obj/item/stock_parts/matter_bin,
/obj/item/stock_parts/matter_bin,
/obj/item/stock_parts/manipulator,
/obj/item/stock_parts/manipulator,
/obj/item/stock_parts/manipulator,
/obj/item/stock_parts/capacitor,
/obj/item/stock_parts/capacitor,
/obj/item/stack/sheet/metal/ten,
/obj/item/stack/sheet/metal/five,
/obj/item/stack/sheet/glass/five,
/obj/item/stack/cable_coil/random,
/obj/item/reagent_containers/rag,
/obj/item/book/manual/wiki/barman_recipes,
/obj/item/book/granter/action/drink_fling,
/obj/item/reagent_containers/food/drinks/shaker,
/obj/item/clothing/under/waiter,
/obj/item/clothing/under/rank/bartender,
/obj/item/clothing/under/rank/bartender/skirt,
/obj/item/clothing/accessory/waistcoat,
/obj/item/circuitboard/machine/chem_dispenser/drinks/beer,
/obj/item/circuitboard/machine/chem_dispenser/drinks,
/obj/item/circuitboard/machine/dish_drive)
crate_name = "build a bar crate"
/datum/supply_pack/service/maintgarden
name = "Maintenance Garden Crate"
desc = "Set up your own tiny paradise with do-it-yourself botany kit. Contains sandstone for dirt plots, pest spray, ammonia, a portable seed generator, basic botanical tools, and some seeds to start off with."
cost = 2350
contains = list(/obj/item/storage/bag/plants/portaseeder,
/obj/item/reagent_containers/spray/pestspray,
/obj/item/stack/sheet/mineral/sandstone/twelve,
/obj/item/reagent_containers/glass/bucket,
/obj/item/reagent_containers/glass/bottle/ammonia,
/obj/item/reagent_containers/glass/bottle/ammonia,
/obj/item/hatchet,
/obj/item/cultivator,
/obj/item/plant_analyzer,
/obj/item/flashlight,
/obj/item/seeds/carrot,
/obj/item/seeds/carrot,
/obj/item/seeds/tower,
/obj/item/seeds/tower,
/obj/item/seeds/watermelon,
/obj/item/seeds/watermelon,
/obj/item/seeds/grass,
/obj/item/seeds/grass)
crate_name = "maint garden crate"
crate_type = /obj/structure/closet/crate/hydroponics
/datum/supply_pack/service/janitor
name = "Janitorial Supplies Crate"
desc = "Fight back against dirt and grime with Nanotrasen's Janitorial Essentials(tm)! Contains three buckets, caution signs, and cleaner grenades. Also has a single mop, spray cleaner, rag, NT soap and a trash bag."
@@ -1974,6 +2168,25 @@
/obj/item/reagent_containers/food/snacks/grown/banana)
crate_name = "food crate"
/datum/supply_pack/organic/fiestatortilla
name = "Fiesta Crate"
desc = "Spice up the kitchen with this fiesta themed food order! Contains 8 tortilla based food items, as well as a sombrero, moustache, and cloak!"
cost = 2750
contains = list(/obj/item/clothing/head/sombrero,
/obj/item/clothing/suit/hooded/cloak/david,
/obj/item/clothing/mask/fakemoustache,
/obj/item/reagent_containers/food/snacks/taco,
/obj/item/reagent_containers/food/snacks/taco,
/obj/item/reagent_containers/food/snacks/taco/plain,
/obj/item/reagent_containers/food/snacks/taco/plain,
/obj/item/reagent_containers/food/snacks/enchiladas,
/obj/item/reagent_containers/food/snacks/enchiladas,
/obj/item/reagent_containers/food/snacks/carneburrito,
/obj/item/reagent_containers/food/snacks/cheesyburrito,
/obj/item/reagent_containers/glass/bottle/capsaicin,
/obj/item/reagent_containers/glass/bottle/capsaicin)
crate_name = "fiesta crate"
/datum/supply_pack/organic/cream_piee
name = "High-yield Clown-grade Cream Pie Crate"
desc = "Designed by Aussec's Advanced Warfare Research Division, these high-yield, Clown-grade cream pies are powered by a synergy of performance and efficiency. Guaranteed to provide maximum results."
@@ -1985,8 +2198,8 @@
crate_type = /obj/structure/closet/crate/secure
/datum/supply_pack/organic/hunting
name = "Huntting gear"
desc = "Even in space, we can fine prey to hunt, this crate contains everthing a fine hunter needs to have a sporting time. This crate needs armory access to open. A true huntter only needs a fine bottle of cognac, a nice coat, some good o' cigars, and of cource a huntting shotgun. "
name = "Hunting gear"
desc = "Even in space, we can find prey to hunt, this crate contains everthing a fine hunter needs to have a sporting time. This crate needs armory access to open. A true huntter only needs a fine bottle of cognac, a nice coat, some good o' cigars, and of cource a hunting shotgun. "
cost = 3500
contraband = TRUE
contains = list(/obj/item/clothing/head/flatcap,
@@ -2000,6 +2213,42 @@
crate_name = "sporting crate"
crate_type = /obj/structure/closet/crate/secure // Would have liked a wooden crate but access >:(
/datum/supply_pack/organic/fakemeat
name = "Meat Crate"
desc = "Run outta meat already? Keep the lizards content with this freezer filled with cruelty-free chemically compounded meat! Contains 4 slabs of meat product, and two slabs of *carp*."
cost = 1700
contains = list(/obj/item/reagent_containers/food/snacks/meat/slab/meatproduct,
/obj/item/reagent_containers/food/snacks/meat/slab/meatproduct,
/obj/item/reagent_containers/food/snacks/meat/slab/meatproduct,
/obj/item/reagent_containers/food/snacks/meat/slab/meatproduct,
/obj/item/reagent_containers/food/snacks/carpmeat/imitation,
/obj/item/reagent_containers/food/snacks/carpmeat/imitation)
crate_name = "meaty crate"
crate_type = /obj/structure/closet/crate/freezer
/datum/supply_pack/organic/monkeydripmeat
name = "*Meat* Crate"
desc = "Need some meat? With this do-it-yourself kit you'll be swimming in it! Contains a monkey cube, an IV drip, and some cryoxadone!"
cost = 2150
contraband = TRUE
contains = list(/obj/item/reagent_containers/food/snacks/monkeycube,
/obj/item/restraints/handcuffs/cable,
/obj/machinery/iv_drip,
/obj/item/reagent_containers/glass/beaker/cryoxadone,
/obj/item/reagent_containers/glass/beaker/cryoxadone)
crate_name = "monkey meat crate"
/datum/supply_pack/organic/mixedboxes
name = "Mixed Ingredient Boxes"
desc = "Get overwhelmed with inspiration by ordering these boxes of surprise ingredients! Get four boxes filled with an assortment of products!"
cost = 2300
contains = list(/obj/item/storage/box/ingredients/wildcard,
/obj/item/storage/box/ingredients/wildcard,
/obj/item/storage/box/ingredients/wildcard,
/obj/item/storage/box/ingredients/wildcard)
crate_name = "wildcard food crate"
crate_type = /obj/structure/closet/crate/freezer
/datum/supply_pack/organic/hydroponics
name = "Hydroponics Crate"
desc = "Supplies for growing a great garden! Contains two bottles of ammonia, two Plant-B-Gone spray bottles, a hatchet, cultivator, plant analyzer, as well as a pair of leather gloves and a botanist's apron."
@@ -2124,6 +2373,21 @@
crate_name = "valentine crate"
crate_type = /obj/structure/closet/crate/secure
/datum/supply_pack/organic/strangeseeds
name = "Strange Seeds Crate"
desc = "After our chemical waste mysteriously disappeared we've discovered many strange and interesting species of plants, and they're yours for the taking! Contains 8 packs of strange seeds."
cost = 4500
contains = list(/obj/item/seeds/random,
/obj/item/seeds/random,
/obj/item/seeds/random,
/obj/item/seeds/random,
/obj/item/seeds/random,
/obj/item/seeds/random,
/obj/item/seeds/random,
/obj/item/seeds/random)
crate_name = "strange seeds crate"
crate_type = /obj/structure/closet/crate/hydroponics
/datum/supply_pack/organic/exoticseeds
name = "Exotic Seeds Crate"
desc = "Any entrepreneuring botanist's dream. Contains twelve different seeds, including three replica-pod seeds and two mystery seeds!"
@@ -2276,6 +2540,18 @@
/mob/living/simple_animal/hostile/retaliate/poison/snake)
crate_name = "snake crate"
/datum/supply_pack/critter/mouse
name = "Mouse Crate"
desc = "Good for snakes and lizards of all ages. Contains ~12 feeder mice."
cost = 2000
contains = list(/mob/living/simple_animal/mouse,)
crate_name = "mouse crate"
/datum/supply_pack/critter/mouse/generate()
. = ..()
for(var/i in 1 to 11)
new /mob/living/simple_animal/mouse(.)
/datum/supply_pack/critter/secbat
name = "Security Bat Crate"
desc = "Contains five security bats, perfect to Bat-up any security officer."
@@ -2648,7 +2924,10 @@
name = "Kinkmate construction kit"
cost = 2000
contraband = TRUE
contains = list(/obj/item/vending_refill/kink, /obj/item/circuitboard/machine/kinkmate)
contains = list(/obj/item/vending_refill/kink,
/obj/item/vending_refill/kink,
/obj/item/vending_refill/kink,
/obj/item/circuitboard/machine/kinkmate)
crate_name = "Kinkmate construction kit"
//////////////////////////////////////////////////////////////////////////////
@@ -2687,6 +2966,51 @@
crate_name = "captain pen"
crate_type = /obj/structure/closet/crate/secure/weapon //It is a combat pen
/datum/supply_pack/misc/exoticfootwear
name = "Exotic Footwear Crate"
desc = "Popularised by lizards and exotic dancers, the footwear included in this shipment is sure to give your feet the breathing room they deserve. Sweet Kicks Inc. is not responsible for any damage, distress, or @r0u$a1 caused by this shipment."
cost = 3000
contains = list(/obj/item/clothing/shoes/wraps,
/obj/item/clothing/shoes/wraps,
/obj/item/clothing/shoes/wraps/silver,
/obj/item/clothing/shoes/wraps/silver,
/obj/item/clothing/shoes/wraps/red,
/obj/item/clothing/shoes/wraps/red,
/obj/item/clothing/shoes/wraps/blue,
/obj/item/clothing/shoes/wraps/blue,
/obj/item/clothing/shoes/clown_shoes,
/obj/item/clothing/shoes/kindleKicks)
crate_name = "footie crate"
/datum/supply_pack/misc/randombedsheets
name = "Bedsheet Crate (R)"
desc = "Snuggle up in some sweet sheets with this assorted bedsheet crate. Each set comes with eight random bedsheets for your slumbering pleasure!"
cost = 2000
contains = list(/obj/item/bedsheet/random,
/obj/item/bedsheet/random,
/obj/item/bedsheet/random,
/obj/item/bedsheet/random,
/obj/item/bedsheet/random,
/obj/item/bedsheet/random,
/obj/item/bedsheet/random,
/obj/item/bedsheet/random) //I'm lazy, and I copy paste stuff.
crate_name = "random bedsheet crate"
/datum/supply_pack/misc/coloredsheets
name = "Bedsheet Crate (C)"
desc = "Give your night life a splash of color with this crate filled with bedsheets! Contains a total of nine different-colored sheets."
cost = 1250
contains = list(/obj/item/bedsheet/blue,
/obj/item/bedsheet/green,
/obj/item/bedsheet/orange,
/obj/item/bedsheet/purple,
/obj/item/bedsheet/red,
/obj/item/bedsheet/yellow,
/obj/item/bedsheet/brown,
/obj/item/bedsheet/black,
/obj/item/bedsheet/rainbow)
crate_name = "colored bedsheet crate"
/datum/supply_pack/misc/bicycle
name = "Bicycle"
desc = "Nanotrasen reminds all employees to never toy with powers outside their control."
@@ -2722,6 +3046,36 @@
/obj/item/book/random/triple)
crate_type = /obj/structure/closet/crate/wooden
/datum/supply_pack/misc/cbtpack
name = "CBT Equipment"
desc = "(*!&@#CBT is a special term coined by high ranking syndicate operatives for a special form of information extraction. While the training required to use this shipment is highly classified, the distribution of it's contents are not. In addition to this crates unusual contents, we have added a bar of soap.#@*$"
hidden = TRUE
cost = 2400
contains = list(/mob/living/simple_animal/chicken,
/obj/item/toy/beach_ball/holoball,
/obj/item/melee/baton/cattleprod,
/obj/item/soap/syndie)
crate_name = "cbt crate"
crate_type = /obj/structure/closet/crate/large
/datum/supply_pack/misc/casinocrate
name = "Casino Crate"
desc = "Start up your own grand casino with this crate filled with slot machine and arcade boards!"
cost = 3000
contains = list(/obj/item/circuitboard/computer/arcade/battle,
/obj/item/circuitboard/computer/arcade/battle,
/obj/item/circuitboard/computer/arcade/orion_trail,
/obj/item/circuitboard/computer/arcade/orion_trail,
/obj/item/circuitboard/computer/arcade/minesweeper,
/obj/item/circuitboard/computer/arcade/minesweeper,
/obj/item/circuitboard/computer/slot_machine,
/obj/item/circuitboard/computer/slot_machine,
/obj/item/circuitboard/computer/slot_machine,
/obj/item/circuitboard/computer/slot_machine,
/obj/item/circuitboard/computer/slot_machine,
/obj/item/circuitboard/computer/slot_machine)
crate_name = "casino crate"
/datum/supply_pack/misc/paper
name = "Bureaucracy Crate"
desc = "High stacks of papers on your desk Are a big problem - make it Pea-sized with these bureaucratic supplies! Contains five pens, some camera film, hand labeler supplies, a paper bin, three folders, two clipboards and two stamps as well as a briefcase."//that was too forced
@@ -2804,11 +3158,13 @@
/datum/supply_pack/misc/lewd
name = "Lewd Crate" // OwO
desc = "Psss want to have a good time with your sluts? Well I got what you want maid clothing, dildos, collars and more!"
desc = "Psss want to have a good time with your sluts? Well I got what you want! Maid clothing, dildos, collars and more!"
cost = 5000
contraband = TRUE
contains = list(/obj/item/dildo/custom,
/obj/item/dildo/custom,
/obj/item/circuitboard/machine/kinkmate,
/obj/item/vending_refill/kink,
/obj/item/vending_refill/kink,
/obj/item/vending_refill/kink,
/obj/item/clothing/under/maid,
@@ -2859,6 +3215,33 @@
/obj/item/autosurgeon/womb)
crate_name = "promiscuous organs"
/datum/supply_pack/misc/shower
name = "Shower Supplies"
desc = "Everyone needs a bit of R&R. Make sure you get can get yours by ordering this crate filled with towels, rubber duckies, and some soap!"
cost = 1000
contains = list(/obj/item/reagent_containers/rag/towel,
/obj/item/reagent_containers/rag/towel,
/obj/item/reagent_containers/rag/towel,
/obj/item/reagent_containers/rag/towel,
/obj/item/reagent_containers/rag/towel,
/obj/item/reagent_containers/rag/towel,
/obj/item/bikehorn/rubberducky,
/obj/item/bikehorn/rubberducky,
/obj/item/soap/nanotrasen)
crate_name = "shower crate"
/datum/supply_pack/misc/spacehermitstarter
name = "Space Hermit Starter Pack"
desc = "So sick of the station you wish to leave and never come back? Or perhaps you need to find a place of solitutde and privacy? Jumping out of an external airlock may just be the solution for you! But not before you buy this crate - contains a mining hardsuit, a proto-kinetic accelerator, GPS, luxury bluespace shelter aswell as a deluxe bluespace shelter.(Jetpack not included)"
cost = 5000
contraband = TRUE
contains = list(/obj/item/clothing/suit/space/hardsuit/mining,
/obj/item/gun/energy/kinetic_accelerator,
/obj/item/survivalcapsule/deluxe,
/obj/item/survivalcapsule/luxury,
/obj/item/gps)
crate_name = "space hermit crate"
/datum/supply_pack/misc/toner
name = "Toner Crate"
desc = "Spent too much ink printing butt pictures? Fret not, with these six toner refills, you'll be printing butts 'till the cows come home!'"
+2 -2
View File
@@ -357,8 +357,8 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "<table><tr><td width='340px' height='300px' valign='top'>"
dat += "<h2>Flavor Text</h2>"
dat += "<a href='?_src_=prefs;preference=flavor_text;task=input'><b>Set Examine Text</b></a><br>"
if(lentext(features["flavor_text"]) <= 40)
if(!lentext(features["flavor_text"]))
if(length(features["flavor_text"]) <= 40)
if(!length(features["flavor_text"]))
dat += "\[...\]"
else
dat += "[features["flavor_text"]]"
+22 -1
View File
@@ -69,7 +69,7 @@
/obj/item/clothing/shoes/clown_shoes
desc = "The prankster's standard-issue clowning shoes. Damn, they're huge!"
name = "clown shoes"
icon_state = "clown"
icon_state = "clown_shoes"
item_state = "clown_shoes"
slowdown = SHOES_SLOWDOWN+1
item_color = "clown"
@@ -312,3 +312,24 @@
set_light(0)
lightCycle = 0
active = FALSE
/obj/item/clothing/shoes/wraps
name = "gilded leg wraps"
desc = "Ankle coverings. These ones have a golden design."
icon_state = "gildedcuffs"
body_parts_covered = FALSE
/obj/item/clothing/shoes/wraps/silver
name = "silver leg wraps"
desc = "Ankle coverings. Not made of real silver."
icon_state = "silvergildedcuffs"
/obj/item/clothing/shoes/wraps/red
name = "red leg wraps"
desc = "Ankle coverings. Show off your style with these shiny red ones!"
icon_state = "redcuffs"
/obj/item/clothing/shoes/wraps/blue
name = "blue leg wraps"
desc = "Ankle coverings. Hang ten, brother."
icon_state = "bluecuffs"
+22 -1
View File
@@ -636,11 +636,24 @@
/datum/crafting_recipe/wheelchair
name = "Wheelchair"
result = /obj/vehicle/ridden/wheelchair
reqs = list(/obj/item/stack/sheet/plasteel = 2,
reqs = list(/obj/item/stack/sheet/metal = 10,
/obj/item/stack/rods = 8)
time = 100
category = CAT_MISC
/datum/crafting_recipe/motorized_wheelchair
name = "Motorized Wheelchair"
result = /obj/vehicle/ridden/wheelchair/motorized
reqs = list(/obj/item/stack/sheet/metal = 10,
/obj/item/stack/rods = 8,
/obj/item/stock_parts/manipulator = 2,
/obj/item/stock_parts/capacitor = 1)
parts = list(/obj/item/stock_parts/manipulator = 2,
/obj/item/stock_parts/capacitor = 1)
tools = list(TOOL_WELDER, TOOL_SCREWDRIVER, TOOL_WRENCH)
time = 200
category = CAT_MISC
/datum/crafting_recipe/rcl
name = "Makeshift Rapid Cable Layer"
result = /obj/item/twohanded/rcl/ghetto
@@ -963,3 +976,11 @@
time = 60
always_availible = TRUE
category = CAT_CLOTHING
/datum/crafting_recipe/coconut_bong
name = "Coconut Bong"
result = /obj/item/bong/coconut
reqs = list(/obj/item/stack/sheet/mineral/bamboo = 2,
/obj/item/reagent_containers/food/snacks/grown/coconut = 1)
time = 70
category = CAT_MISC
@@ -14,6 +14,7 @@
volume = 50
resistance_flags = NONE
var/isGlass = TRUE //Whether the 'bottle' is made of glass or not so that milk cartons dont shatter when someone gets hit by it
splashable = TRUE
/obj/item/reagent_containers/food/drinks/on_reagent_change(changetype)
if (gulp_size < 5)
@@ -104,6 +105,7 @@
/obj/item/reagent_containers/food/drinks/throw_impact(atom/target, datum/thrownthing/throwinfo)
. = ..()
if(!.) //if the bottle wasn't caught
SplashReagents(target)
smash(target, throwinfo.thrower, TRUE)
/obj/item/reagent_containers/food/drinks/proc/smash(atom/target, mob/thrower, ranged = FALSE)
@@ -794,4 +794,25 @@
name = "Red Queen"
id = "red_queen"
results = list("red_queen" = 10)
required_reagents = list("tea" = 6, "mercury" = 2, "blackpepper" = 1, "growthserum" = 1)
required_reagents = list("tea" = 6, "mercury" = 2, "blackpepper" = 1, "growthserum" = 1)
/datum/chemical_reaction/gunfire
name = "Gunfire"
id = "gunfire"
results = list("gunfire" = 4)
required_reagents = list("rum" = 1, "tea" = 3)
mix_message = "A loud popping begins to fill the air as the drink is mixed."
/datum/chemical_reaction/hellfire
name = "Hellfire"
id = "hellfire"
results = list("hellfire" = 5)
required_reagents = list("rum" = 1, "beer" = 1, "ice" = 1, "capsaicin" = 1, "limejuice" = 1)
mix_message = "The liquid begins to churn as it changes to an amber orange and catches on fire."
/datum/chemical_reaction/sins_delight
name = "Sins Delight"
id = "sins_delight"
results = list("sins_delight" = 5)
required_reagents = list("demonsblood" = 2, "triple_sec" = 1, "martini" = 1, "changelingsting" = 1)
mix_message = "The liquid starts swirling, before forming a pink cloud that dissipates in the air."
@@ -69,8 +69,9 @@
/datum/crafting_recipe/food/birthdaycake
name = "Birthday cake"
reqs = list(
/obj/item/clothing/head/hardhat/cakehat = 1,
/obj/item/reagent_containers/food/snacks/store/cake/plain = 1
/obj/item/reagent_containers/food/snacks/store/cake/plain = 1,
/obj/item/candle = 1,
/datum/reagent/consumable/sugar = 5,
)
result = /obj/item/reagent_containers/food/snacks/store/cake/birthday
subcategory = CAT_CAKE
+1 -1
View File
@@ -240,7 +240,7 @@
dat += "</table>"
else
dat += "No trait-related genes detected in sample.<br>"
if(can_insert && istype(disk.gene, /datum/plant_gene/trait))
if(can_insert && istype(disk.gene, /datum/plant_gene/trait) && !seed.is_gene_forbidden(disk.gene))
dat += "<a href='?src=[REF(src)];op=insert'>Insert: [disk.gene.get_name()]</a>"
dat += "</div>"
else
+32 -2
View File
@@ -90,7 +90,7 @@
lifespan = 30
endurance = 25
mutatelist = list()
genes = list(/datum/plant_gene/trait/glow/berry , /datum/plant_gene/trait/noreact, /datum/plant_gene/trait/repeated_harvest)
genes = list(/datum/plant_gene/trait/glow/white , /datum/plant_gene/trait/noreact, /datum/plant_gene/trait/repeated_harvest)
reagents_add = list("uranium" = 0.25, "iodine" = 0.2, "vitamin" = 0.04, "nutriment" = 0.1)
rarity = 20
@@ -121,8 +121,9 @@
growing_icon = 'icons/obj/hydroponics/growing_fruits.dmi'
icon_grow = "cherry-grow"
icon_dead = "cherry-dead"
icon_harvest = "cherry-harvest"
genes = list(/datum/plant_gene/trait/repeated_harvest)
mutatelist = list(/obj/item/seeds/cherry/blue)
mutatelist = list(/obj/item/seeds/cherry/blue, /obj/item/seeds/cherry/bulb)
reagents_add = list("nutriment" = 0.07, "sugar" = 0.07)
/obj/item/reagent_containers/food/snacks/grown/cherries
@@ -162,6 +163,31 @@
tastes = list("blue cherry" = 1)
wine_power = 50
//Cherry Bulbs
/obj/item/seeds/cherry/bulb
name = "pack of cherry bulb pits"
desc = "The glowy kind of cherries."
icon_state = "seed-cherrybulb"
species = "cherrybulb"
plantname = "Cherry Bulb Tree"
product = /obj/item/reagent_containers/food/snacks/grown/cherrybulbs
genes = list(/datum/plant_gene/trait/repeated_harvest, /datum/plant_gene/trait/glow/pink)
mutatelist = list()
reagents_add = list("nutriment" = 0.07, "sugar" = 0.07)
rarity = 10
/obj/item/reagent_containers/food/snacks/grown/cherrybulbs
seed = /obj/item/seeds/cherry/bulb
name = "cherry bulbs"
desc = "They're like little Space Christmas lights!"
icon_state = "cherry_bulb"
filling_color = "#FF0000"
bitesize_mod = 2
foodtype = FRUIT
grind_results = list(/datum/reagent/consumable/cherryjelly = 0)
tastes = list("cherry" = 1)
wine_power = 50
// Grapes
/obj/item/seeds/grape
name = "pack of grape seeds"
@@ -224,6 +250,10 @@
species = "strawberry"
plantname = "Strawberry Vine"
product = /obj/item/reagent_containers/food/snacks/grown/strawberry
growthstages = 6
growing_icon = 'icons/obj/hydroponics/growing_fruits.dmi'
icon_grow = "strawberry-grow"
icon_dead = "berry-dead"
reagents_add = list("vitamin" = 0.07, "nutriment" = 0.1, "sugar" = 0.2)
mutatelist = list()
+37 -1
View File
@@ -49,7 +49,7 @@
icon_grow = "lime-grow"
icon_dead = "lime-dead"
genes = list(/datum/plant_gene/trait/repeated_harvest)
mutatelist = list(/obj/item/seeds/lime)
mutatelist = list(/obj/item/seeds/lime, /obj/item/seeds/orange_3d)
reagents_add = list("vitamin" = 0.04, "nutriment" = 0.05)
/obj/item/reagent_containers/food/snacks/grown/citrus/orange
@@ -61,6 +61,42 @@
juice_results = list("orangejuice" = 0)
distill_reagent = "triple_sec"
//3D Orange
/obj/item/seeds/orange_3d
name = "pack of extradimensional orange seeds"
desc = "Polygonal seeds."
icon_state = "seed-orange"
species = "orange"
plantname = "Extradimensional Orange Tree"
product = /obj/item/reagent_containers/food/snacks/grown/citrus/orange
lifespan = 60
endurance = 50
yield = 5
potency = 20
growing_icon = 'icons/obj/hydroponics/growing_fruits.dmi'
icon_grow = "lime-grow"
icon_dead = "lime-dead"
genes = list(/datum/plant_gene/trait/repeated_harvest)
reagents_add = list("vitamin" = 0.04, "nutriment" = 0.05, "haloperidol" = 0.15)
/obj/item/reagent_containers/food/snacks/grown/citrus/orange_3d
seed = /obj/item/seeds/orange
name = "extradminesional orange"
desc = "You can hardly wrap your head around this thing."
icon_state = "orang"
filling_color = "#FFA500"
juice_results = list("orangejuice" = 0)
distill_reagent = "triple_sec"
tastes = list("polygons" = 1, "oranges" = 1)
/obj/item/reagent_containers/food/snacks/grown/citrus/orange_3d/pickup(mob/user)
. = ..()
icon_state = "orange"
/obj/item/reagent_containers/food/snacks/grown/citrus/orange_3d/dropped(mob/user)
. = ..()
icon_state = "orang"
// Lemon
/obj/item/seeds/lemon
name = "pack of lemon seeds"
+3 -2
View File
@@ -183,6 +183,7 @@
icon_grow = "moonflower-grow"
icon_dead = "sunflower-dead"
product = /obj/item/reagent_containers/food/snacks/grown/moonflower
genes = list(/datum/plant_gene/trait/glow/purple)
mutatelist = list()
reagents_add = list("moonshine" = 0.2, "vitamin" = 0.02, "nutriment" = 0.02)
rarity = 15
@@ -293,8 +294,8 @@
/obj/item/seeds/bee_balm/honey
name = "pack of Honey Balm seeds"
desc = "These seeds grow into Honey Balms."
icon_state = "seed-bee_balmalt"
species = "seed-bee_balm_alt"
icon_state = "seed-bee_balm_alt"
species = "bee_balmalt"
plantname = "Honey Balm Pods"
product = /obj/item/reagent_containers/food/snacks/grown/bee_balm/honey
endurance = 1
+22 -1
View File
@@ -15,7 +15,7 @@
icon_grow = "grass-grow"
icon_dead = "grass-dead"
genes = list(/datum/plant_gene/trait/repeated_harvest)
mutatelist = list(/obj/item/seeds/grass/carpet)
mutatelist = list(/obj/item/seeds/grass/carpet, /obj/item/seeds/grass/fairy)
reagents_add = list("nutriment" = 0.02, "hydrogen" = 0.05)
/obj/item/reagent_containers/food/snacks/grown/grass
@@ -40,6 +40,27 @@
new stacktype(user.drop_location(), grassAmt)
qdel(src)
//Fairygrass
/obj/item/seeds/grass/fairy
name = "pack of fairygrass seeds"
desc = "These seeds grow into a more mystical grass."
icon_state = "seed-fairygrass"
species = "fairygrass"
plantname = "Fairygrass"
product = /obj/item/reagent_containers/food/snacks/grown/grass/fairy
icon_grow = "fairygrass-grow"
icon_dead = "fairygrass-dead"
genes = list(/datum/plant_gene/trait/repeated_harvest, /datum/plant_gene/trait/glow/blue)
reagents_add = list("nutriment" = 0.02, "hydrogen" = 0.05, "space_drugs" = 0.15)
/obj/item/reagent_containers/food/snacks/grown/grass/fairy
seed = /obj/item/seeds/grass/fairy
name = "fairygrass"
desc = "Blue, glowing, and smells fainly of mushrooms."
icon_state = "fairygrassclump"
filling_color = "#3399ff"
stacktype = /obj/item/stack/tile/fairygrass
// Carpet
/obj/item/seeds/grass/carpet
name = "pack of carpet seeds"
+1
View File
@@ -44,6 +44,7 @@
species = "holymelon"
plantname = "Holy Melon Vines"
product = /obj/item/reagent_containers/food/snacks/grown/holymelon
genes = list(/datum/plant_gene/trait/glow/yellow)
mutatelist = list()
reagents_add = list("holywater" = 0.2, "vitamin" = 0.04, "nutriment" = 0.1)
rarity = 20
+280
View File
@@ -142,6 +142,7 @@
yield = 4
growthstages = 3
reagents_add = list("sugar" = 0.25)
mutatelist = list(/obj/item/seeds/bamboo)
/obj/item/reagent_containers/food/snacks/grown/sugarcane
seed = /obj/item/seeds/sugarcane
@@ -239,3 +240,282 @@
product = /obj/item/reagent_containers/food/snacks/grown/ash_flora/cactus_fruit
growing_icon = 'icons/obj/hydroponics/growing_fruits.dmi'
growthstages = 2
// Coconut
/obj/item/seeds/coconut
name = "pack of coconut seeds"
desc = "They're seeds that grow into coconut palm trees."
icon_state = "seed-coconut"
species = "coconut"
plantname = "Coconut Palm Tree"
product = /obj/item/reagent_containers/food/snacks/grown/coconut
lifespan = 50
endurance = 30
potency = 35
growing_icon = 'icons/obj/hydroponics/growing.dmi'
icon_dead = "coconut-dead"
genes = list(/datum/plant_gene/trait/repeated_harvest)
forbiddengenes = list(/datum/plant_gene/trait/squash, /datum/plant_gene/trait/stinging)
reagents_add = list("coconutmilk" = 0.3)
/obj/item/reagent_containers/food/snacks/grown/coconut
seed = /obj/item/seeds/coconut
name = "coconut"
desc = "Hard shell of a nut containing delicious milk inside. Perhaps try using something sharp?"
icon_state = "coconut"
item_state = "coconut"
possible_transfer_amounts = list(5, 10, 15, 20, 25, 30, 50)
spillable = FALSE
resistance_flags = ACID_PROOF
volume = 150 //so it won't cut reagents despite having the capacity for them
w_class = WEIGHT_CLASS_SMALL
force = 5
throwforce = 5
hitsound = 'sound/weapons/klonk.ogg'
attack_verb = list("klonked", "donked", "bonked")
var/opened = FALSE
var/carved = FALSE
var/chopped = FALSE
var/straw = FALSE
var/fused = FALSE
var/fusedactive = FALSE
var/defused = FALSE
/obj/item/reagent_containers/food/snacks/grown/coconut/Initialize(mapload, obj/item/seeds/new_seed)
. = ..()
var/newvolume
newvolume = 50 + round(seed.potency,10)
if (seed.get_gene(/datum/plant_gene/trait/maxchem))
newvolume = newvolume + 50
volume = newvolume
reagents.maximum_volume = newvolume
reagents.update_total()
transform *= TRANSFORM_USING_VARIABLE(40, 100) + 0.5 //temporary fix for size?
/obj/item/reagent_containers/food/snacks/grown/coconut/attack_self(mob/user)
if (opened == TRUE)
if(possible_transfer_amounts.len)
var/i=0
for(var/A in possible_transfer_amounts)
i++
if(A == amount_per_transfer_from_this)
if(i<possible_transfer_amounts.len)
amount_per_transfer_from_this = possible_transfer_amounts[i+1]
else
amount_per_transfer_from_this = possible_transfer_amounts[1]
to_chat(user, "<span class='notice'>[src]'s transfer amount is now [amount_per_transfer_from_this] units.</span>")
return
/obj/item/reagent_containers/food/snacks/grown/coconut/attackby(obj/item/W, mob/user, params)
//DEFUSING NADE LOGIC
if (W.tool_behaviour == TOOL_WIRECUTTER && fused == TRUE)
user.show_message("<span class='notice'>You cut the fuse!</span>", 1)
playsound(user, W.hitsound, 50, 1, -1)
icon_state = "coconut_carved"
desc = "A coconut. This one's got a hole in it."
name = "coconut"
defused = TRUE
fused = FALSE
fusedactive = FALSE
if(!seed.get_gene(/datum/plant_gene/trait/glow))
set_light(0, 0.0)
return
//IGNITING NADE LOGIC
if(fusedactive == FALSE && fused == TRUE)
var/lighting_text = W.ignition_effect(src, user)
if(lighting_text)
user.visible_message("<span class='warning'>[user] ignites [src]'s fuse!</span>", "<span class='userdanger'>You ignite the [src]'s fuse!</span>")
fusedactive = TRUE
defused = FALSE
playsound(src, 'sound/effects/fuse.ogg', 100, 0)
message_admins("[ADMIN_LOOKUPFLW(user)] ignited a coconut bomb for detonation at [ADMIN_VERBOSEJMP(user)] "+ pretty_string_from_reagent_list(reagents.reagent_list))
log_game("[key_name(user)] primed a coconut grenade for detonation at [AREACOORD(user)].")
addtimer(CALLBACK(src, .proc/prime), 5 SECONDS)
icon_state = "coconut_grenade_active"
desc = "RUN!"
if(!seed.get_gene(/datum/plant_gene/trait/glow))
light_color = "#FFCC66" //for the fuse
set_light(3, 0.8)
return
//ADDING A FUSE, NADE LOGIC
if (istype(W,/obj/item/stack/sheet/cloth) || istype(W,/obj/item/stack/sheet/durathread))
if (carved == TRUE && straw == FALSE && fused == FALSE)
user.show_message("<span class='notice'>You add a fuse to the coconut!</span>", 1)
W.use(1)
fused = TRUE
icon_state = "coconut_grenade"
desc = "A makeshift bomb made out of a coconut. You estimate the fuse is long enough for 5 seconds."
name = "coconut bomb"
return
//ADDING STRAW LOGIC
if (istype(W,/obj/item/stack/sheet/mineral/bamboo) && opened == TRUE && straw == FALSE && fused == FALSE)
user.show_message("<span class='notice'>You add a bamboo straw to the coconut!</span>", 1)
straw = TRUE
W.use(1)
icon_state += "_straw"
desc = "You can already feel like you're on a tropical vacation."
//OPENING THE NUT LOGIC
if (carved == FALSE && chopped == FALSE)
if(W.tool_behaviour == TOOL_SCREWDRIVER)
user.show_message("<span class='notice'>You make a hole in the coconut!</span>", 1)
carved = TRUE
opened = TRUE
reagent_flags = OPENCONTAINER
ENABLE_BITFIELD(reagents.reagents_holder_flags, OPENCONTAINER)
icon_state = "coconut_carved"
desc = "A coconut. This one's got a hole in it."
playsound(user, W.hitsound, 50, 1, -1)
return
else if(W.sharpness)
user.show_message("<span class='notice'>You slice the coconut open!</span>", 1)
chopped = TRUE
opened = TRUE
reagent_flags = OPENCONTAINER
ENABLE_BITFIELD(reagents.reagents_holder_flags, OPENCONTAINER)
spillable = TRUE
icon_state = "coconut_chopped"
desc = "A coconut. This one's sliced open, with all its delicious contents for your eyes to savour."
playsound(user, W.hitsound, 50, 1, -1)
return
/obj/item/reagent_containers/food/snacks/grown/coconut/attack(mob/living/M, mob/user, obj/target)
if(M && user.a_intent == INTENT_HARM && spillable == FALSE)
var/obj/item/bodypart/affecting = user.zone_selected //Find what the player is aiming at
if (affecting == BODY_ZONE_HEAD && prob(15))
//smash the nut open
var/armor_block = min(90, M.run_armor_check(affecting, "melee", null, null,armour_penetration)) // For normal attack damage
M.apply_damage(force, BRUTE, affecting, armor_block)
//Sound
playsound(user, hitsound, 100, 1, -1)
//Attack logs
log_combat(user, M, "attacked", src)
//Display an attack message.
if(M != user)
M.visible_message("<span class='danger'>[user] has cracked open a [src.name] on [M]'s head!</span>", \
"<span class='userdanger'>[user] has cracked open a [src.name] on [M]'s head!</span>")
else
user.visible_message("<span class='danger'>[M] cracks open a [src.name] on their [M.p_them()] head!</span>", \
"<span class='userdanger'>[M] cracks open a [src.name] on [M.p_their()] head!</span>")
//The coconut breaks open so splash its reagents
spillable = TRUE
SplashReagents(M)
//Lastly we remove the nut
qdel(src)
else
. = ..()
return
if(fusedactive)
return
if(opened == FALSE)
return
if(!canconsume(M, user))
return
if(!reagents || !reagents.total_volume)
to_chat(user, "<span class='warning'>[src] is empty!</span>")
return
if(istype(M))
if(user.a_intent == INTENT_HARM && spillable == TRUE)
var/R
M.visible_message("<span class='danger'>[user] splashes the contents of [src] onto [M]!</span>", \
"<span class='userdanger'>[user] splashes the contents of [src] onto [M]!</span>")
if(reagents)
for(var/datum/reagent/A in reagents.reagent_list)
R += A.id + " ("
R += num2text(A.volume) + "),"
if(isturf(target) && reagents.reagent_list.len && thrownby)
log_combat(thrownby, target, "splashed (thrown) [english_list(reagents.reagent_list)]")
message_admins("[ADMIN_LOOKUPFLW(thrownby)] splashed (thrown) [english_list(reagents.reagent_list)] on [target] at [ADMIN_VERBOSEJMP(target)].")
reagents.reaction(M, TOUCH)
log_combat(user, M, "splashed", R)
reagents.clear_reagents()
else
if(M != user)
M.visible_message("<span class='danger'>[user] attempts to feed something to [M].</span>", \
"<span class='userdanger'>[user] attempts to feed something to you.</span>")
if(!do_mob(user, M))
return
if(!reagents || !reagents.total_volume)
return // The drink might be empty after the delay, such as by spam-feeding
M.visible_message("<span class='danger'>[user] feeds something to [M].</span>", "<span class='userdanger'>[user] feeds something to you.</span>")
log_combat(user, M, "fed", reagents.log_list())
else
to_chat(user, "<span class='notice'>You swallow a gulp of [src].</span>")
var/fraction = min(5/reagents.total_volume, 1)
reagents.reaction(M, INGEST, fraction)
addtimer(CALLBACK(reagents, /datum/reagents.proc/trans_to, M, 5), 5)
playsound(M.loc,'sound/items/drink.ogg', rand(10,50), 1)
/obj/item/reagent_containers/food/snacks/grown/coconut/afterattack(obj/target, mob/user, proximity)
. = ..()
if(fusedactive)
return
if((!proximity) || !check_allowed_items(target,target_self=1))
return
if(target.is_refillable()) //Something like a glass. Player probably wants to transfer TO it.
if(!reagents.total_volume)
to_chat(user, "<span class='warning'>[src] is empty!</span>")
return
if(target.reagents.holder_full())
to_chat(user, "<span class='warning'>[target] is full.</span>")
return
var/trans = reagents.trans_to(target, amount_per_transfer_from_this)
to_chat(user, "<span class='notice'>You transfer [trans] unit\s of the solution to [target].</span>")
else if(target.is_drainable()) //A dispenser. Transfer FROM it TO us.
if(!target.reagents.total_volume)
to_chat(user, "<span class='warning'>[target] is empty and can't be refilled!</span>")
return
if(reagents.holder_full())
to_chat(user, "<span class='warning'>[src] is full.</span>")
return
var/trans = target.reagents.trans_to(src, amount_per_transfer_from_this)
to_chat(user, "<span class='notice'>You fill [src] with [trans] unit\s of the contents of [target].</span>")
else if(reagents.total_volume)
if(user.a_intent == INTENT_HARM && spillable == TRUE)
user.visible_message("<span class='danger'>[user] splashes the contents of [src] onto [target]!</span>", \
"<span class='notice'>You splash the contents of [src] onto [target].</span>")
reagents.reaction(target, TOUCH)
reagents.clear_reagents()
/obj/item/reagent_containers/food/snacks/grown/coconut/dropped(mob/user)
. = ..()
transform *= TRANSFORM_USING_VARIABLE(40, 100) + 0.5 //temporary fix for size?
/obj/item/reagent_containers/food/snacks/grown/coconut/proc/prime()
if (!defused)
var/turf/T = get_turf(src)
reagents.chem_temp = 1000
//Disable seperated contents when the grenade primes
if (seed.get_gene(/datum/plant_gene/trait/noreact))
DISABLE_BITFIELD(reagents.reagents_holder_flags, NO_REACT)
reagents.handle_reactions()
log_game("Coconut bomb detonation at [AREACOORD(T)], location [loc]")
qdel(src)
/obj/item/reagent_containers/food/snacks/grown/coconut/ex_act(severity)
qdel(src)
/obj/item/reagent_containers/food/snacks/grown/coconut/deconstruct(disassembled = TRUE)
if(!disassembled && fused)
prime()
if(!QDELETED(src))
qdel(src)
@@ -98,6 +98,49 @@
/obj/item/grown/log/steel/CheckAccepted(obj/item/I)
return FALSE
/obj/item/seeds/bamboo
name = "pack of bamboo seeds"
desc = "A plant known for its flexible and resistant logs."
icon_state = "seed-bamboo"
species = "bamboo"
plantname = "Bamboo"
product = /obj/item/grown/log/bamboo
lifespan = 80
endurance = 70
maturation = 15
production = 2
yield = 5
potency = 50
growthstages = 2
growing_icon = 'icons/obj/hydroponics/growing.dmi'
icon_dead = "bamboo-dead"
genes = list(/datum/plant_gene/trait/repeated_harvest)
/obj/item/grown/log/bamboo
seed = /obj/item/seeds/bamboo
name = "bamboo log"
desc = "A long and resistant bamboo log."
icon_state = "bamboo"
plank_type = /obj/item/stack/sheet/mineral/bamboo
plank_name = "bamboo sticks"
/obj/item/grown/log/bamboo/CheckAccepted(obj/item/I)
return FALSE
/obj/structure/punji_sticks
name = "punji sticks"
desc = "Don't step on this."
icon = 'icons/obj/hydroponics/equipment.dmi'
icon_state = "punji"
resistance_flags = FLAMMABLE
max_integrity = 30
density = FALSE
anchored = TRUE
/obj/structure/punji_sticks/Initialize(mapload)
. = ..()
AddComponent(/datum/component/caltrop, 20, 30, 100, CALTROP_BYPASS_SHOES)
/////////BONFIRES//////////
/obj/structure/bonfire
+32 -7
View File
@@ -301,14 +301,39 @@
/datum/plant_gene/trait/glow/shadow/glow_power(obj/item/seeds/S)
return -max(S.potency*(rate*0.2), 0.2)
/datum/plant_gene/trait/glow/red
name = "Red Electrical Glow"
glow_color = LIGHT_COLOR_RED
//Colored versions of bioluminescence.
datum/plant_gene/trait/glow/white
name = "White Bioluminescence"
glow_color = "#FFFFFF"
/datum/plant_gene/trait/glow/berry
name = "Strong Bioluminescence"
rate = 0.05
glow_color = null
/datum/plant_gene/trait/glow/red
name = "Red Bioluminescence"
glow_color = "#FF3333"
/datum/plant_gene/trait/glow/yellow
//not the disgusting glowshroom yellow hopefully
name = "Yellow Bioluminescence"
glow_color = "#FFFF66"
/datum/plant_gene/trait/glow/green
//oh no, now i'm radioactive
name = "Green Bioluminescence"
glow_color = "#99FF99"
/datum/plant_gene/trait/glow/blue
//the best one
name = "Blue Bioluminescence"
glow_color = "#6699FF"
/datum/plant_gene/trait/glow/purple
//did you know that notepad++ doesnt think bioluminescence is a word
name = "Purple Bioluminescence"
glow_color = "#D966FF"
/datum/plant_gene/trait/glow/pink
//gay tide station pride
name = "Pink Bioluminescence"
glow_color = "#FFB3DA"
/datum/plant_gene/trait/teleport
+6 -1
View File
@@ -26,6 +26,7 @@
var/rarity = 0 // How rare the plant is. Used for giving points to cargo when shipping off to CentCom.
var/list/mutatelist = list() // The type of plants that this plant can mutate into.
var/list/genes = list() // Plant genes are stored here, see plant_genes.dm for more info.
var/list/forbiddengenes = list() // Plant genes that the seed may be forbidden from having.
var/list/reagents_add = list()
// A list of reagents to add to product.
// Format: "reagent_id" = potency multiplier
@@ -90,6 +91,10 @@
/obj/item/seeds/proc/get_gene(typepath)
return (locate(typepath) in genes)
obj/item/seeds/proc/is_gene_forbidden(typepath)
return (locate(typepath) in forbiddengenes)
/obj/item/seeds/proc/reagents_from_genes()
reagents_add = list()
for(var/datum/plant_gene/reagent/R in genes)
@@ -390,7 +395,7 @@
for(var/i in 1 to amount_random_traits)
var/random_trait = pick((subtypesof(/datum/plant_gene/trait)-typesof(/datum/plant_gene/trait/plant_type)))
var/datum/plant_gene/trait/T = new random_trait
if(T.can_add(src))
if(T.can_add(src) && !is_gene_forbidden(T))
genes += T
else
qdel(T)
+1 -1
View File
@@ -231,7 +231,7 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
var/r_val
var/b_val
var/g_val
var/color_format = lentext(input_color)
var/color_format = length(input_color)
if(color_format == 3)
r_val = hex2num(copytext(input_color, 1, 2))*16
g_val = hex2num(copytext(input_color, 2, 3))*16
@@ -781,7 +781,7 @@
broken_plural = TRUE
else
var/holder = broken[1] //our one and only element
if(holder[lentext(holder)] == "s")
if(holder[length(holder)] == "s")
broken_plural = TRUE
//Put the items in that list into a string of text
for(var/B in broken)
@@ -793,7 +793,7 @@
damaged_plural = TRUE
else
var/holder = damaged[1]
if(holder[lentext(holder)] == "s")
if(holder[length(holder)] == "s")
damaged_plural = TRUE
for(var/D in damaged)
damaged_message += D
@@ -94,6 +94,10 @@
var/ignorelistcleanuptimer = 1 // This ticks up every automated action, at 300 we clean the ignore list
var/robot_arm = /obj/item/bodypart/r_arm/robot
var/commissioned = FALSE // Will other (noncommissioned) bots salute this bot?
var/can_salute = TRUE
var/salute_delay = 60 SECONDS
hud_possible = list(DIAG_STAT_HUD, DIAG_BOT_HUD, DIAG_HUD, DIAG_PATH_HUD = HUD_LIST_LIST) //Diagnostic HUD views
/mob/living/simple_animal/bot/proc/get_mode()
@@ -244,6 +248,14 @@
if(!on || client)
return
if(!commissioned && can_salute)
for(var/mob/living/simple_animal/bot/B in get_hearers_in_view(5, get_turf(src)))
if(B.commissioned)
visible_message("<b>[src]</b> performs an elaborate salute for [B]!")
can_salute = FALSE
addtimer(VARSET_CALLBACK(src, can_salute, TRUE), salute_delay)
break
switch(mode) //High-priority overrides are processed first. Bots can do nothing else while under direct command.
if(BOT_RESPONDING) //Called by the AI.
call_mode()
@@ -14,13 +14,14 @@
model = "Cleanbot"
bot_core_type = /obj/machinery/bot_core/cleanbot
window_id = "autoclean"
window_name = "Automatic Station Cleaner v1.2"
window_name = "Automatic Station Cleaner v1.4"
pass_flags = PASSMOB
path_image_color = "#993299"
var/blood = 1
var/trash = 0
var/pests = 0
var/drawn = 0
var/list/target_types
var/obj/effect/decal/cleanable/target
@@ -32,14 +33,81 @@
var/next_dest
var/next_dest_loc
var/obj/item/weapon
var/weapon_orig_force = 0
var/chosen_name
var/list/stolen_valor
var/static/list/officers = list("Captain", "Head of Personnel", "Head of Security")
var/static/list/command = list("Captain" = "Cpt.","Head of Personnel" = "Lt.")
var/static/list/security = list("Head of Security" = "Maj.", "Warden" = "Sgt.", "Detective" = "Det.", "Security Officer" = "Officer")
var/static/list/engineering = list("Chief Engineer" = "Chief Engineer", "Station Engineer" = "Engineer", "Atmospherics Technician" = "Technician")
var/static/list/medical = list("Chief Medical Officer" = "C.M.O.", "Medical Doctor" = "M.D.", "Chemist" = "Pharm.D.")
var/static/list/research = list("Research Director" = "Ph.D.", "Roboticist" = "M.S.", "Scientist" = "B.S.")
var/static/list/legal = list("Lawyer" = "Esq.")
var/list/prefixes
var/list/suffixes
/mob/living/simple_animal/bot/cleanbot/proc/deputize(obj/item/W, mob/user)
if(in_range(src, user))
to_chat(user, "<span class='notice'>You attach \the [W] to \the [src].</span>")
user.transferItemToLoc(W, src)
weapon = W
weapon_orig_force = weapon.force
if(!emagged)
weapon.force = weapon.force / 2
add_overlay(image(icon=weapon.lefthand_file,icon_state=weapon.item_state))
/mob/living/simple_animal/bot/cleanbot/proc/update_titles()
var/working_title = ""
for(var/pref in prefixes)
for(var/title in pref)
if(title in stolen_valor)
working_title += pref[title] + " "
if(title in officers)
commissioned = TRUE
break
working_title += chosen_name
for(var/suf in suffixes)
for(var/title in suf)
if(title in stolen_valor)
working_title += " " + suf[title]
break
name = working_title
/mob/living/simple_animal/bot/cleanbot/examine(mob/user)
. = ..()
if(weapon)
. += " <span class='warning'>Is that \a [weapon] taped to it...?</span>"
/mob/living/simple_animal/bot/cleanbot/Initialize()
. = ..()
chosen_name = name
get_targets()
icon_state = "cleanbot[on]"
var/datum/job/janitor/J = new/datum/job/janitor
access_card.access += J.get_access()
prev_access = access_card.access
stolen_valor = list()
prefixes = list(command, security, engineering)
suffixes = list(research, medical, legal)
/mob/living/simple_animal/bot/cleanbot/Destroy()
if(weapon)
var/atom/Tsec = drop_location()
weapon.force = weapon_orig_force
drop_part(weapon, Tsec)
return ..()
/mob/living/simple_animal/bot/cleanbot/turn_on()
..()
@@ -53,6 +121,8 @@
/mob/living/simple_animal/bot/cleanbot/bot_reset()
..()
if(weapon && emagged == 2)
weapon.force = weapon_orig_force
ignore_list = list() //Allows the bot to clean targets it previously ignored due to being unreachable.
target = null
oldloc = null
@@ -62,6 +132,22 @@
text_dehack = "[name]'s software has been reset!"
text_dehack_fail = "[name] does not seem to respond to your repair code!"
/mob/living/simple_animal/bot/cleanbot/Crossed(atom/movable/AM)
. = ..()
zone_selected = pick(BODY_ZONE_L_LEG, BODY_ZONE_R_LEG)
if(weapon && has_gravity() && ismob(AM))
var/mob/living/carbon/C = AM
if(!istype(C))
return
if(!(C.job in stolen_valor))
stolen_valor += C.job
update_titles()
weapon.attack(C, src)
C.Knockdown(20)
/mob/living/simple_animal/bot/cleanbot/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/card/id)||istype(W, /obj/item/pda))
if(bot_core.allowed(user) && !open && !emagged)
@@ -74,12 +160,19 @@
to_chat(user, "<span class='warning'>Please close the access panel before locking it.</span>")
else
to_chat(user, "<span class='notice'>\The [src] doesn't seem to respect your authority.</span>")
else if(istype(W, /obj/item/kitchen/knife) && user.a_intent != INTENT_HARM)
to_chat(user, "<span class='notice'>You start attaching \the [W] to \the [src]...</span>")
if(do_after(user, 25, target = src))
deputize(W, user)
else
return ..()
/mob/living/simple_animal/bot/cleanbot/emag_act(mob/user)
..()
if(emagged == 2)
if(weapon)
weapon.force = weapon_orig_force
if(user)
to_chat(user, "<span class='danger'>[src] buzzes and beeps.</span>")
@@ -132,6 +225,9 @@
if(!target && trash) //Then for trash.
target = scan(/obj/item/trash)
if(!target && trash) //Search for dead mices.
target = scan(/obj/item/reagent_containers/food/snacks/deadmouse)
if(!target && auto_patrol) //Search for cleanables it can see.
if(mode == BOT_IDLE || mode == BOT_START_PATROL)
start_patrol()
@@ -177,7 +273,6 @@
/obj/effect/decal/cleanable/oil,
/obj/effect/decal/cleanable/vomit,
/obj/effect/decal/cleanable/robot_debris,
/obj/effect/decal/cleanable/crayon,
/obj/effect/decal/cleanable/molten_object,
/obj/effect/decal/cleanable/tomato_smudge,
/obj/effect/decal/cleanable/egg_smudge,
@@ -199,33 +294,37 @@
target_types += /mob/living/simple_animal/cockroach
target_types += /mob/living/simple_animal/mouse
if(drawn)
target_types += /obj/effect/decal/cleanable/crayon
if(trash)
target_types += /obj/item/trash
target_types += /obj/item/reagent_containers/food/snacks/deadmouse
target_types = typecacheof(target_types)
/mob/living/simple_animal/bot/cleanbot/UnarmedAttack(atom/A)
if(istype(A, /obj/effect/decal/cleanable))
anchored = TRUE
if(is_cleanable(A))
icon_state = "cleanbot-c"
visible_message("<span class='notice'>[src] begins to clean up [A].</span>")
mode = BOT_CLEANING
spawn(50)
if(mode == BOT_CLEANING)
if(A && isturf(A.loc))
var/atom/movable/AM = A
if(istype(AM, /obj/effect/decal/cleanable))
for(var/obj/effect/decal/cleanable/C in A.loc)
qdel(C)
anchored = FALSE
target = null
mode = BOT_IDLE
icon_state = "cleanbot[on]"
var/turf/T = get_turf(A)
if(do_after(src, 1, target = T))
SEND_SIGNAL(T, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_MEDIUM)
visible_message("<span class='notice'>[src] cleans \the [T].</span>")
for(var/atom/dirtything in T)
if(is_cleanable(dirtything))
qdel(dirtything)
target = null
mode = BOT_IDLE
icon_state = "cleanbot[on]"
else if(istype(A, /obj/item) || istype(A, /obj/effect/decal/remains))
visible_message("<span class='danger'>[src] sprays hydrofluoric acid at [A]!</span>")
playsound(src, 'sound/effects/spray2.ogg', 50, 1, -6)
playsound(src, 'sound/effects/spray2.ogg', 50, TRUE, -6)
A.acid_act(75, 10)
target = null
else if(istype(A, /mob/living/simple_animal/cockroach) || istype(A, /mob/living/simple_animal/mouse))
var/mob/living/simple_animal/M = target
if(!M.stat)
@@ -245,7 +344,7 @@
"MY ONLY MISSION IS TO CLEANSE THE WORLD OF EVIL.", "EXTERMINATING PESTS.")
say(phrase)
victim.emote("scream")
playsound(src.loc, 'sound/effects/spray2.ogg', 50, 1, -6)
playsound(src.loc, 'sound/effects/spray2.ogg', 50, TRUE, -6)
victim.acid_act(5, 100)
else if(A == src) // Wets floors and spawns foam randomly
if(prob(75))
@@ -277,7 +376,6 @@
/obj/machinery/bot_core/cleanbot
req_one_access = list(ACCESS_JANITOR, ACCESS_ROBOTICS)
/mob/living/simple_animal/bot/cleanbot/get_controls(mob/user)
var/dat
dat += hack(user)
@@ -289,6 +387,7 @@ Maintenance panel panel is [open ? "opened" : "closed"]"})
if(!locked || issilicon(user)|| IsAdminGhost(user))
dat += "<BR>Clean Blood: <A href='?src=[REF(src)];operation=blood'>[blood ? "Yes" : "No"]</A>"
dat += "<BR>Clean Trash: <A href='?src=[REF(src)];operation=trash'>[trash ? "Yes" : "No"]</A>"
dat += "<BR>Clean Graffiti: <A href='?src=[REF(src)];operation=drawn'>[drawn ? "Yes" : "No"]</A>"
dat += "<BR>Exterminate Pests: <A href='?src=[REF(src)];operation=pests'>[pests ? "Yes" : "No"]</A>"
dat += "<BR><BR>Patrol Station: <A href='?src=[REF(src)];operation=patrol'>[auto_patrol ? "Yes" : "No"]</A>"
return dat
@@ -304,5 +403,7 @@ Maintenance panel panel is [open ? "opened" : "closed"]"})
pests = !pests
if("trash")
trash = !trash
if("drawn")
drawn = !drawn
get_targets()
update_controls()
+27 -9
View File
@@ -3,6 +3,8 @@
/mob/living
var/last_taste_time
var/last_taste_text
var/last_ph_taste_time
var/last_ph_taste_number
/mob/living/proc/get_taste_sensitivity()
return DEFAULT_TASTE_SENSITIVITY
@@ -49,14 +51,30 @@
say("The pH is appropriately [round(from.pH, 1)].")
return
if (!HAS_TRAIT(src, TRAIT_AGEUSIA)) //I'll let you get away with not having 1 damage.
switch(from.pH)
if(11.5 to INFINITY)
to_chat(src, "<span class='warning'>You taste a strong alkaline flavour!</span>")
if(8.5 to 11.5)
to_chat(src, "<span class='notice'>You taste a sort of soapy tone in the mixture.</span>")
if(2.5 to 5.5)
to_chat(src, "<span class='notice'>You taste a sort of acid tone in the mixture.</span>")
if(-INFINITY to 2.5)
to_chat(src, "<span class='warning'>You taste a strong acidic flavour!</span>")
if(last_ph_taste_time + 50 < world.time)
var/ph_taste_number
switch(from.pH)
if(11.5 to INFINITY)
ph_taste_number = 1
if(8.5 to 11.5)
ph_taste_number = 2
if(2.5 to 5.5)
ph_taste_number = 3
if(-INFINITY to 2.5)
ph_taste_number = 4
if(ph_taste_number != last_ph_taste_number || last_ph_taste_time + 200 < world.time)
if (ph_taste_number == 1)
to_chat(src, "<span class='warning'>You taste a strong alkaline flavour!</span>")
if (ph_taste_number == 2)
to_chat(src, "<span class='notice'>You taste a sort of soapy tone in the mixture.</span>")
if (ph_taste_number == 3)
to_chat(src, "<span class='notice'>You taste a sort of acid tone in the mixture.</span>")
if (ph_taste_number == 4)
to_chat(src, "<span class='warning'>You taste a strong acidic flavour!</span>")
last_ph_taste_time = world.time
last_ph_taste_number = ph_taste_number
#undef DEFAULT_TASTE_SENSITIVITY
+4 -4
View File
@@ -67,8 +67,8 @@
/proc/slur(n,var/strength=50)
strength = min(strength,50)
var/phrase = html_decode(n)
var/leng = lentext(phrase)
var/counter=lentext(phrase)
var/leng = length(phrase)
var/counter=length(phrase)
var/newphrase=""
var/newletter=""
while(counter>=1)
@@ -102,8 +102,8 @@
/proc/cultslur(n) // Inflicted on victims of a stun talisman
var/phrase = html_decode(n)
var/leng = lentext(phrase)
var/counter=lentext(phrase)
var/leng = length(phrase)
var/counter=length(phrase)
var/newphrase=""
var/newletter=""
while(counter>=1)
+1 -1
View File
@@ -25,7 +25,7 @@
if(flavor_text && flavor_text != "")
// We are decoding and then encoding to not only get correct amount of characters, but also to prevent partial escaping characters being shown.
var/msg = html_decode(replacetext(flavor_text, "\n", " "))
if(lentext(msg) <= 40)
if(length(msg) <= 40)
return "<span class='notice'>[html_encode(msg)]</span>"
else
return "<span class='notice'>[html_encode(copytext(msg, 1, 37))]... <a href='?src=[REF(src)];flavor_more=1'>More...</span></a>"
@@ -122,3 +122,19 @@
else
to_chat(user, "<span class='notice'>You can't put the [A] into \the [src]!</span>")
return FALSE
/obj/item/gun/syringe/blowgun
name = "blowgun"
desc = "Fire syringes at a short distance."
icon_state = "blowgun"
item_state = "blowgun"
fire_sound = 'sound/weapons/grenadelaunch.ogg'
/obj/item/gun/syringe/blowgun/process_fire(atom/target, mob/living/user, message = TRUE, params = null, zone_override = "", bonus_spread = 0)
visible_message("<span class='danger'>[user] starts aiming with a blowgun!</span>")
if(do_after(user, 25, target = src))
var/shot
shot = ..()
if (shot == TRUE)
user.adjustStaminaLoss(15)
user.adjustOxyLoss(15)
@@ -2227,3 +2227,48 @@ All effects don't start immediately, but rather get worse over time; the rate is
taste_description = flavor
if(holder.my_atom)
holder.my_atom.on_reagent_change()
/datum/reagent/consumable/ethanol/gunfire
name = "Gunfire"
id = "gunfire"
description = "A drink that tastes like tiny explosions."
color = "#e4830d"
boozepwr = 40
quality = DRINK_GOOD
taste_description = "tiny explosions"
glass_icon_state = "gunfire"
glass_name = "Gunfire"
glass_desc = "It pops constantly as you look at it, giving off tiny sparks."
/datum/reagent/consumable/ethanol/hellfire/on_mob_life(mob/living/carbon/M)
if (prob(3))
to_chat(M,"<span class='notice'>You feel the gunfire pop in your mouth.</span>")
return ..()
/datum/reagent/consumable/ethanol/hellfire
name = "Hellfire"
id = "hellfire"
description = "A nice drink that isn't quite as hot as it looks."
color = "#fb2203"
boozepwr = 60
quality = DRINK_VERYGOOD
taste_description = "cold flames that lick at the top of your mouth"
glass_icon_state = "hellfire"
glass_name = "Hellfire"
glass_desc = "An amber colored drink that isn't quite as hot as it looks."
/datum/reagent/consumable/ethanol/hellfire/on_mob_life(mob/living/carbon/M)
M.adjust_bodytemperature(30 * TEMPERATURE_DAMAGE_COEFFICIENT, 0, BODYTEMP_NORMAL + 30)
return ..()
/datum/reagent/consumable/ethanol/sins_delight
name = "Sin's Delight"
id = "sins_delight"
description = "The drink smells like the seven sins."
color = "#330000"
boozepwr = 66
quality = DRINK_FANTASTIC
taste_description = "sin"
glass_icon_state = "sins_delight"
glass_name = "Sin's Delight"
glass_desc = "You can smell the seven sins rolling off the top of the glass."
@@ -242,6 +242,23 @@
. = 1
..()
/datum/reagent/consumable/coconutmilk
name = "Coconut Milk"
id = "coconutmilk"
description = "A transparent white liquid extracted from coconuts. Rich in taste."
color = "#DFDFDF" // rgb: 223, 223, 223
taste_description = "sweet milk"
quality = DRINK_GOOD
glass_icon_state = "glass_white"
glass_name = "glass of coconut milk"
glass_desc = "White and nutritious goodness!"
/datum/reagent/consumable/coconutmilk/on_mob_life(mob/living/carbon/M)
if(M.getBruteLoss() && prob(20))
M.heal_bodypart_damage(2,0, 0)
. = 1
..()
/datum/reagent/consumable/cream
name = "Cream"
id = "cream"
+2 -1
View File
@@ -17,6 +17,7 @@
var/spillable = FALSE
var/beaker_weakness_bitflag = NONE//Bitflag!
var/container_HP = 2
var/splashable = FALSE
/obj/item/reagent_containers/Initialize(mapload, vol)
. = ..()
@@ -92,7 +93,7 @@
transform = initial(transform)
/obj/item/reagent_containers/proc/SplashReagents(atom/target, thrown = FALSE)
if(!reagents || !reagents.total_volume || !spillable)
if(!reagents || !reagents.total_volume || !(splashable ? splashable : spillable))
return
if(ismob(target) && target.reagents)
@@ -21,6 +21,32 @@
build_path = /obj/item/kitchen/fork
category = list("initial","Dinnerware")
/datum/design/plastic_fork
name = "Plastic Fork"
id = "plastic_fork"
build_type = AUTOLATHE | PROTOLATHE
materials = list(MAT_PLASTIC = 80)
build_path = /obj/item/kitchen/fork/plastic
category = list("initial", "Tool Designs", "Dinnerware")
departmental_flags = DEPARTMENTAL_FLAG_SERVICE
/datum/design/plastic_spoon
name = "Plastic Spoon"
id = "plastic_spoon"
build_type = AUTOLATHE | PROTOLATHE
materials = list(MAT_PLASTIC = 120)
build_path = /obj/item/kitchen/spoon/plastic
category = list("initial", "Tool Designs", "Dinnerware")
departmental_flags = DEPARTMENTAL_FLAG_SERVICE
/datum/design/plastic_knife
name = "Plastic Knife"
id = "plastic_knife"
build_type = AUTOLATHE | PROTOLATHE
materials = list(MAT_PLASTIC = 100)
build_path = /obj/item/kitchen/knife/plastic
category = list("initial", "Tool Designs","Dinnerware")
/datum/design/tray
name = "Tray"
id = "tray"
@@ -41,3 +41,11 @@
build_path = /obj/item/circuitboard/computer/card
category = list("Computer Boards")
departmental_flags = DEPARTMENTAL_FLAG_SECURITY | DEPARTMENTAL_FLAG_ENGINEERING //Honestly should have a bridge techfab for this sometime.
/datum/design/board/advanced_camera
name = "Computer Design (Advanced Camera Console)"
desc = "Allows for the construction of circuit boards used to build advanced camera consoles."
id = "advanced_camera"
build_path = /obj/item/circuitboard/computer/advanced_camera
category = list("Computer Boards")
departmental_flags = DEPARTMENTAL_FLAG_SECURITY
@@ -476,6 +476,15 @@
category = list("Phazon")
//Exosuit Equipment
/datum/design/ripleyupgrade
name = "Ripley MK-1 to MK-II conversion kit"
id = "ripleyupgrade"
build_type = MECHFAB
build_path = /obj/item/mecha_parts/mecha_equipment/ripleyupgrade
materials = list(MAT_METAL=10000,MAT_PLASMA=10000)
construction_time = 100
category = list("Exosuit Equipment")
/datum/design/mech_hydraulic_clamp
name = "Exosuit Engineering Equipment (Hydraulic Clamp)"
id = "mech_hydraulic_clamp"
@@ -906,3 +906,16 @@
build_path = /obj/item/bodypart/r_arm/robot/surplus_upgraded
category = list("Medical Designs")
departmental_flags = DEPARTMENTAL_FLAG_MEDICAL
/datum/design/adv_dis_hypo
name = "Disposable Hypospray MK.II"
desc = "A cheaply made hypospray"
id = "disposable_hypospray"
build_type = PROTOLATHE
materials = list(MAT_METAL = 100, MAT_PLASTIC = 500)
construction_time = 40
build_path = /obj/item/hypospray/mkii/disposable
category = list("Medical Designs")
departmental_flags = DEPARTMENTAL_FLAG_MEDICAL
+4 -3
View File
@@ -11,7 +11,8 @@
design_ids = list("basic_matter_bin", "basic_cell", "basic_scanning", "basic_capacitor", "basic_micro_laser", "micro_mani",
"destructive_analyzer", "circuit_imprinter", "experimentor", "rdconsole", "design_disk", "tech_disk", "rdserver", "rdservercontrol", "mechfab",
"space_heater", "xlarge_beaker", "sec_rshot", "sec_bshot", "sec_slug", "sec_Islug", "sec_dart", "sec_38", "sec_38lethal",
"rglass","plasteel","plastitanium","plasmaglass","plasmareinforcedglass","titaniumglass","plastitaniumglass","chem_pack","medkit_cabinet")
"rglass","plasteel","plastitanium","plasmaglass","plasmareinforcedglass","titaniumglass","plastitaniumglass","chem_pack","medkit_cabinet",
"disposable_hypospray","plastic_knife","plastic_fork","plastic_spoon")
/datum/techweb_node/mmi
id = "mmi"
@@ -34,7 +35,7 @@
display_name = "Mechanical Exosuits"
description = "Mechanized exosuits that are several magnitudes stronger and more powerful than the average human."
design_ids = list("mecha_tracking", "mechacontrol", "mechapower", "mech_recharger", "ripley_chassis", "firefighter_chassis", "ripley_torso", "ripley_left_arm", "ripley_right_arm", "ripley_left_leg", "ripley_right_leg",
"ripley_main", "ripley_peri", "mech_hydraulic_clamp")
"ripley_main", "ripley_peri", "ripleyupgrade", "mech_hydraulic_clamp")
/datum/techweb_node/mech_tools
id = "mech_tools"
@@ -1052,7 +1053,7 @@
display_name = "Illegal Technology"
description = "Dangerous research used to create dangerous objects."
prereq_ids = list("adv_engi", "adv_weaponry", "explosive_weapons")
design_ids = list("decloner", "borg_syndicate_module", "suppressor", "largecrossbow", "donksofttoyvendor")
design_ids = list("decloner", "borg_syndicate_module", "suppressor", "largecrossbow", "donksofttoyvendor", "advanced_camera")
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 10000)
export_price = 5000
hidden = TRUE
@@ -0,0 +1,168 @@
/obj/vehicle/ridden/wheelchair/motorized
name = "motorized wheelchair"
desc = "A chair with big wheels. It seems to have a motor in it."
max_integrity = 150
var/speed = 2
var/power_efficiency = 1
var/power_usage = 100
var/panel_open = FALSE
var/list/required_parts = list(/obj/item/stock_parts/manipulator,
/obj/item/stock_parts/manipulator,
/obj/item/stock_parts/capacitor)
var/obj/item/stock_parts/cell/power_cell
/obj/vehicle/ridden/wheelchair/motorized/CheckParts(list/parts_list)
..()
refresh_parts()
/obj/vehicle/ridden/wheelchair/motorized/proc/refresh_parts()
speed = 1 // Should never be under 1
for(var/obj/item/stock_parts/manipulator/M in contents)
speed += M.rating
for(var/obj/item/stock_parts/capacitor/C in contents)
power_efficiency = C.rating
var/datum/component/riding/D = GetComponent(/datum/component/riding)
D.vehicle_move_delay = round(CONFIG_GET(number/movedelay/run_delay) * delay_multiplier) / speed
/obj/vehicle/ridden/wheelchair/motorized/obj_destruction(damage_flag)
var/turf/T = get_turf(src)
for(var/atom/movable/A in contents)
A.forceMove(T)
//if(isliving(A))
// var/mob/living/L = A
// L.update_mobility()
..()
/obj/vehicle/ridden/wheelchair/motorized/driver_move(mob/living/user, direction)
if(istype(user))
if(!canmove)
return FALSE
if(!power_cell)
to_chat(user, "<span class='warning'>There seems to be no cell installed in [src].</span>")
canmove = FALSE
addtimer(VARSET_CALLBACK(src, canmove, TRUE), 20)
return FALSE
if(power_cell.charge < power_usage / max(power_efficiency, 1))
to_chat(user, "<span class='warning'>The display on [src] blinks 'Out of Power'.</span>")
canmove = FALSE
addtimer(VARSET_CALLBACK(src, canmove, TRUE), 20)
return FALSE
if(user.get_num_arms() < arms_required)
to_chat(user, "<span class='warning'>You don't have enough arms to operate the motor controller!</span>")
canmove = FALSE
addtimer(VARSET_CALLBACK(src, canmove, TRUE), 20)
return FALSE
power_cell.use(power_usage / max(power_efficiency, 1))
return ..()
/obj/vehicle/ridden/wheelchair/motorized/set_move_delay(mob/living/user)
return
/obj/vehicle/ridden/wheelchair/motorized/post_buckle_mob(mob/living/user)
. = ..()
density = TRUE
/obj/vehicle/ridden/wheelchair/motorized/post_unbuckle_mob()
. = ..()
density = FALSE
/obj/vehicle/ridden/wheelchair/motorized/attack_hand(mob/living/user)
if(power_cell && panel_open)
power_cell.update_icon()
user.put_in_hands(power_cell)
power_cell = null
to_chat(user, "<span class='notice'>You remove the power cell from [src].</span>")
return
return ..()
/obj/vehicle/ridden/wheelchair/motorized/attackby(obj/item/I, mob/user, params)
if(I.tool_behaviour == TOOL_SCREWDRIVER)
I.play_tool_sound(src)
panel_open = !panel_open
user.visible_message("<span class='notice'>[user] [panel_open ? "opens" : "closes"] the maintenance panel on [src].</span>", "<span class='notice'>You [panel_open ? "open" : "close"] the maintenance panel.</span>")
return
if(panel_open)
if(istype(I, /obj/item/stock_parts/cell))
if(power_cell)
to_chat(user, "<span class='warning'>There is a power cell already installed.</span>")
else
I.forceMove(src)
power_cell = I
to_chat(user, "<span class='notice'>You install the [I].</span>")
refresh_parts()
return
if(istype(I, /obj/item/stock_parts))
var/obj/item/stock_parts/B = I
var/P
for(var/obj/item/stock_parts/A in contents)
for(var/D in required_parts)
if(ispath(A.type, D))
P = D
break
if(istype(B, P) && istype(A, P))
if(B.get_part_rating() > A.get_part_rating())
B.forceMove(src)
user.put_in_hands(A)
user.visible_message("<span class='notice'>[user] replaces [A] with [B] in [src].</span>", "<span class='notice'>You replace [A] with [B].</span>")
break
refresh_parts()
return
return ..()
/obj/vehicle/ridden/wheelchair/motorized/wrench_act(mob/living/user, obj/item/I)
to_chat(user, "<span class='notice'>You begin to detach the wheels...</span>")
if(I.use_tool(src, user, 40, volume=50))
to_chat(user, "<span class='notice'>You detach the wheels and deconstruct the chair.</span>")
new /obj/item/stack/rods(drop_location(), 8)
new /obj/item/stack/sheet/metal(drop_location(), 10)
var/turf/T = get_turf(src)
for(var/atom/movable/A in contents)
A.forceMove(T)
//if(isliving(A))
// var/mob/living/L = A
// L.update_mobility()
qdel(src)
return TRUE
/obj/vehicle/ridden/wheelchair/motorized/examine(mob/user)
. = ..()
if((obj_flags & EMAGGED) && panel_open)
. += "There is a bomb under the maintenance panel."
. += "There is a small screen on it, [(in_range(user, src) || isobserver(user)) ? "[power_cell ? "it reads:" : "but it is dark."]" : "but you can't see it from here."]"
if(!power_cell || (!in_range(user, src) && !isobserver(user)))
return
. += "Speed: [speed]"
. += "Energy efficiency: [power_efficiency]"
. += "Power: [power_cell.charge] out of [power_cell.maxcharge]"
/obj/vehicle/ridden/wheelchair/motorized/Bump(atom/movable/M)
. = ..()
// Here is the shitty emag functionality.
if(obj_flags & EMAGGED && (istype(M, /turf/closed) || isliving(M)))
explosion(src, -1, 1, 3, 2, 0)
visible_message("<span class='boldwarning'>[src] explodes!!</span>")
return
// If the speed is higher than delay_multiplier throw the person on the wheelchair away
if(M.density && speed > delay_multiplier && has_buckled_mobs())
var/mob/living/H = buckled_mobs[1]
var/atom/throw_target = get_edge_target_turf(H, pick(GLOB.cardinals))
unbuckle_mob(H)
H.throw_at(throw_target, 2, 3)
H.Knockdown(100)
H.adjustStaminaLoss(40)
if(isliving(M))
var/mob/living/D = M
throw_target = get_edge_target_turf(D, pick(GLOB.cardinals))
D.throw_at(throw_target, 2, 3)
D.Knockdown(80)
D.adjustStaminaLoss(35)
visible_message("<span class='danger'>[src] crashes into [M], sending [H] and [D] flying!</span>")
else
visible_message("<span class='danger'>[src] crashes into [M], sending [H] flying!</span>")
playsound(src, 'sound/effects/bang.ogg', 50, 1)
/obj/vehicle/ridden/wheelchair/motorized/emag_act(mob/user)
if((obj_flags & EMAGGED) || !panel_open)
return
to_chat(user, "<span class='warning'>A bomb appears in [src], what the fuck?</span>")
obj_flags |= EMAGGED
+12 -7
View File
@@ -1,4 +1,4 @@
/obj/vehicle/ridden/wheelchair //ported from Hippiestation (by Jujumatic) Then ported by Fermis from tg!
/obj/vehicle/ridden/wheelchair //ported from Hippiestation (by Jujumatic)
name = "wheelchair"
desc = "A chair with big wheels. It looks like you can move in this on your own."
icon = 'icons/obj/vehicles.dmi'
@@ -9,7 +9,8 @@
legs_required = 0 //You'll probably be using this if you don't have legs
canmove = TRUE
density = FALSE //Thought I couldn't fix this one easily, phew
arms_required = 1
// Run speed delay is multiplied with this for vehicle move delay.
var/delay_multiplier = 6.7
/obj/vehicle/ridden/wheelchair/Initialize()
. = ..()
@@ -42,16 +43,19 @@
canmove = FALSE
addtimer(VARSET_CALLBACK(src, canmove, TRUE), 20)
return FALSE
var/datum/component/riding/D = GetComponent(/datum/component/riding)
//1.5 (movespeed as of this change) multiplied by 6.7 gets ABOUT 10 (rounded), the old constant for the wheelchair that gets divided by how many arms they have
//if that made no sense this simply makes the wheelchair speed change along with movement speed delay
D.vehicle_move_delay = round((CONFIG_GET(number/movedelay/run_delay) * 4) / min(user.get_num_arms(), 2), world.tick_lag)
set_move_delay(user)
return ..()
/obj/vehicle/ridden/wheelchair/proc/set_move_delay(mob/living/user)
var/datum/component/riding/D = GetComponent(/datum/component/riding)
//1.5 (movespeed as of this change) multiplied by 6.7 gets ABOUT 10 (rounded), the old constant for the wheelchair that gets divided by how many arms they have
//if that made no sense this simply makes the wheelchair speed change along with movement speed delay
D.vehicle_move_delay = round(CONFIG_GET(number/movedelay/run_delay) * delay_multiplier) / min(user.get_num_arms(), 2)
/obj/vehicle/ridden/wheelchair/Moved()
. = ..()
cut_overlays()
playsound(src, 'sound/effects/roll.ogg', 75, 1)
playsound(src, 'sound/effects/roll.ogg', 75, TRUE)
if(has_buckled_mobs())
handle_rotation_overlayed()
@@ -69,6 +73,7 @@
handle_rotation(newdir)
/obj/vehicle/ridden/wheelchair/wrench_act(mob/living/user, obj/item/I) //Attackby should stop it attacking the wheelchair after moving away during decon
..()
to_chat(user, "<span class='notice'>You begin to detach the wheels...</span>")
if(I.use_tool(src, user, 40, volume=50))
to_chat(user, "<span class='notice'>You detach the wheels and deconstruct the chair.</span>")
+1
View File
@@ -14,6 +14,7 @@
/obj/item/seeds/chanter = 3,
/obj/item/seeds/chili = 3,
/obj/item/seeds/cocoapod = 3,
/obj/item/seeds/coconut = 3,
/obj/item/seeds/coffee = 3,
/obj/item/seeds/cotton = 3,
/obj/item/seeds/corn = 3,
+1
View File
@@ -131,6 +131,7 @@
/obj/item/clothing/mask/bandana/skull = 2)
premium = list(/obj/item/radio/headset/headset_rob = 2) //Cit change
contraband = list(/obj/item/clothing/suit/hooded/techpriest = 2)
contraband = list(/obj/item/organ/tongue/robot = 2)
refill_canister = /obj/item/vending_refill/wardrobe/robo_wardrobe
/obj/item/vending_refill/wardrobe/robo_wardrobe
+9
View File
@@ -146,6 +146,9 @@ LOG_MANIFEST
## Enable logging pictures
# LOG_PICTURES
## log cloning actions
LOG_CLONING
##Log camera pictures - Must have picture logging enabled
PICTURE_LOGGING_CAMERA
@@ -176,6 +179,12 @@ VOTE_DELAY 6000
## time period (deciseconds) which voting session will last (default 1 minute)
VOTE_PERIOD 600
## autovote initial delay (deciseconds) before first automatic transfer vote call (default 120 minutes)
VOTE_AUTOTRANSFER_INITIAL 72000
##autovote delay (deciseconds) before sequential automatic transfer votes are called (default 30 minutes)
VOTE_AUTOTRANSFER_INTERVAL 18000
## prevents dead players from voting or starting votes
# NO_DEAD_VOTE
Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 145 KiB

After

Width:  |  Height:  |  Size: 152 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 55 KiB

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 56 KiB

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Some files were not shown because too many files have changed in this diff Show More