diff --git a/_maps/RandomZLevels/centcomAway.dmm b/_maps/RandomZLevels/centcomAway.dmm index 2731714e96e..ae417e2bea1 100644 --- a/_maps/RandomZLevels/centcomAway.dmm +++ b/_maps/RandomZLevels/centcomAway.dmm @@ -169,7 +169,7 @@ "dm" = (/obj/machinery/door/window/northright{base_state = "right"; dir = 4; icon_state = "right"; name = "Security Desk"; req_access_txt = "103"},/turf/simulated/floor/plasteel/shuttle{icon_state = "shuttlefloor2"},/area/awaymission/centcomAway/hangar) "dn" = (/obj/structure/closet/crate,/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 9},/area/awaymission/centcomAway/hangar) "do" = (/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 1},/area/awaymission/centcomAway/hangar) -"dp" = (/obj/structure/largecrate,/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 5},/area/awaymission/centcomAway/hangar) +"dp" = (/obj/structure/closet/crate/large,/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 5},/area/awaymission/centcomAway/hangar) "dq" = (/obj/structure/dresser,/turf/simulated/floor/carpet,/area/awaymission/centcomAway/cafe) "dr" = (/obj/structure/table/reinforced,/obj/item/device/t_scanner,/turf/simulated/floor/plasteel{icon_state = "yellow"},/area/awaymission/centcomAway/general) "ds" = (/obj/structure/disposalpipe/trunk{dir = 1},/obj/machinery/disposal/bin,/turf/simulated/floor/plating,/area/awaymission/centcomAway/cafe) @@ -192,7 +192,7 @@ "dJ" = (/turf/simulated/floor/plasteel{icon_state = "blackcorner"; dir = 4},/area/awaymission/centcomAway/general) "dK" = (/turf/simulated/floor/plasteel{icon_state = "yellow"},/area/awaymission/centcomAway/general) "dL" = (/obj/machinery/door/airlock/hatch{name = "Rest Room"; req_access_txt = "0"},/turf/simulated/floor/plasteel/shuttle{icon_state = "shuttlefloor3"},/area/awaymission/centcomAway/hangar) -"dM" = (/obj/structure/largecrate,/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 10},/area/awaymission/centcomAway/hangar) +"dM" = (/obj/structure/closet/crate/large,/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 10},/area/awaymission/centcomAway/hangar) "dN" = (/obj/structure/closet/crate,/turf/simulated/floor/plating{dir = 2; icon_state = "warnplate"},/area/awaymission/centcomAway/hangar) "dO" = (/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 6},/area/awaymission/centcomAway/hangar) "dP" = (/turf/simulated/floor/plasteel{icon_state = "yellow"; dir = 10},/area/awaymission/centcomAway/general) @@ -486,7 +486,7 @@ "jr" = (/obj/structure/table,/obj/item/weapon/firstaid_arm_assembly,/turf/simulated/floor/plasteel{icon_state = "vault"},/area/awaymission/centcomAway/hangar) "js" = (/obj/structure/table,/obj/item/device/assembly/flash/handheld,/obj/item/device/assembly/flash/handheld,/turf/simulated/floor/plasteel{icon_state = "vault"},/area/awaymission/centcomAway/hangar) "jt" = (/obj/structure/table,/obj/item/stack/sheet/glass{amount = 50},/obj/item/stack/sheet/metal{amount = 50},/turf/simulated/floor/plasteel{icon_state = "vault"},/area/awaymission/centcomAway/hangar) -"ju" = (/obj/structure/table,/obj/item/device/mmi/radio_enabled,/turf/simulated/floor/plasteel{icon_state = "vault"},/area/awaymission/centcomAway/hangar) +"ju" = (/obj/structure/table,/obj/item/device/mmi,/turf/simulated/floor/plasteel{icon_state = "vault"},/area/awaymission/centcomAway/hangar) "jv" = (/obj/structure/table,/obj/item/weapon/storage/toolbox/mechanical,/turf/simulated/floor/plasteel{icon_state = "vault"},/area/awaymission/centcomAway/hangar) "jw" = (/obj/machinery/door/airlock/maintenance_hatch{req_access_txt = "101"},/turf/simulated/floor/plating,/area/awaymission/centcomAway/general) "jx" = (/obj/machinery/door/window,/obj/machinery/door/window/northright,/turf/simulated/floor/plasteel{icon_state = "floor"},/area/awaymission/centcomAway/general) diff --git a/_maps/RandomZLevels/spacebattle.dmm b/_maps/RandomZLevels/spacebattle.dmm index a26038404da..b282455054a 100644 --- a/_maps/RandomZLevels/spacebattle.dmm +++ b/_maps/RandomZLevels/spacebattle.dmm @@ -376,7 +376,7 @@ "hm" = (/turf/simulated/floor/plasteel/shuttle/red/syndicate,/area/awaymission/spacebattle/syndicate7) "hn" = (/obj/structure/shuttle/engine/heater{icon_state = "heater"; dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating/airless,/area/awaymission/spacebattle/syndicate7) "ho" = (/obj/structure/shuttle/engine/propulsion{icon_state = "propulsion_r"; dir = 8},/turf/space,/area/awaymission/spacebattle/syndicate7) -"hp" = (/obj/structure/largecrate,/turf/simulated/floor/plating,/area/awaymission/spacebattle/cruiser) +"hp" = (/obj/structure/closet/crate/large,/turf/simulated/floor/plating,/area/awaymission/spacebattle/cruiser) "hq" = (/obj/structure/closet/crate/secure/plasma,/turf/simulated/floor/plating,/area/awaymission/spacebattle/cruiser) "hr" = (/obj/structure/closet/crate/medical,/obj/item/weapon/storage/firstaid/fire,/turf/simulated/floor/plating,/area/awaymission/spacebattle/cruiser) "hs" = (/obj/structure/rack,/obj/item/clothing/suit/space/hardsuit,/obj/item/clothing/head/helmet/space/hardsuit,/turf/simulated/floor/plasteel,/area/awaymission/spacebattle/cruiser) @@ -385,7 +385,7 @@ "hv" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/engine,/area/awaymission/spacebattle/cruiser) "hw" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/awaymission/spacebattle/syndicate7) "hx" = (/obj/structure/shuttle/engine/propulsion{icon_state = "propulsion_l"; dir = 8},/turf/space,/area/awaymission/spacebattle/syndicate7) -"hy" = (/obj/structure/largecrate,/mob/living/simple_animal/pet/dog/corgi/puppy,/turf/simulated/floor/plating,/area/awaymission/spacebattle/cruiser) +"hy" = (/obj/structure/closet/crate/large,/mob/living/simple_animal/pet/dog/corgi/puppy,/turf/simulated/floor/plating,/area/awaymission/spacebattle/cruiser) "hz" = (/obj/structure/closet/crate,/obj/item/weapon/paint/anycolor,/turf/simulated/floor/plating,/area/awaymission/spacebattle/cruiser) "hA" = (/obj/structure/closet/crate,/obj/item/weapon/stock_parts/cell/high,/obj/item/weapon/stock_parts/cell/high,/turf/simulated/floor/plating,/area/awaymission/spacebattle/cruiser) "hB" = (/obj/structure/closet/crate/medical,/obj/item/weapon/storage/firstaid/regular,/turf/simulated/floor/plating,/area/awaymission/spacebattle/cruiser) diff --git a/_maps/RandomZLevels/wildwest.dmm b/_maps/RandomZLevels/wildwest.dmm index 91d013263d7..36d5dc8dad5 100644 --- a/_maps/RandomZLevels/wildwest.dmm +++ b/_maps/RandomZLevels/wildwest.dmm @@ -54,7 +54,7 @@ "be" = (/obj/item/ammo_box/c10mm,/turf/simulated/floor/plating/ironsand{icon_state = "ironsand1"},/area/awaymission/wwmines) "bf" = (/mob/living/simple_animal/hostile/syndicate/ranged,/turf/simulated/floor/plating/ironsand{icon_state = "ironsand1"},/area/awaymission/wwmines) "bg" = (/turf/simulated/wall/mineral/sandstone,/area/space) -"bh" = (/obj/structure/largecrate,/turf/simulated/floor/plating,/area/awaymission/wwrefine) +"bh" = (/obj/structure/closet/crate/large,/turf/simulated/floor/plating,/area/awaymission/wwrefine) "bi" = (/obj/effect/landmark/corpse/miner/rig,/obj/effect/mine/sound/bwoink,/turf/simulated/floor/plating/ironsand{icon_state = "ironsand1"},/area/awaymission/wwmines) "bj" = (/turf/simulated/floor/wood,/area/awaymission/wwmines) "bk" = (/obj/effect/decal/cleanable/blood,/turf/simulated/floor/wood,/area/awaymission/wwmines) @@ -181,7 +181,7 @@ "dB" = (/obj/structure/toilet,/mob/living/simple_animal/hostile/creature,/turf/simulated/floor/plasteel{icon_state = "white"},/area/awaymission/wwgov) "dC" = (/turf/simulated/floor/plating/ironsand{icon_state = "ironsand9"},/area/awaymission/wwgov) "dD" = (/obj/structure/mineral_door/wood{icon_state = "wood"},/turf/simulated/floor/plating/ironsand{icon_state = "ironsand1"},/area/awaymission/wwgov) -"dE" = (/obj/structure/largecrate,/turf/simulated/floor/wood,/area/awaymission/wwmines) +"dE" = (/obj/structure/closet/crate/large,/turf/simulated/floor/wood,/area/awaymission/wwmines) "dF" = (/turf/simulated/floor/plating/ironsand{icon_state = "ironsand7"},/area/awaymission/wwgov) "dG" = (/obj/machinery/washing_machine,/turf/simulated/floor/plasteel{icon_state = "cafeteria"; dir = 5},/area/awaymission/wwmines) "dH" = (/obj/structure/bed,/obj/item/weapon/bedsheet/blue,/turf/simulated/floor/wood,/area/awaymission/wwmines) diff --git a/_maps/map_files/BirdStation/BirdStation.dmm b/_maps/map_files/BirdStation/BirdStation.dmm index 654f570eaf9..0f8a0549a9f 100644 --- a/_maps/map_files/BirdStation/BirdStation.dmm +++ b/_maps/map_files/BirdStation/BirdStation.dmm @@ -2374,7 +2374,7 @@ "aTJ" = (/obj/structure/bed,/obj/item/clothing/suit/apron/chef,/obj/item/clothing/suit/apron/chef,/turf/simulated/floor/plasteel/white,/area/maintenance/asmaint2) "aTK" = (/turf/simulated/wall,/area/hallway/primary/aft{name = "\improper South Hallway"}) "aTL" = (/obj/machinery/hologram/holopad,/turf/simulated/floor/plasteel,/area/crew_quarters/sleep) -"aTM" = (/obj/structure/closet/crate/hydroponics/prespawned,/obj/item/weapon/shovel/spade,/obj/item/weapon/wrench,/obj/item/weapon/reagent_containers/glass/bucket,/obj/item/weapon/wirecutters,/obj/item/weapon/reagent_containers/glass/bucket,/obj/item/weapon/reagent_containers/glass/bucket,/obj/item/weapon/twohanded/required/chainsaw,/turf/simulated/floor/plasteel/whitegreen/side{icon_state = "whitegreen"; dir = 9},/area/hydroponics) +"aTM" = (/obj/structure/closet/crate/hydroponics,/obj/item/weapon/shovel/spade,/obj/item/weapon/wrench,/obj/item/weapon/reagent_containers/glass/bucket,/obj/item/weapon/wirecutters,/obj/item/weapon/reagent_containers/glass/bucket,/obj/item/weapon/reagent_containers/glass/bucket,/obj/item/weapon/twohanded/required/chainsaw,/turf/simulated/floor/plasteel/whitegreen/side{icon_state = "whitegreen"; dir = 9},/area/hydroponics) "aTN" = (/obj/machinery/atmospherics/pipe/simple/cyan/hidden{icon_state = "intact"; dir = 4},/turf/simulated/floor/plasteel,/area/toxins/misc_lab) "aTO" = (/obj/machinery/atmospherics/pipe/manifold/cyan/hidden,/turf/simulated/floor/plasteel,/area/toxins/misc_lab) "aTP" = (/obj/effect/landmark/start{name = "Scientist"},/obj/machinery/atmospherics/pipe/simple/cyan/hidden{icon_state = "intact"; dir = 4},/turf/simulated/floor/plasteel,/area/toxins/misc_lab) @@ -2653,7 +2653,7 @@ "aZc" = (/obj/machinery/biogenerator,/turf/simulated/floor/plasteel/white,/area/maintenance/fore{name = "Security Maintenance"}) "aZd" = (/obj/machinery/seed_extractor,/turf/simulated/floor/plasteel/white,/area/maintenance/fore{name = "Security Maintenance"}) "aZe" = (/obj/structure/sink/kitchen{desc = "A sink used for washing one's hands and face. It looks rusty and home-made"; name = "old sink"; pixel_y = 28},/obj/item/weapon/reagent_containers/spray/plantbgone,/turf/simulated/floor/plasteel/white,/area/maintenance/fore{name = "Security Maintenance"}) -"aZf" = (/obj/structure/closet/crate/secure/hydrosec{req_access_txt = "35"},/obj/item/seeds/kudzuseed{potency = 0; production = 8},/obj/item/seeds/chilighost,/obj/item/seeds/deathberryseed,/obj/item/device/gps,/turf/simulated/floor/plasteel/white,/area/maintenance/fore{name = "Security Maintenance"}) +"aZf" = (/obj/structure/closet/crate/secure/hydroponics{req_access_txt = "35"},/obj/item/seeds/kudzuseed{potency = 0; production = 8},/obj/item/seeds/chilighost,/obj/item/seeds/deathberryseed,/obj/item/device/gps,/turf/simulated/floor/plasteel/white,/area/maintenance/fore{name = "Security Maintenance"}) "aZg" = (/obj/structure/cable/cyan{icon_state = "1-2"},/obj/machinery/camera/autoname{icon_state = "camera"; dir = 5},/turf/simulated/floor/wood,/area/security/brig) "aZh" = (/obj/structure/closet/secure_closet/detective,/obj/item/device/camera/detective,/turf/simulated/floor/wood,/area/security/brig) "aZi" = (/obj/structure/table/wood,/turf/simulated/floor/wood,/area/security/brig) diff --git a/_maps/map_files/MiniStation/cargopacks.dm b/_maps/map_files/MiniStation/cargopacks.dm new file mode 100644 index 00000000000..a6a1db75df3 --- /dev/null +++ b/_maps/map_files/MiniStation/cargopacks.dm @@ -0,0 +1,37 @@ +/datum/supply_pack/engineering/oxygen + name = "Oxygen Canister" + cost = 15 + contains = list(/obj/machinery/portable_atmospherics/canister/oxygen) + crate_name = "oxygen canister crate" + crate_type = /obj/structure/closet/crate/large + +/datum/supply_pack/engineering/toxins + name = "Plasma Canister" + cost = 30 + contains = list(/obj/machinery/portable_atmospherics/canister/toxins) + crate_name = "plasma canister crate" + crate_type = /obj/structure/closet/crate/large + +/datum/supply_pack/engineering/nitrogen + name = "Nitrogen Canister" + cost = 20 + contains = list(/obj/machinery/portable_atmospherics/canister/nitrogen) + crate_name = "nitrogen canister crate" + crate_type = /obj/structure/closet/crate/large + +/datum/supply_pack/engineering/carbon_dio + name = "Carbon Dioxide Canister" + cost = 35 + contains = list(/obj/machinery/portable_atmospherics/canister/carbon_dioxide) + crate_name = "carbon dioxide canister crate" + crate_type = /obj/structure/closet/crate/large + +/obj/machinery/hydroponics/constructable/unattached + anchored = 0 + +/datum/supply_pack/organic/hydroponics/hydro_tray + name = "Hydroponics Tray Kit" + contains = list(/obj/machinery/hydroponics/constructable/unattached) + cost = 10 + crate_name = "hydroponics kit" + crate_type = /obj/structure/closet/crate/large \ No newline at end of file diff --git a/_maps/map_files/MiniStation/supplypacks.dm b/_maps/map_files/MiniStation/supplypacks.dm deleted file mode 100644 index 330322a0d6f..00000000000 --- a/_maps/map_files/MiniStation/supplypacks.dm +++ /dev/null @@ -1,38 +0,0 @@ -/datum/supply_packs/engineering/oxygen - name = "Oxygen Canister" - contains = list(/obj/machinery/portable_atmospherics/canister/oxygen) - cost = 15 - containertype = /obj/structure/largecrate - containername = "oxygen canister crate" - -/datum/supply_packs/engineering/toxins - name = "Toxins Canister" - contains = list(/obj/machinery/portable_atmospherics/canister/toxins) - cost = 30 - containertype = /obj/structure/largecrate - containername = "toxins canister crate" - -/datum/supply_packs/engineering/nitrogen - name = "Nitrogen Canister" - contains = list(/obj/machinery/portable_atmospherics/canister/nitrogen) - cost = 20 - containertype = /obj/structure/largecrate - containername = "nitrogen canister crate" - -/datum/supply_packs/engineering/carbon_dio - name = "Carbon Dioxide Canister" - contains = list(/obj/machinery/portable_atmospherics/canister/carbon_dioxide) - cost = 35 - containertype = /obj/structure/largecrate - containername = "carbon dioxide canister crate" - - -/obj/machinery/hydroponics/constructable/unattached - anchored = 0 - -/datum/supply_packs/organic/hydroponics/hydro_tray - name = "Hydroponics Tray Kit" - contains = list(/obj/machinery/hydroponics/constructable/unattached) - cost = 10 - containertype = /obj/structure/largecrate - containername = "hydroponics kit" \ No newline at end of file diff --git a/_maps/map_files/generic/z6.dmm b/_maps/map_files/generic/z6.dmm index c6861e94afd..7563f9b83c9 100644 --- a/_maps/map_files/generic/z6.dmm +++ b/_maps/map_files/generic/z6.dmm @@ -55,7 +55,7 @@ "bc" = (/turf/simulated/floor/plating,/area/awaymission/BMPship/Aft) "bd" = (/obj/item/weapon/storage/box,/turf/simulated/floor/plating,/area/awaymission/BMPship/Aft) "be" = (/obj/item/weapon/hand_labeler,/turf/simulated/floor/plating,/area/awaymission/BMPship/Aft) -"bf" = (/obj/structure/largecrate,/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 4},/area/awaymission/BMPship/Aft) +"bf" = (/obj/structure/closet/crate/large,/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 4},/area/awaymission/BMPship/Aft) "bg" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/grille,/turf/simulated/floor/plating/airless,/area/awaymission/BMPship/Fore) "bh" = (/obj/structure/table/wood,/obj/item/stack/spacecash/c500,/obj/item/stack/spacecash/c100,/obj/item/weapon/reagent_containers/food/drinks/beer,/turf/simulated/floor/wood,/area/awaymission/BMPship/Fore) "bi" = (/obj/structure/bed,/obj/item/weapon/bedsheet/yellow,/turf/simulated/floor/wood,/area/awaymission/BMPship/Fore) @@ -112,7 +112,7 @@ "ch" = (/turf/simulated/wall/shuttle{icon_state = "swall13"},/area/awaymission/BMPship/Midship) "ci" = (/turf/simulated/wall/shuttle{icon_state = "swall15"},/area/awaymission/BMPship/Aft) "cj" = (/obj/machinery/door/poddoor/shutters{id = "packerMed"},/turf/simulated/floor/plating/airless,/area/awaymission/BMPship/Aft) -"ck" = (/obj/structure/largecrate,/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 10},/area/awaymission/BMPship/Aft) +"ck" = (/obj/structure/closet/crate/large,/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 10},/area/awaymission/BMPship/Aft) "cl" = (/turf/simulated/floor/plating{dir = 2; icon_state = "warnplate"},/area/awaymission/BMPship/Aft) "cm" = (/obj/machinery/light/small,/turf/simulated/floor/plating{dir = 2; icon_state = "warnplate"},/area/awaymission/BMPship/Aft) "cn" = (/obj/structure/kitchenspike,/turf/simulated/floor/plating{dir = 2; icon_state = "warnplate"},/area/awaymission/BMPship/Aft) @@ -433,8 +433,8 @@ "iq" = (/turf/simulated/floor/plating,/turf/simulated/wall/shuttle{icon_state = "swall_f6"; dir = 2},/area/awaymission/BMPship/Fore) "ir" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/structure/grille,/turf/simulated/floor/engine,/area/awaymission/BMPship/Fore) "is" = (/turf/simulated/mineral/diamond,/area/awaymission) -"it" = (/turf/simulated/mineral/clown,/area/awaymission) -"iu" = (/turf/simulated/mineral,/area/mine/unexplored) +"it" = (/turf/simulated/wall/shuttle{icon_state = "wall3"},/area/awaymission) +"iu" = (/turf/simulated/mineral,/area/awaymission) "iv" = (/turf/simulated/wall/r_wall,/area/awaymission/listeningpost) "iw" = (/turf/simulated/floor/plating,/area/awaymission/listeningpost) "ix" = (/obj/machinery/power/smes/magical{desc = "A high-capacity superconducting magnetic energy storage (SMES) unit."; name = "power storage unit"},/turf/simulated/floor/plating,/area/awaymission/listeningpost) @@ -451,27 +451,26 @@ "iI" = (/obj/item/device/radio/intercom{desc = "Talk through this. Evilly"; freerange = 1; frequency = 1213; name = "Syndicate Intercom"; pixel_x = 32; subspace_transmission = 1; syndie = 1},/turf/simulated/floor/plasteel,/area/awaymission/listeningpost) "iJ" = (/obj/structure/rack,/obj/item/clothing/suit/space/syndicate,/obj/item/clothing/mask/gas,/obj/item/clothing/head/helmet/space/syndicate,/turf/simulated/floor/plasteel,/area/awaymission/listeningpost) "iK" = (/obj/machinery/door/airlock,/obj/structure/safe/floor,/obj/item/weapon/paper{info = "I wonder how much longer they will accept my empty reports. They will cancel the case soon without results. When the pickup comes, I will tell them I have lost faith in our cause, and beg them to consider a diplomatic solution. How many nuclear teams have been dispatched with those nukes? I must try and prevent more from ever being sent. If they will not listen to reason, I will detonate the warehouse myself. Maybe some day in the immediate future, space will be peaceful, though I don't intend to live to see it. And that is why I write this down- it is my sacrifice that stabilised your worlds, traveller. Spare a thought for me, and please attempt to prevent nuclear proliferation, should it ever rear it's ugly head again. -Donk Co. Operative #451"; name = "odd report"},/obj/item/weapon/gun/projectile/automatic/pistol,/turf/simulated/floor/plasteel,/area/awaymission/listeningpost) -"iL" = (/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/turf/simulated/mineral,/area/mine/unexplored) -"iM" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/mineral,/area/mine/unexplored) +"iL" = (/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/turf/simulated/mineral,/area/awaymission) +"iM" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/mineral,/area/awaymission) "iN" = (/obj/structure/disposaloutlet{dir = 4},/obj/structure/disposalpipe/trunk{dir = 8},/turf/simulated/floor/plating/airless,/area/space) "iO" = (/obj/structure/bed,/obj/item/weapon/bedsheet/brown,/turf/simulated/floor/plasteel,/area/awaymission/listeningpost) "iP" = (/obj/structure/table,/obj/item/device/flashlight/lamp,/turf/simulated/floor/plasteel,/area/awaymission/listeningpost) "iQ" = (/obj/machinery/vending/snack,/turf/simulated/floor/plasteel,/area/awaymission/listeningpost) -"iR" = (/obj/structure/disposalpipe/segment,/turf/simulated/mineral,/area/mine/unexplored) +"iR" = (/obj/structure/disposalpipe/segment,/turf/simulated/mineral,/area/awaymission) "iS" = (/obj/machinery/vending/cola,/turf/simulated/floor/plasteel,/area/awaymission/listeningpost) "iT" = (/obj/structure/closet,/obj/item/clothing/gloves/boxing,/turf/simulated/floor/plasteel,/area/awaymission/listeningpost) "iU" = (/obj/structure/filingcabinet,/obj/item/weapon/paper{info = "A good start to the operation: intercepted Nanotrasen military communications. A convoy is scheduled to transfer nuclear warheads to a new military base. This is as good a chance as any to get our hands on some heavy weaponry, I suggest we take it."; name = "april report"},/obj/item/weapon/paper{info = "Nothing of real interest to report this month. I have intercepted faint transmissions from what appears to be some sort of pirate radio station. They do not appear to be relevant to my assignment."; name = "may report"},/obj/item/weapon/paper{info = "Nanotrasen communications have been noticably less frequent recently. The pirate radio station I found last month has been transmitting pro-Nanotrasen propaganda. I will continue to monitor it."; name = "june report"},/obj/item/weapon/paper{info = "Nothing of interest to report."; name = "july report"},/obj/item/weapon/paper{info = "Nothing of interest to report."; name = "august report"},/obj/item/weapon/paper{info = "Nothing of interest to report."; name = "september report"},/obj/item/weapon/paper{info = "Nothing of interest to report."; name = "october report"},/obj/item/weapon/paper{info = "1 x Stechtkin pistol - $600
1 x silencer - $200
shipping charge - $4360
total - $5160"; name = "receipt"},/turf/simulated/floor/plasteel,/area/awaymission/listeningpost) "iV" = (/obj/structure/table,/obj/item/weapon/paper{info = "Mission Details: You have been assigned to a newly constructed listening post constructed within an asteroid in Nanotrasen space to monitor their plasma mining operations. Accurate intel is crucial to the success of our operatives onboard, do not fail us."; name = "mission briefing"},/turf/simulated/floor/plasteel,/area/awaymission/listeningpost) "iW" = (/obj/machinery/disposal/bin,/obj/structure/disposalpipe/trunk{dir = 4},/turf/simulated/floor/plasteel,/area/awaymission/listeningpost) "iX" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/wall/r_wall,/area/awaymission/listeningpost) -"iY" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/turf/simulated/mineral,/area/mine/unexplored) +"iY" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/turf/simulated/mineral,/area/awaymission) "iZ" = (/obj/machinery/door/airlock{name = "Toilet"},/turf/simulated/floor/plasteel,/area/awaymission/listeningpost) "ja" = (/turf/simulated/floor/plasteel{icon_state = "freezerfloor"},/area/awaymission/listeningpost) "jb" = (/obj/machinery/shower{icon_state = "shower"; dir = 8},/turf/simulated/floor/plasteel{icon_state = "freezerfloor"},/area/awaymission/listeningpost) "jc" = (/obj/structure/toilet{icon_state = "toilet00"; dir = 8},/turf/simulated/floor/plasteel{icon_state = "freezerfloor"},/area/awaymission/listeningpost) -"jd" = (/turf/simulated/mineral/clown,/area/mine/unexplored) -"je" = (/turf/simulated/wall/shuttle{icon_state = "wall3"},/area/mine/explored) -"jf" = (/turf/simulated/floor/plasteel/airless{icon_state = "gcircuit"},/area/mine/explored) +"jd" = (/turf/simulated/mineral/clown,/area/awaymission) +"je" = (/turf/simulated/floor/plasteel/airless{icon_state = "gcircuit"},/area/awaymission) (1,1,1) = {" aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -566,8 +565,8 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagQgQgQgQgQacacgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagQgQgQgQgQacacacgQgQisgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagQgQgQgQgQacacacgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagQgQgQgQgQacacacgQgQgQgQgQgQitgQgQgQgQgQgQgQgQgQgQgQacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagQgQgQgQgQacacacgQgQgQitgQgQitgQgQgQgQgQgQgQgQgQacacacacgQgQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagQgQgQgQgQacacacgQgQgQgQgQgQjdgQgQgQgQgQgQgQgQgQgQgQacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagQgQgQgQgQacacacgQgQgQjdgQgQjdgQgQgQgQgQgQgQgQgQacacacacgQgQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagQgQgQgQacacacacgQgQgQgQgQgQgQgQgQgQgQgQgQgQgQacacgQgQgQgQgQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagQgQacacacacacacgQgQgQgQgQgQgQgQgQgQgQgQacacacacgQgQgQgQgQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacacgQgQgQgQgQgQgQgQacacacacaaaaaagQgQgQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -621,10 +620,10 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiviwixiviuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiviviviyizivivivivaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiviviAiBiCiCiDiwiwiDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiEiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiviFiGiHiCiCiDiwiwiDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuaaiEiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiviviIiBiCiCivivivivaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiEiEiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiviCiCiCiJiviuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiEiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiviviviviKiziziziviuiLiMiMiNaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaciuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiviFiGiHiCiCiDiwiwiDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuaaaciuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiviviIiBiCiCivivivivaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuacaciuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiviCiCiCiJiviuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuaciuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiviviviviKiziziziviuiLiMiMiNaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiviOiPiziCiCiCiQiviuiRiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiviCiCiyiCiCiCiSiviuiRiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiviTiUiziViCiWiXiXiMiYiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -639,12 +638,12 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiEiEiEiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiujdjdiuiuiuiuiuiuiuiEiEaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiujdiuiujdiuiuiuiEiEiEaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiujdiuiuiuiuiuiuiuiuiuiuiuiuiEaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiujdjdiuiuiuiuiuiuiuiuiuiuiuiEaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiujdjdiuiuiuiuiuiuiuiuiuiuiuiEaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuacacaciuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiujdjdiuiuiuiuiuiuiuacacaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiujdiuiujdiuiuiuacacacaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiujdiuiuiuiuiuiuiuiuiuiuiuiuacaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiujdjdiuiuiuiuiuiuiuiuiuiuiuacaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiujdjdiuiuiuiuiuiuiuiuiuiuiuacaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiujdiuiuiuiuiuiuaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -653,24 +652,24 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiujdiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiujdjdiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiEiEiEiEiEiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiEaaaaaaaaiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiEiEiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuacacacacaciuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuacaaaaaaaaiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuacaciuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiujejejejejejejeiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiEjfjfjfjfjfjeiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiujfjfjfjfjfjeiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiujfjfjfjfjeiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiEiuiuiuiuiuiuiuiuiuiuiuiuiuiujfjfjfjfjfjeiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiEiEiuiuiuiuiuiuiuiuiuiuiuiuiuiEjfjfjfjfjeiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaiEiuiuiuiuiuiuiuiuiuiuiuiuiEiEjejejejejeiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuitititititititiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuacjejejejejeitiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiujejejejejeitiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiujejejejeitiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiEiuiuiuiuiuiuiuiuiuiuiuiuiuiujejejejejeitiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiEiEiuiuiuiuiuiuiuiuiuiuiuiuiuacjejejejeitiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaiEiuiuiuiuiuiuiuiuiuiuiuiuacacitititititiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiEiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiEiEiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuaaiEiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuaaaaiEiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuaciuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuacaciuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuaaaciuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuaaaaaciuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuiuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa diff --git a/_maps/ministation.dm b/_maps/ministation.dm index eb39ecc4ed0..70a1a381242 100644 --- a/_maps/ministation.dm +++ b/_maps/ministation.dm @@ -67,7 +67,7 @@ Changes to the uplinks were made to discourage murderboning, the rest is the sam #if !defined(MAP_OVERRIDE_FILES) #define MAP_OVERRIDE_FILES #include "map_files\MiniStation\misc.dm" - #include "map_files\MiniStation\supplypacks.dm" + #include "map_files\MiniStation\cargopacks.dm" #include "map_files\MiniStation\telecomms.dm" #include "map_files\MiniStation\uplink_item.dm" #include "map_files\MiniStation\job\jobs.dm" diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm index 29d58d3d448..9e94460dcbd 100644 --- a/code/__DEFINES/misc.dm +++ b/code/__DEFINES/misc.dm @@ -120,9 +120,11 @@ //some arbitrary defines to be used by self-pruning global lists. (see master_controller) #define PROCESS_KILL 26 //Used to trigger removal from a processing list -#define MANIFEST_ERROR_NAME 1 -#define MANIFEST_ERROR_COUNT 2 -#define MANIFEST_ERROR_ITEM 4 +// Cargo-related stuff. +#define MANIFEST_ERROR_CHANCE 5 +#define MANIFEST_ERROR_NAME 1 +#define MANIFEST_ERROR_CONTENTS 2 +#define MANIFEST_ERROR_ITEM 4 #define TRANSITIONEDGE 7 //Distance from edge to move to another z-level diff --git a/code/__HELPERS/text.dm b/code/__HELPERS/text.dm index ddaf73e00ea..ac392a72090 100644 --- a/code/__HELPERS/text.dm +++ b/code/__HELPERS/text.dm @@ -420,3 +420,8 @@ var/list/binary = list("0","1") t = replacetext(t, "\[/list\]", "") return t + +/proc/char_split(t) + . = list() + for(var/x in 1 to length(t)) + . += copytext(t,x,x+1) diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index 5dfc704757e..f3c3e4ae279 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -1213,3 +1213,37 @@ proc/shift_proximity(atom/checker, atom/A, range, atom/B, newrange) var/turf/F = E F.proximity_checkers |= checker return 1 + +/proc/get_closest_atom(type, list, source) + var/closest_atom + var/closest_distance + for(var/A in list) + if(!istype(A, type)) + continue + var/distance = get_dist(source, A) + if(!closest_distance) + closest_distance = distance + closest_atom = A + else + if(closest_distance > distance) + closest_distance = distance + closest_atom = A + return closest_atom + +proc/pick_closest_path(value) + var/list/matches = get_fancy_list_of_types() + if (!isnull(value) && value!="") + matches = filter_fancy_list(matches, value) + + if(matches.len==0) + return + + var/chosen + if(matches.len==1) + chosen = matches[1] + else + chosen = input("Select an atom type", "Spawn Atom", matches[1]) as null|anything in matches + if(!chosen) + return + chosen = matches[chosen] + return chosen \ No newline at end of file diff --git a/code/_onclick/ai.dm b/code/_onclick/ai.dm index 719f7718977..e354fbbe2d4 100644 --- a/code/_onclick/ai.dm +++ b/code/_onclick/ai.dm @@ -10,9 +10,9 @@ Note that AI have no need for the adjacency proc, and so this proc is a lot cleaner. */ /mob/living/silicon/ai/DblClickOn(var/atom/A, params) - if(client.buildmode) // comes after object.Click to allow buildmode gui objects to be clicked - build_click(src, client.buildmode, params, A) - return + if(client.click_intercept) + if(call(client.click_intercept, "ClickOn")(src, params, A)) + return if(control_disabled || stat) return @@ -27,9 +27,9 @@ return next_click = world.time + 1 - if(client.buildmode) // comes after object.Click to allow buildmode gui objects to be clicked - build_click(src, client.buildmode, params, A) - return + if(client.click_intercept) + if(call(client.click_intercept, "ClickOn")(src, params, A)) + return if(control_disabled || stat) return diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm index e8297662c85..d500428a29f 100644 --- a/code/_onclick/click.dm +++ b/code/_onclick/click.dm @@ -52,9 +52,10 @@ if(world.time <= next_click) return next_click = world.time + 1 - if(client.buildmode) - build_click(src, client.buildmode, params, A) - return + + if(client.click_intercept) + if(call(client.click_intercept, "ClickOn")(src, params, A)) + return var/list/modifiers = params2list(params) if(modifiers["shift"] && modifiers["ctrl"]) diff --git a/code/_onclick/cyborg.dm b/code/_onclick/cyborg.dm index 4cb6a641ba8..3d32ee284cb 100644 --- a/code/_onclick/cyborg.dm +++ b/code/_onclick/cyborg.dm @@ -11,9 +11,9 @@ return next_click = world.time + 1 - if(client.buildmode) // comes after object.Click to allow buildmode gui objects to be clicked - build_click(src, client.buildmode, params, A) - return + if(client.click_intercept) + if(call(client.click_intercept,"ClickOn")(src,params,A)) + return if(stat || lockcharge || weakened || stunned || paralysis) return diff --git a/code/_onclick/hud/action.dm b/code/_onclick/hud/action.dm index 3bf0600e96c..84a49083a9d 100644 --- a/code/_onclick/hud/action.dm +++ b/code/_onclick/hud/action.dm @@ -30,9 +30,8 @@ return Remove(owner) owner = T - owner.actions.Add(src) - owner.update_action_buttons() - return + T.actions += src + T.update_action_buttons() /datum/action/proc/Remove(mob/living/T) if(button) @@ -40,10 +39,9 @@ T.client.screen -= button qdel(button) button = null - T.actions.Remove(src) + T.actions -= src T.update_action_buttons() owner = null - return /datum/action/proc/Trigger() if(!Checks()) @@ -86,7 +84,7 @@ current_button.overlays.Cut() if(button_icon && button_icon_state) var/image/img - img = image(button_icon,current_button,button_icon_state) + img = image(button_icon, current_button, button_icon_state) img.pixel_x = 0 img.pixel_y = 0 current_button.overlays += img @@ -151,7 +149,7 @@ /obj/screen/movable/action_button/hide_toggle/UpdateIcon() overlays.Cut() - var/image/img = image(icon,src,hidden?"show":"hide") + var/image/img = image(icon, src, hidden ? "show" : "hide") overlays += img return @@ -171,11 +169,11 @@ #define AB_MAX_COLUMNS 10 /datum/hud/proc/ButtonNumberToScreenCoords(number) // TODO : Make this zero-indexed for readabilty - var/row = round((number-1)/AB_MAX_COLUMNS) + var/row = round((number - 1)/AB_MAX_COLUMNS) var/col = ((number - 1)%(AB_MAX_COLUMNS)) + 1 var/coord_col = "+[col-1]" - var/coord_col_offset = 4+2*col + var/coord_col_offset = 4 + 2 * col var/coord_row = "[row ? -row : "+0"]" @@ -289,7 +287,7 @@ /datum/action/innate/proc/Deactivate() return -//Preset for action that call specific procs (consider innate) +//Preset for action that call specific procs (consider innate). /datum/action/generic check_flags = 0 var/procname @@ -298,7 +296,7 @@ if(!..()) return 0 if(target && procname) - call(target,procname)(usr) + call(target, procname)(usr) return 1 @@ -312,12 +310,12 @@ /datum/action/innate/scan_mode/Activate() active = 1 owner.research_scanner = 1 - owner << " Research analyzer is now active." + owner << "Research analyzer is now active." /datum/action/innate/scan_mode/Deactivate() active = 0 owner.research_scanner = 0 - owner << " Research analyzer deactivated." + owner << "Research analyzer deactivated." /datum/action/innate/scan_mode/Grant(mob/living/T) ..(T) diff --git a/code/_onclick/observer.dm b/code/_onclick/observer.dm index 411f562888b..ba3c1c05783 100644 --- a/code/_onclick/observer.dm +++ b/code/_onclick/observer.dm @@ -1,7 +1,8 @@ /mob/dead/observer/DblClickOn(var/atom/A, var/params) - if(client.buildmode) - build_click(src, client.buildmode, params, A) - return + if(client.click_intercept) + if(call(client.click_intercept,"ClickOn")(src,params,A)) + return + if(can_reenter_corpse && mind && mind.current) if(A == mind.current || (mind.current in A)) // double click your corpse or whatever holds it reenter_corpse() // (cloning scanner, body bag, closet, mech, etc) @@ -16,9 +17,10 @@ loc = get_turf(A) /mob/dead/observer/ClickOn(var/atom/A, var/params) - if(client.buildmode) - build_click(src, client.buildmode, params, A) - return + + if(client.click_intercept) + if(call(client.click_intercept,"ClickOn")(src,params,A)) + return var/list/modifiers = params2list(params) if(modifiers["middle"]) diff --git a/code/controllers/master.dm b/code/controllers/master.dm index 6800c95e2b4..75ded6c78cd 100644 --- a/code/controllers/master.dm +++ b/code/controllers/master.dm @@ -21,8 +21,10 @@ var/global/datum/controller/master/Master = new() var/iteration = 0 // The cost (in deciseconds) of the MC loop. var/cost = 0 +#if DM_VERSION < 510 // The old fps when we slow it down to prevent lag. var/old_fps +#endif // A list of subsystems to process(). var/list/subsystems = list() // The cost of running the subsystems (in deciseconds). @@ -39,7 +41,6 @@ var/global/datum/controller/master/Master = new() else init_subtypes(/datum/subsystem, subsystems) Master = src - processing_interval = calculate_gcd() /datum/controller/master/Destroy() ..() @@ -109,7 +110,9 @@ var/global/datum/controller/master/Master = new() SS.next_fire = world.time + rand(0, SS.wait) // Stagger subsystems. // Used to smooth out costs to try and avoid oscillation. +#define MC_AVERAGE_FAST(average, current) (0.7 * (average) + 0.3 * (current)) #define MC_AVERAGE(average, current) (0.8 * (average) + 0.2 * (current)) +#define MC_AVERAGE_SLOW(average, current) (0.9 * (average) + 0.1 * (current)) /datum/controller/master/process() if(!Failsafe) new/datum/controller/failsafe() // (re)Start the failsafe. @@ -129,29 +132,44 @@ var/global/datum/controller/master/Master = new() var/ran_subsystems = 0 for(var/datum/subsystem/SS in subsystems) +#if DM_VERSION >= 510 + if (world.tick_usage > 80) +#else if(world.cpu >= 100) - //if world.cpu gets above 120, - //byond will pause most client updates for (about) 1.6 seconds. - //(1.6 seconds worth of ticks) - //We just stop running subsystems to avoid that. +#endif break + if(SS.can_fire > 0) if(SS.next_fire <= world.time && SS.last_fire + (SS.wait * 0.75) <= world.time) // Check if it's time. +#if DM_VERSION >= 510 + if (world.tick_usage + SS.tick_usage > 80 && SS.last_fire + (SS.wait*1.25) > world.time) + continue +#endif ran_subsystems = 1 timer = world.timeofday last_type_processed = SS.type SS.last_fire = world.time +#if DM_VERSION >= 510 + var/tick_usage = world.tick_usage +#endif SS.fire() // Fire the subsystem and record the cost. - SS.cost = MC_AVERAGE(SS.cost, world.timeofday - timer) +#if DM_VERSION >= 510 + var/newusage = max(world.tick_usage - tick_usage, 0) + if (newusage < SS.tick_usage) + SS.tick_usage = MC_AVERAGE_SLOW(SS.tick_usage,world.tick_usage - tick_usage) + else + SS.tick_usage = MC_AVERAGE_FAST(SS.tick_usage,world.tick_usage - tick_usage) +#endif + SS.cost = max(MC_AVERAGE(SS.cost, world.timeofday - timer), 0) if(SS.dynamic_wait) // Adjust wait depending on lag. var/oldwait = SS.wait var/global_delta = (subsystem_cost - (SS.cost / (SS.wait / 10))) - 1 var/newwait = (SS.cost - SS.dwait_buffer + global_delta) * SS.dwait_delta newwait = newwait * (world.cpu / 100 + 1) - newwait = MC_AVERAGE(oldwait, newwait) + //smooth out wait changes, but only if going down + if(newwait < oldwait) + newwait = MC_AVERAGE(oldwait, newwait) SS.wait = Clamp(newwait, SS.dwait_lower, SS.dwait_upper) - if(oldwait != SS.wait) - processing_interval = calculate_gcd() SS.next_fire = world.time + SS.wait else SS.next_fire += SS.wait @@ -161,7 +179,7 @@ var/global/datum/controller/master/Master = new() break sleep(0) - cost = MC_AVERAGE(cost, world.timeofday - start_time) + cost = max(MC_AVERAGE(cost, world.timeofday - start_time), 0) if(ran_subsystems) var/oldcost = subsystem_cost var/newcost = 0 @@ -172,13 +190,10 @@ var/global/datum/controller/master/Master = new() subsystem_cost = MC_AVERAGE(oldcost, newcost) var/extrasleep = 0 - // If we caused BYOND to miss a tick, sleep a bit extra... - if(startingtick < world.time || start_time + 1 < world.timeofday) - extrasleep += world.tick_lag * 2 // If we are loading the server too much, sleep a bit extra... if(world.cpu >= 75) extrasleep += (extrasleep + processing_interval) * ((world.cpu-50)/10) - +#if DM_VERSION < 510 if(world.cpu >= 100) if(!old_fps) old_fps = world.fps @@ -187,33 +202,16 @@ var/global/datum/controller/master/Master = new() else if(old_fps && world.cpu < 50) world.fps = old_fps old_fps = null - +#endif sleep(processing_interval + extrasleep) else sleep(50) #undef MC_AVERAGE -// Determine the GCD of subsystem waits: the longest the MC can wait while still staying on schedule. -/datum/controller/master/proc/calculate_gcd() - var/GCD - // The shortest possible fire rate is the lowest of two ticks or 1 decisecond. - var/minimumInterval = min(world.tick_lag * 2, 1) - - // Loop over each subsystem and determine the GCD based on its wait value. - for(var/datum/subsystem/SS in subsystems) - if(SS.wait) - GCD = Gcd(round(SS.wait * 10), GCD) - GCD = round(GCD) - // If the GCD is less than the minimum, just use the minimum. - if(GCD < minimumInterval * 10) - GCD = minimumInterval * 10 - // Return GCD. - return GCD / 10 - /datum/controller/master/proc/stat_entry() if(!statclick) statclick = new/obj/effect/statclick/debug("Initializing...", src) - stat("Master Controller:", statclick.update("[round(Master.cost, 0.001)]ds (Interval: [Master.processing_interval] | Iteration:[Master.iteration])")) + stat("Master Controller:", statclick.update("[round(Master.cost, 0.01)]ds (Interval: [Master.processing_interval] | Iteration:[Master.iteration])")) diff --git a/code/controllers/subsystem.dm b/code/controllers/subsystem.dm index 90ba95687b4..2edfa916c59 100644 --- a/code/controllers/subsystem.dm +++ b/code/controllers/subsystem.dm @@ -24,6 +24,9 @@ var/last_fire = 0 //last world.time we called fire() var/next_fire = 0 //scheduled world.time for next fire() var/cost = 0 //average time to execute +#if DM_VERSION >= 510 + var/tick_usage = 0 //average tick usage +#endif var/times_fired = 0 //number of times we have called fire() // The object used for the clickable stat() button. @@ -59,9 +62,13 @@ dwait = "DWait:[round(wait,0.1)]ds " if(can_fire) - msg = "[round(cost,0.001)]ds\t[dwait][msg]" +#if DM_VERSION >= 510 + msg = "[round(cost,0.01)]ds|[round(tick_usage,1)]%\t[dwait][msg]" +#else + msg = "[round(cost,0.01)]ds\t[dwait][msg]" +#endif else - msg = "OFFLINE" + msg = "OFFLINE\t[msg]" stat(name, statclick.update(msg)) @@ -79,4 +86,4 @@ /datum/subsystem/on_varedit(edited_var) if (edited_var == "can_fire" && can_fire) next_fire = world.time + wait - + diff --git a/code/controllers/subsystem/garbage.dm b/code/controllers/subsystem/garbage.dm index 108497d7255..04c111d3198 100644 --- a/code/controllers/subsystem/garbage.dm +++ b/code/controllers/subsystem/garbage.dm @@ -22,7 +22,8 @@ var/datum/subsystem/garbage_collector/SSgarbage var/list/queue = list() // list of refID's of things that should be garbage collected // refID's are associated with the time at which they time out and need to be manually del() // we do this so we aren't constantly locating them and preventing them from being gc'd - + + var/list/tobequeued = list() //We store the references of things to be added to the queue seperately so we can spread out GC overhead over a few ticks var/list/didntgc = list() // list of all types that have failed to GC associated with the number of times that's happened. // the types are stored as strings @@ -52,12 +53,23 @@ var/datum/subsystem/garbage_collector/SSgarbage ..(msg) /datum/subsystem/garbage_collector/fire() + var/time_to_stop = world.timeofday + max_run_time + HandleToBeQueued(time_to_stop) + HandleQueue(time_to_stop) + +//If you see this proc high on the profile, what you are really seeing is the garbage collection/soft delete overhead in byond. +//Don't attempt to optimize, not worth the effort. +/datum/subsystem/garbage_collector/proc/HandleToBeQueued(time_to_stop) + while(tobequeued.len && world.timeofday < time_to_stop) + var/ref = tobequeued[1] + Queue(ref) + tobequeued.Cut(1, 2) + +/datum/subsystem/garbage_collector/proc/HandleQueue(time_to_stop) delslasttick = 0 gcedlasttick = 0 - var/time_to_stop = world.timeofday + max_run_time var/time_to_kill = world.time - collection_timeout // Anything qdel() but not GC'd BEFORE this time needs to be manually del() - - + while(queue.len && world.timeofday < time_to_stop) var/refID = queue[1] if (!refID) @@ -85,15 +97,24 @@ var/datum/subsystem/garbage_collector/SSgarbage ++totalgcs queue.Cut(1, 2) +/datum/subsystem/garbage_collector/proc/QueueForQueuing(datum/A) + if (istype(A) && isnull(A.gc_destroyed)) + tobequeued += A -/datum/subsystem/garbage_collector/proc/Queue(datum/A, harddel = 0) +/datum/subsystem/garbage_collector/proc/Queue(datum/A) if (!istype(A) || !isnull(A.gc_destroyed)) - return - A.gc_destroyed = world.time - queue -= "\ref[A]" // Removing any previous references that were GC'd so that the current object will be at the end of the list. - queue["\ref[A]"] = world.time + return + var/gctime = world.time + var/refid = "\ref[A]" + + A.gc_destroyed = gctime + + if (queue[refid]) + queue -= "\ref[A]" // Removing any previous references that were GC'd so that the current object will be at the end of the list. + + queue[refid] = gctime -/datum/subsystem/garbage_collector/proc/HardQueue(datum/A, harddel = 0) +/datum/subsystem/garbage_collector/proc/HardQueue(datum/A) if (!istype(A) || !isnull(A.gc_destroyed)) return A.gc_destroyed = world.time @@ -117,7 +138,7 @@ var/datum/subsystem/garbage_collector/SSgarbage return switch(hint) if (QDEL_HINT_QUEUE) //qdel should queue the object for deletion. - SSgarbage.Queue(D) + SSgarbage.QueueForQueuing(D) if (QDEL_HINT_LETMELIVE) //qdel should let the object live after calling destory. return if (QDEL_HINT_IWILLGC) //functionally the same as the above. qdel should assume the object will gc on its own, and not check it. @@ -129,7 +150,7 @@ var/datum/subsystem/garbage_collector/SSgarbage if (QDEL_HINT_PUTINPOOL) //qdel will put this object in the pool. PlaceInPool(D, 0) if (QDEL_HINT_FINDREFERENCE)//qdel will, if TESTING is enabled, display all references to this object, then queue the object for deletion. - SSgarbage.Queue(D) + SSgarbage.QueueForQueuing(D) #ifdef TESTING A.find_references() #endif @@ -137,7 +158,7 @@ var/datum/subsystem/garbage_collector/SSgarbage if(!("[D.type]" in SSgarbage.noqdelhint)) SSgarbage.noqdelhint += "[D.type]" testing("WARNING: [D.type] is not returning a qdel hint. It is being placed in the queue. Further instances of this type will also be queued.") - SSgarbage.Queue(D) + SSgarbage.QueueForQueuing(D) // Returns 1 if the object has been queued for deletion. /proc/qdeleted(datum/D) @@ -145,6 +166,8 @@ var/datum/subsystem/garbage_collector/SSgarbage return FALSE if(D.gc_destroyed) return TRUE + if(SSgarbage && SSgarbage.tobequeued && SSgarbage.tobequeued.len && D in SSgarbage.tobequeued) + return TRUE return FALSE // Default implementation of clean-up code. @@ -249,4 +272,4 @@ var/datum/subsystem/garbage_collector/SSgarbage dat += "[path] - [tmplist[path]] times
" usr << browse(dat, "window=qdeletedlog") -#endif \ No newline at end of file +#endif diff --git a/code/controllers/subsystem/shuttles.dm b/code/controllers/subsystem/shuttles.dm index 9736345ad41..4442bee8933 100644 --- a/code/controllers/subsystem/shuttles.dm +++ b/code/controllers/subsystem/shuttles.dm @@ -22,7 +22,7 @@ var/datum/subsystem/shuttle/SSshuttle var/ordernum = 1 //order number given to next order var/points = 50 //number of trade-points we have var/points_per_decisecond = 0.005 //points gained every decisecond - var/points_per_slip = 2 //points gained per slip returned + var/points_per_manifest = 2 //points gained per manifest returned var/points_per_crate = 5 //points gained per crate returned var/points_per_intel = 250 //points gained per intel returned var/points_per_plasma = 5 //points gained per plasma returned @@ -31,17 +31,17 @@ var/datum/subsystem/shuttle/SSshuttle var/list/discoveredPlants = list() //Typepaths for unusual plants we've already sent CentComm, associated with their potencies var/list/techLevels = list() var/list/researchDesigns = list() + + var/list/supply_packs = list() var/list/shoppinglist = list() var/list/requestlist = list() - var/list/supply_packs = list() - var/datum/round_event/shuttle_loan/shuttle_loan - var/sold_atoms = "" + var/list/orderhistory = list() + var/datum/round_event/shuttle_loan/shuttle_loan /datum/subsystem/shuttle/New() NEW_SS_GLOBAL(SSshuttle) - /datum/subsystem/shuttle/Initialize(timeofday, zlevel) if (zlevel) return ..() @@ -50,12 +50,14 @@ var/datum/subsystem/shuttle/SSshuttle if(!supply) WARNING("No /obj/docking_port/mobile/supply placed on the map!") - ordernum = rand(1,9000) + ordernum = rand(1, 9000) - for(var/typepath in subtypesof(/datum/supply_packs)) - var/datum/supply_packs/P = new typepath() - if(P.name == "HEADER") continue // To filter out group headers + for(var/pack in subtypesof(/datum/supply_pack)) + var/datum/supply_pack/P = new pack() + if(!P.contains) + continue supply_packs["[P.type]"] = P + initial_move() ..() diff --git a/code/controllers/subsystem/shuttles/emergency.dm b/code/controllers/subsystem/shuttles/emergency.dm deleted file mode 100644 index f798b68ea24..00000000000 --- a/code/controllers/subsystem/shuttles/emergency.dm +++ /dev/null @@ -1,262 +0,0 @@ -/obj/docking_port/mobile/emergency - name = "emergency shuttle" - id = "emergency" - - dwidth = 9 - width = 22 - height = 11 - dir = 4 - travelDir = -90 - roundstart_move = "emergency_away" - var/sound_played = 0 //If the launch sound has been sent to all players on the shuttle itself - -/obj/docking_port/mobile/emergency/New() - ..() - SSshuttle.emergency = src - -/obj/docking_port/mobile/emergency/timeLeft(divisor) - if(divisor <= 0) - divisor = 10 - if(!timer) - return round(SSshuttle.emergencyCallTime/divisor, 1) - - var/dtime = world.time - timer - switch(mode) - if(SHUTTLE_ESCAPE) - dtime = max(SSshuttle.emergencyEscapeTime - dtime, 0) - if(SHUTTLE_DOCKED) - dtime = max(SSshuttle.emergencyDockTime - dtime, 0) - else - dtime = max(SSshuttle.emergencyCallTime - dtime, 0) - return round(dtime/divisor, 1) - -/obj/docking_port/mobile/emergency/request(obj/docking_port/stationary/S, coefficient=1, area/signalOrigin, reason, redAlert) - SSshuttle.emergencyCallTime = initial(SSshuttle.emergencyCallTime) * coefficient - switch(mode) - if(SHUTTLE_RECALL) - mode = SHUTTLE_CALL - timer = world.time - timeLeft(1) - if(SHUTTLE_IDLE) - mode = SHUTTLE_CALL - timer = world.time - if(SHUTTLE_CALL) - if(world.time < timer) //this is just failsafe - timer = world.time - else - return - - if(prob(70)) - SSshuttle.emergencyLastCallLoc = signalOrigin - else - SSshuttle.emergencyLastCallLoc = null - - priority_announce("The emergency shuttle has been called. [redAlert ? "Red Alert state confirmed: Dispatching priority shuttle. " : "" ]It will arrive in [timeLeft(600)] minutes.[reason][SSshuttle.emergencyLastCallLoc ? "\n\nCall signal traced. Results can be viewed on any communications console." : "" ]", null, 'sound/AI/shuttlecalled.ogg', "Priority") - -/obj/docking_port/mobile/emergency/cancel(area/signalOrigin) - if(mode != SHUTTLE_CALL) - return - - timer = world.time - timeLeft(1) - mode = SHUTTLE_RECALL - - if(prob(70)) - SSshuttle.emergencyLastCallLoc = signalOrigin - else - SSshuttle.emergencyLastCallLoc = null - priority_announce("The emergency shuttle has been recalled.[SSshuttle.emergencyLastCallLoc ? " Recall signal traced. Results can be viewed on any communications console." : "" ]", null, 'sound/AI/shuttlerecalled.ogg', "Priority") - -/* -/obj/docking_port/mobile/emergency/findTransitDock() - . = SSshuttle.getDock("emergency_transit") - if(.) - return . - return ..() -*/ - - -/obj/docking_port/mobile/emergency/check() - if(!timer) - return - - var/time_left = timeLeft(1) - switch(mode) - if(SHUTTLE_RECALL) - if(time_left <= 0) - mode = SHUTTLE_IDLE - timer = 0 - if(SHUTTLE_CALL) - if(time_left <= 0) - //move emergency shuttle to station - if(dock(SSshuttle.getDock("emergency_home"))) - setTimer(20) - return - mode = SHUTTLE_DOCKED - timer = world.time - send2irc("Server", "The Emergency Shuttle has docked with the station.") - priority_announce("The Emergency Shuttle has docked with the station. You have [timeLeft(600)] minutes to board the Emergency Shuttle.", null, 'sound/AI/shuttledock.ogg', "Priority") - - //Gangs only have one attempt left if the shuttle has docked with the station to prevent suffering from dominator delays - for(var/datum/gang/G in ticker.mode.gangs) - if(isnum(G.dom_timer)) - G.dom_attempts = 0 - else - G.dom_attempts = min(1,G.dom_attempts) - - if(SHUTTLE_DOCKED) - - if(time_left <= 50 && !sound_played) //4 seconds left:REV UP THOSE ENGINES BOYS. - should sync up with the launch - sound_played = 1 //Only rev them up once. - for(var/area/shuttle/escape/E in world) - E << 'sound/effects/hyperspace_begin.ogg' - - if(time_left <= 0 && SSshuttle.emergencyNoEscape) - priority_announce("Hostile environment detected. Departure has been postponed indefinitely pending conflict resolution.", null, 'sound/misc/notice1.ogg', "Priority") - sound_played = 0 //Since we didn't launch, we will need to rev up the engines again next pass. - mode = SHUTTLE_STRANDED - - if(time_left <= 0 && !SSshuttle.emergencyNoEscape) - //move each escape pod (or applicable spaceship) to its corresponding transit dock - for(var/A in SSshuttle.mobile) - var/obj/docking_port/mobile/M = A - if(M.launch_status == UNLAUNCHED) //Pods will not launch from the mine/planet, and other ships won't launch unless we tell them to. - M.launch_status = ENDGAME_LAUNCHED - M.enterTransit() - - //now move the actual emergency shuttle to its transit dock - for(var/area/shuttle/escape/E in world) - E << 'sound/effects/hyperspace_progress.ogg' - enterTransit() - mode = SHUTTLE_ESCAPE - launch_status = ENDGAME_LAUNCHED - timer = world.time - priority_announce("The Emergency Shuttle has left the station. Estimate [timeLeft(600)] minutes until the shuttle docks at Central Command.", null, null, "Priority") - if(SHUTTLE_ESCAPE) - if(time_left <= 0) - //move each escape pod to its corresponding escape dock - for(var/A in SSshuttle.mobile) - var/obj/docking_port/mobile/M = A - if(M.launch_status == ENDGAME_LAUNCHED) - if(istype(M, /obj/docking_port/mobile/pod)) - M.dock(SSshuttle.getDock("[M.id]_away")) //Escape pods dock at centcomm - else - continue //Mapping a new docking point for each ship mappers could potentially want docking with centcomm would take up lots of space, just let them keep flying off into the sunset for their greentext - - //now move the actual emergency shuttle to centcomm - for(var/area/shuttle/escape/E in world) - E << 'sound/effects/hyperspace_end.ogg' - dock(SSshuttle.getDock("emergency_away")) - mode = SHUTTLE_ENDGAME - timer = 0 - open_dock() - -/obj/docking_port/mobile/emergency/proc/open_dock() - for(var/obj/machinery/door/poddoor/shuttledock/D in airlocks) - var/turf/T = get_step(D, D.checkdir) - if(!istype(T,/turf/space)) - spawn(0) - D.open() - -/obj/docking_port/mobile/pod - name = "escape pod" - id = "pod" - dwidth = 1 - width = 3 - height = 4 - launch_status = UNLAUNCHED - -/obj/docking_port/mobile/pod/request() - if((security_level == SEC_LEVEL_RED || security_level == SEC_LEVEL_DELTA) && launch_status == UNLAUNCHED) - launch_status = EARLY_LAUNCHED - return ..() - -/obj/docking_port/mobile/pod/New() - if(id == "pod") - WARNING("[type] id has not been changed from the default. Use the id convention \"pod1\" \"pod2\" etc.") - ..() - -/obj/docking_port/mobile/pod/cancel() - return - -/obj/machinery/computer/shuttle/pod - name = "pod control computer" - admin_controlled = 1 - shuttleId = "pod" - possible_destinations = "pod_asteroid" - icon = 'icons/obj/terminals.dmi' - icon_state = "dorm_available" - density = 0 - -/obj/machinery/computer/shuttle/pod/update_icon() - return - -/obj/docking_port/stationary/random - name = "escape pod" - id = "pod" - dwidth = 1 - width = 3 - height = 4 - var/target_area = /area/mine/unexplored - -/obj/docking_port/stationary/random/initialize() - ..() - var/list/turfs = get_area_turfs(target_area) - var/turf/T = pick(turfs) - src.loc = T - -//Pod suits/pickaxes - - -/obj/item/clothing/head/helmet/space/orange - name = "emergency space helmet" - icon_state = "syndicate-helm-orange" - item_state = "syndicate-helm-orange" - -/obj/item/clothing/suit/space/orange - name = "emergency space suit" - icon_state = "syndicate-orange" - item_state = "syndicate-orange" - slowdown = 3 - -/obj/item/weapon/pickaxe/emergency - name = "emergency disembarkation tool" - desc = "For extracting yourself from rough landings." - -/obj/item/weapon/storage/pod - name = "emergency space suits" - desc = "A wall mounted safe containing space suits. Will only open in emergencies." - anchored = 1 - density = 0 - icon = 'icons/obj/storage.dmi' - icon_state = "safe" - -/obj/item/weapon/storage/pod/New() - ..() - new /obj/item/clothing/head/helmet/space/orange(src) - new /obj/item/clothing/head/helmet/space/orange(src) - new /obj/item/clothing/suit/space/orange(src) - new /obj/item/clothing/suit/space/orange(src) - new /obj/item/clothing/mask/gas(src) - new /obj/item/clothing/mask/gas(src) - new /obj/item/weapon/tank/internals/oxygen/red(src) - new /obj/item/weapon/tank/internals/oxygen/red(src) - new /obj/item/weapon/pickaxe/emergency(src) - new /obj/item/weapon/pickaxe/emergency(src) - new /obj/item/weapon/survivalcapsule(src) - -/obj/item/weapon/storage/pod/attackby(obj/item/weapon/W, mob/user, params) - return - -/obj/item/weapon/storage/pod/MouseDrop(over_object, src_location, over_location) - if(security_level == SEC_LEVEL_RED || security_level == SEC_LEVEL_DELTA) - return ..() - else - usr << "The storage unit will only unlock during a Red or Delta security alert." - -/obj/item/weapon/storage/pod/attack_hand(mob/user) - return - - - -#undef UNLAUNCHED -#undef LAUNCHED -#undef EARLY_LAUNCHED diff --git a/code/game/asteroid.dm b/code/game/asteroid.dm index 1a54baa825f..5e405252680 100644 --- a/code/game/asteroid.dm +++ b/code/game/asteroid.dm @@ -64,7 +64,7 @@ var/global/max_secret_rooms = 6 if("organharvest") walltypes = list(/turf/simulated/wall/r_wall=2,/turf/simulated/wall=2,/turf/simulated/mineral/random/high_chance=1) floortypes = list(/turf/simulated/floor/plasteel,/turf/simulated/floor/engine) - treasureitems = list(/mob/living/simple_animal/bot/medbot/mysterious=1, /obj/item/weapon/circular_saw=1, /obj/structure/closet/critter/cat=2) + treasureitems = list(/mob/living/simple_animal/bot/medbot/mysterious=1, /obj/item/weapon/circular_saw=1, /obj/structure/closet/crate/critter=2, /mob/living/simple_animal/pet/cat/space=1) fluffitems = list(/obj/effect/decal/cleanable/blood=5,/obj/item/organ/internal/appendix=2,/obj/structure/closet/crate/freezer=2, /obj/structure/table/optable=1,/obj/item/weapon/scalpel=1,/obj/item/weapon/storage/firstaid/regular=3, /obj/item/weapon/tank/internals/anesthetic=1, /obj/item/weapon/surgical_drapes=2, /obj/item/device/mass_spectrometer/adv=1,/obj/item/clothing/glasses/hud/health=1) diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index 94bee1c4a7e..2e5fadd8916 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -131,8 +131,7 @@ . = ..() if(client) reset_perspective(destination) - if(pipes_shown.len && !istype(loc, /obj/machinery/atmospherics)) - remove_ventcrawl() + update_canmove() //if the mob was asleep inside a container and then got forceMoved out we need to make them fall. /mob/living/carbon/brain/forceMove(atom/destination) if(container) diff --git a/code/game/gamemodes/blob/blobs/blob_mobs.dm b/code/game/gamemodes/blob/blobs/blob_mobs.dm index 895e025eb02..5058c2d6b3a 100644 --- a/code/game/gamemodes/blob/blobs/blob_mobs.dm +++ b/code/game/gamemodes/blob/blobs/blob_mobs.dm @@ -19,6 +19,7 @@ color = overmind.blob_reagent_datum.color /mob/living/simple_animal/hostile/blob/blob_act() + adjustHealth(-maxHealth*0.025) return /mob/living/simple_animal/hostile/blob/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume) @@ -60,7 +61,7 @@ /mob/living/simple_animal/hostile/blob/blobspore/Life() if(!is_zombie && isturf(src.loc)) - for(var/mob/living/carbon/human/H in oview(src,1)) //Only for corpse right next to/on same tile + for(var/mob/living/carbon/human/H in view(src,1)) //Only for corpse right next to/on same tile if(H.stat == DEAD) Zombify(H) break @@ -89,7 +90,7 @@ human_overlays = H.overlays update_icons() H.loc = src - loc.visible_message("The corpse of [H.name] suddenly rises!") + visible_message("The corpse of [H.name] suddenly rises!") /mob/living/simple_animal/hostile/blob/blobspore/death(gibbed) ..(1) @@ -173,7 +174,7 @@ if(overmind) var/mob/living/L = target var/mob_protection = L.get_permeability_protection() - overmind.blob_reagent_datum.reaction_mob(L, VAPOR, 20, 0, mob_protection)//this will do between 10 and 20 damage(reduced by mob protection), depending on chemical, plus 4 from base brute damage. + overmind.blob_reagent_datum.reaction_mob(L, VAPOR, 20, 0, mob_protection, overmind)//this will do between 10 and 20 damage(reduced by mob protection), depending on chemical, plus 4 from base brute damage. if(target) ..() diff --git a/code/game/gamemodes/blob/powers.dm b/code/game/gamemodes/blob/powers.dm index a489e4d5407..f08365799c9 100644 --- a/code/game/gamemodes/blob/powers.dm +++ b/code/game/gamemodes/blob/powers.dm @@ -169,12 +169,12 @@ if(!can_buy(5)) return last_attack = world.time - OB.expand(T, 0, src) + OB.expand(T, src) for(var/mob/living/L in T) if("blob" in L.faction) //no friendly fire continue var/mob_protection = L.get_permeability_protection() - blob_reagent_datum.reaction_mob(L, VAPOR, 25, 1, mob_protection) + blob_reagent_datum.reaction_mob(L, VAPOR, 25, 1, mob_protection, src) blob_reagent_datum.send_message(L) /mob/camera/blob/verb/rally_spores_power() @@ -213,8 +213,11 @@ set desc = "Replaces your chemical with a random, different one." if(!can_buy(40)) return - var/datum/reagent/blob/B = pick((subtypesof(/datum/reagent/blob) - blob_reagent_datum.type)) - blob_reagent_datum = new B + set_chemical() + +/mob/camera/blob/proc/set_chemical() + var/datum/reagent/blob/BC = pick((subtypesof(/datum/reagent/blob) - blob_reagent_datum.type)) + blob_reagent_datum = new BC for(var/obj/effect/blob/BL in blobs) BL.update_icon() for(var/mob/living/simple_animal/hostile/blob/BLO) diff --git a/code/game/gamemodes/blob/theblob.dm b/code/game/gamemodes/blob/theblob.dm index 3b67eab6a7c..95063875993 100644 --- a/code/game/gamemodes/blob/theblob.dm +++ b/code/game/gamemodes/blob/theblob.dm @@ -103,7 +103,7 @@ if(expand_range) src.expand() for(var/obj/effect/blob/B in orange(expand_range, src)) - if(prob(20 - get_dist(get_turf(src), get_turf(B)) * 4)) //expand falls off with range but is faster near the blob causing the expansion + if(prob(max(13 - get_dist(get_turf(src), get_turf(B)) * 4, 1))) //expand falls off with range but is faster near the blob causing the expansion B.expand() return @@ -121,9 +121,7 @@ A.blob_act() -/obj/effect/blob/proc/expand(turf/T = null, prob = 1, controller = null) - if(prob && !prob(health)) - return +/obj/effect/blob/proc/expand(turf/T = null, controller = null) if(!T) var/list/dirs = list(1,2,4,8) for(var/i = 1 to 4) diff --git a/code/game/gamemodes/cult/runes.dm b/code/game/gamemodes/cult/runes.dm index 28baf88d03e..d12f9e16923 100644 --- a/code/game/gamemodes/cult/runes.dm +++ b/code/game/gamemodes/cult/runes.dm @@ -152,7 +152,7 @@ structure_check() searches for nearby cultist structures required for the invoca /mob/proc/null_rod_check() //The null rod, if equipped, will protect the holder from the effects of most runes var/obj/item/weapon/nullrod/N = locate() in src if(N) - return 1 + return N return 0 var/list/teleport_runes = list() @@ -291,9 +291,10 @@ var/list/teleport_other_runes = list() if(!offering) rune_in_use = 0 return - if(offering.null_rod_check()) + var/obj/item/weapon/nullrod/N = offering.null_rod_check() + if(N) user << "Something is blocking the Geometer's magic!" - log_game("Sacrifice rune failed - target has null rod") + log_game("Sacrifice rune failed - target has \a [N]!") fail_invoke() rune_in_use = 0 return @@ -790,8 +791,9 @@ var/list/teleport_other_runes = list() visible_message("[src] briefly bubbles before exploding!") for(var/mob/living/carbon/C in viewers(src)) if(!iscultist(C)) - if(C.null_rod_check()) - C << "The null rod suddenly burns hotly before returning to normal!" + var/obj/item/weapon/nullrod/N = C.null_rod_check() + if(N) + C << "\The [N] suddenly burns hotly before returning to normal!" continue C << "Your blood boils in your veins!" C.take_overall_damage(51,51) diff --git a/code/game/gamemodes/handofgod/_handofgod.dm b/code/game/gamemodes/handofgod/_handofgod.dm index 5591897e264..100f079770d 100644 --- a/code/game/gamemodes/handofgod/_handofgod.dm +++ b/code/game/gamemodes/handofgod/_handofgod.dm @@ -188,9 +188,9 @@ var/global/list/global_handofgod_structuretypes = list() if((follower_mind in red_deity_followers) || (follower_mind in red_deity_prophets) || (follower_mind in blue_deity_followers) || (follower_mind in blue_deity_prophets)) H << "You already belong to a deity. Your strong faith has blocked out the conversion attempt by the followers of the [colour] deity." return 0 - var/obj/item/weapon/nullrod/N = locate() in H + var/obj/item/weapon/nullrod/N = H.null_rod_check() if(N) - H << "Your null rod prevented the [colour] deity from brainwashing you." + H << "Your holy weapon prevented the [colour] deity from brainwashing you." return 0 if(colour == "red") diff --git a/code/game/gamemodes/miniantags/revenant/revenant.dm b/code/game/gamemodes/miniantags/revenant/revenant.dm index 0e05f8f4066..0212fb49e7d 100644 --- a/code/game/gamemodes/miniantags/revenant/revenant.dm +++ b/code/game/gamemodes/miniantags/revenant/revenant.dm @@ -319,7 +319,7 @@ /mob/living/simple_animal/revenant/attackby(obj/item/W, mob/living/user, params) if(istype(W, /obj/item/weapon/nullrod)) visible_message("[src] violently flinches!", \ - "As the null rod passes through you, you feel your essence draining away!") + "As \the [W] passes through you, you feel your essence draining away!") adjustBruteLoss(25) //hella effective inhibited = 1 spawn(30) diff --git a/code/game/gamemodes/wizard/spellbook.dm b/code/game/gamemodes/wizard/spellbook.dm index 5d086314ea1..96a8902f030 100644 --- a/code/game/gamemodes/wizard/spellbook.dm +++ b/code/game/gamemodes/wizard/spellbook.dm @@ -227,7 +227,7 @@ /datum/spellbook_entry/shapeshift name = "Wild Shapeshift" - spell_type = /obj/effect/proc_holder/spell/targeted/shapeshift/wild + spell_type = /obj/effect/proc_holder/spell/targeted/shapeshift log_name = "WS" category = "Assistance" cost = 1 diff --git a/code/game/machinery/autolathe.dm b/code/game/machinery/autolathe.dm index 925f9ed8f13..60f080fcceb 100644 --- a/code/game/machinery/autolathe.dm +++ b/code/game/machinery/autolathe.dm @@ -40,7 +40,8 @@ "Security", "Machinery", "Medical", - "Misc" + "Misc", + "Imported" ) /obj/machinery/autolathe/New() @@ -111,7 +112,19 @@ return 1 if(stat) return 1 - + + if(istype(O, /obj/item/weapon/disk/design_disk)) + user.visible_message("[user] begins to load \the [O] in \the [src]...", + "You begin to load a design from \the [O]...", + "You hear the chatter of a floppy drive.") + busy = 1 + var/obj/item/weapon/disk/design_disk/D = O + if(do_after(user, 14.4, target = src)) + files.AddDesign2Known(D.blueprint) + + busy = 0 + return + var/material_amount = materials.get_item_material_amount(O) if(!material_amount) user << "This object does not contain sufficient amounts of metal or glass to be accepted by the autolathe." diff --git a/code/game/machinery/machinery.dm b/code/game/machinery/machinery.dm index 07bd6b78ed7..417bd465fd5 100644 --- a/code/game/machinery/machinery.dm +++ b/code/game/machinery/machinery.dm @@ -127,8 +127,7 @@ Class Procs: /obj/machinery/Destroy() machines.Remove(src) SSmachine.processing -= src - if(occupant) - dropContents() + dropContents() return ..() /obj/machinery/attackby(obj/item/weapon/W, mob/user, params) @@ -160,10 +159,14 @@ Class Procs: /obj/machinery/proc/dropContents() var/turf/T = get_turf(src) + for(var/mob/living/L in src) + L.loc = T + L.reset_perspective(null) + L.update_canmove() //so the mob falls if he became unconscious inside the machine. + . += L + T.contents += contents - if(occupant) - occupant.reset_perspective(null) - occupant = null + occupant = null /obj/machinery/proc/close_machine(mob/living/target = null) state_open = 0 @@ -402,4 +405,16 @@ Class Procs: if (hclient.client.mob && hclient.client.mob.machine == src) hclient.client.mob.unset_machine() /obj/machinery/proc/can_be_overridden() - . = 1 \ No newline at end of file + . = 1 + + +/obj/machinery/tesla_act(var/power) + ..() + if(prob(85)) + emp_act(2) + else if(prob(50)) + ex_act(3) + else if(prob(90)) + ex_act(2) + else + ex_act(1) diff --git a/code/game/machinery/vending.dm b/code/game/machinery/vending.dm index 21b238c95ea..df05de5499c 100644 --- a/code/game/machinery/vending.dm +++ b/code/game/machinery/vending.dm @@ -764,8 +764,7 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C desc = "Wall-mounted Medical Equipment dispenser." icon_state = "wallmed" icon_deny = "wallmed-deny" - req_access_txt = "5" - density = 0 //It is wall-mounted, and thus, not dense. --Superxpdude + density = 0 products = list(/obj/item/weapon/reagent_containers/syringe = 3,/obj/item/weapon/reagent_containers/pill/patch/styptic = 5, /obj/item/weapon/reagent_containers/pill/patch/silver_sulf = 5,/obj/item/weapon/reagent_containers/pill/charcoal = 2) contraband = list(/obj/item/weapon/reagent_containers/pill/tox = 2,/obj/item/weapon/reagent_containers/pill/morphine = 2) @@ -960,4 +959,4 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C #undef STANDARD_CHARGE #undef CONTRABAND_CHARGE -#undef COIN_CHARGE \ No newline at end of file +#undef COIN_CHARGE diff --git a/code/game/mecha/equipment/tools/medical_tools.dm b/code/game/mecha/equipment/tools/medical_tools.dm index d025a43ed9b..9d4a6c7937b 100644 --- a/code/game/mecha/equipment/tools/medical_tools.dm +++ b/code/game/mecha/equipment/tools/medical_tools.dm @@ -1,7 +1,35 @@ +// Sleeper, Medical Beam, and Syringe gun -// Sleeper and Syringe gun +/obj/item/mecha_parts/mecha_equipment/medical -/obj/item/mecha_parts/mecha_equipment/sleeper +/obj/item/mecha_parts/mecha_equipment/medical/New() + ..() + SSobj.processing |= src + + +/obj/item/mecha_parts/mecha_equipment/medical/can_attach(obj/mecha/medical/M) + if(..() && istype(M)) + return 1 + + +/obj/item/mecha_parts/mecha_equipment/medical/attach(obj/mecha/M) + ..() + SSobj.processing |= src + +/obj/item/mecha_parts/mecha_equipment/medical/Destroy() + SSobj.processing -= src + return ..() + +/obj/item/mecha_parts/mecha_equipment/medical/process() + if(!chassis) + SSobj.processing -= src + return 1 + +/obj/item/mecha_parts/mecha_equipment/medical/mechmedbeam/detach() + SSobj.processing -= src + return ..() + +/obj/item/mecha_parts/mecha_equipment/medical/sleeper name = "mounted sleeper" desc = "Equipment for medical exosuits. A mounted sleeper that stabilizes patients and can inject reagents in the exosuit's reserves." icon = 'icons/obj/Cryogenic2.dmi' @@ -15,29 +43,18 @@ var/inject_amount = 10 salvageable = 0 -/obj/item/mecha_parts/mecha_equipment/sleeper/can_attach(obj/mecha/medical/M) - if(..()) - if(istype(M)) - return 1 +/obj/item/mecha_parts/mecha_equipment/medical/sleeper/allow_drop() return 0 -/obj/item/mecha_parts/mecha_equipment/sleeper/attach(obj/mecha/M) - ..() - SSobj.processing |= src - -/obj/item/mecha_parts/mecha_equipment/sleeper/allow_drop() - return 0 - -/obj/item/mecha_parts/mecha_equipment/sleeper/Destroy() - SSobj.processing.Remove(src) +/obj/item/mecha_parts/mecha_equipment/medical/sleeper/Destroy() for(var/atom/movable/AM in src) AM.forceMove(get_turf(src)) return ..() -/obj/item/mecha_parts/mecha_equipment/sleeper/Exit(atom/movable/O) +/obj/item/mecha_parts/mecha_equipment/medical/sleeper/Exit(atom/movable/O) return 0 -/obj/item/mecha_parts/mecha_equipment/sleeper/action(mob/living/carbon/target) +/obj/item/mecha_parts/mecha_equipment/medical/sleeper/action(mob/living/carbon/target) if(!action_checks(target)) return if(!istype(target)) @@ -57,7 +74,7 @@ chassis.visible_message("[chassis] loads [target] into [src].") log_message("[target] loaded. Life support functions engaged.") -/obj/item/mecha_parts/mecha_equipment/sleeper/proc/patient_insertion_check(mob/living/carbon/target) +/obj/item/mecha_parts/mecha_equipment/medical/sleeper/proc/patient_insertion_check(mob/living/carbon/target) if(target.buckled) occupant_message("[target] will not fit into the sleeper because they are buckled to [target.buckled]!") return @@ -69,24 +86,24 @@ return return 1 -/obj/item/mecha_parts/mecha_equipment/sleeper/proc/go_out() +/obj/item/mecha_parts/mecha_equipment/medical/sleeper/proc/go_out() if(!patient) return patient.forceMove(get_turf(src)) occupant_message("[patient] ejected. Life support functions disabled.") log_message("[patient] ejected. Life support functions disabled.") - SSobj.processing.Remove(src) + SSobj.processing -= src patient = null update_equip_info() -/obj/item/mecha_parts/mecha_equipment/sleeper/detach() +/obj/item/mecha_parts/mecha_equipment/medical/sleeper/detach() if(patient) occupant_message("Unable to detach [src] - equipment occupied!") return - SSobj.processing.Remove(src) + SSobj.processing -= src return ..() -/obj/item/mecha_parts/mecha_equipment/sleeper/get_equip_info() +/obj/item/mecha_parts/mecha_equipment/medical/sleeper/get_equip_info() var/output = ..() if(output) var/temp = "" @@ -95,7 +112,7 @@ return "[output] [temp]" return -/obj/item/mecha_parts/mecha_equipment/sleeper/Topic(href,href_list) +/obj/item/mecha_parts/mecha_equipment/medical/sleeper/Topic(href,href_list) ..() var/datum/topic_input/filter = new /datum/topic_input(href,href_list) if(filter.get("eject")) @@ -108,7 +125,7 @@ inject_reagent(filter.getType("inject",/datum/reagent),filter.getObj("source")) return -/obj/item/mecha_parts/mecha_equipment/sleeper/proc/get_patient_stats() +/obj/item/mecha_parts/mecha_equipment/medical/sleeper/proc/get_patient_stats() if(!patient) return return {" @@ -137,7 +154,7 @@ "} -/obj/item/mecha_parts/mecha_equipment/sleeper/proc/get_patient_dam() +/obj/item/mecha_parts/mecha_equipment/medical/sleeper/proc/get_patient_dam() var/t1 switch(patient.stat) if(0) @@ -158,16 +175,16 @@ [patient.getBrainLoss() ? "Significant brain damage detected." : ""]
"} -/obj/item/mecha_parts/mecha_equipment/sleeper/proc/get_patient_reagents() +/obj/item/mecha_parts/mecha_equipment/medical/sleeper/proc/get_patient_reagents() if(patient.reagents) for(var/datum/reagent/R in patient.reagents.reagent_list) if(R.volume > 0) . += "[R]: [round(R.volume,0.01)]
" return . || "None" -/obj/item/mecha_parts/mecha_equipment/sleeper/proc/get_available_reagents() +/obj/item/mecha_parts/mecha_equipment/medical/sleeper/proc/get_available_reagents() var/output - var/obj/item/mecha_parts/mecha_equipment/syringe_gun/SG = locate(/obj/item/mecha_parts/mecha_equipment/syringe_gun) in chassis + var/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/SG = locate(/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun) in chassis if(SG && SG.reagents && islist(SG.reagents.reagent_list)) for(var/datum/reagent/R in SG.reagents.reagent_list) if(R.volume > 0) @@ -175,7 +192,7 @@ return output -/obj/item/mecha_parts/mecha_equipment/sleeper/proc/inject_reagent(datum/reagent/R,obj/item/mecha_parts/mecha_equipment/syringe_gun/SG) +/obj/item/mecha_parts/mecha_equipment/medical/sleeper/proc/inject_reagent(datum/reagent/R,obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/SG) if(!R || !patient || !SG || !(SG in chassis.equipment)) return 0 var/to_inject = min(R.volume, inject_amount) @@ -187,7 +204,7 @@ update_equip_info() return -/obj/item/mecha_parts/mecha_equipment/sleeper/update_equip_info() +/obj/item/mecha_parts/mecha_equipment/medical/sleeper/update_equip_info() if(..()) if(patient) send_byjax(chassis.occupant,"msleeper.browser","lossinfo",get_patient_dam()) @@ -196,18 +213,17 @@ return 1 return -/obj/item/mecha_parts/mecha_equipment/sleeper/container_resist() +/obj/item/mecha_parts/mecha_equipment/medical/sleeper/container_resist() go_out() -/obj/item/mecha_parts/mecha_equipment/sleeper/process() - if(!chassis) - SSobj.processing.Remove(src) +/obj/item/mecha_parts/mecha_equipment/medical/sleeper/process() + if(..()) return if(!chassis.has_charge(energy_drain)) set_ready_state(1) log_message("Deactivated.") occupant_message("[src] deactivated - no power.") - SSobj.processing.Remove(src) + SSobj.processing -= src return var/mob/living/carbon/M = patient if(!M) @@ -229,7 +245,7 @@ ///////////////////////////////// Syringe Gun /////////////////////////////////////////////////////////////// -/obj/item/mecha_parts/mecha_equipment/syringe_gun +/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun name = "exosuit syringe gun" desc = "Equipment for medical exosuits. A chem synthesizer with syringe gun. Reagents inside are held in stasis, so no reactions will occur." icon = 'icons/obj/guns/projectile.dmi' @@ -246,7 +262,7 @@ equip_cooldown = 10 origin_tech = "materials=3;biotech=4;magnets=4;programming=3" -/obj/item/mecha_parts/mecha_equipment/syringe_gun/New() +/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/New() ..() flags |= NOREACT syringes = new @@ -254,32 +270,32 @@ processed_reagents = new create_reagents(max_volume) -/obj/item/mecha_parts/mecha_equipment/syringe_gun/detach() - SSobj.processing.Remove(src) +/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/detach() + SSobj.processing -= src return ..() -/obj/item/mecha_parts/mecha_equipment/syringe_gun/Destroy() - SSobj.processing.Remove(src) +/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/Destroy() + SSobj.processing -= src return ..() -/obj/item/mecha_parts/mecha_equipment/syringe_gun/critfail() +/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/critfail() ..() flags &= ~NOREACT return -/obj/item/mecha_parts/mecha_equipment/syringe_gun/can_attach(obj/mecha/medical/M) +/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/can_attach(obj/mecha/medical/M) if(..()) if(istype(M)) return 1 return 0 -/obj/item/mecha_parts/mecha_equipment/syringe_gun/get_equip_info() +/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/get_equip_info() var/output = ..() if(output) return "[output] \[[mode? "Analyze" : "Launch"]\]
\[Syringes: [syringes.len]/[max_syringes] | Reagents: [reagents.total_volume]/[reagents.maximum_volume]\]
Reagents list" return -/obj/item/mecha_parts/mecha_equipment/syringe_gun/action(atom/movable/target) +/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/action(atom/movable/target) if(!action_checks(target)) return if(istype(target,/obj/item/weapon/reagent_containers/syringe)) @@ -344,7 +360,7 @@ return 1 -/obj/item/mecha_parts/mecha_equipment/syringe_gun/Topic(href,href_list) +/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/Topic(href,href_list) ..() var/datum/topic_input/filter = new (href,href_list) if(filter.get("toggle_mode")) @@ -382,7 +398,7 @@ return return -/obj/item/mecha_parts/mecha_equipment/syringe_gun/proc/get_reagents_page() +/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/proc/get_reagents_page() var/output = {" Reagent Synthesizer @@ -410,7 +426,7 @@ "} return output -/obj/item/mecha_parts/mecha_equipment/syringe_gun/proc/get_reagents_form() +/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/proc/get_reagents_form() var/r_list = get_reagents_list() var/inputs if(r_list) @@ -425,14 +441,14 @@ "} return output -/obj/item/mecha_parts/mecha_equipment/syringe_gun/proc/get_reagents_list() +/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/proc/get_reagents_list() var/output for(var/i=1 to known_reagents.len) var/reagent_id = known_reagents[i] output += {" [known_reagents[reagent_id]]
"} return output -/obj/item/mecha_parts/mecha_equipment/syringe_gun/proc/get_current_reagents() +/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/proc/get_current_reagents() var/output for(var/datum/reagent/R in reagents.reagent_list) if(R.volume > 0) @@ -441,7 +457,7 @@ output += "Total: [round(reagents.total_volume,0.001)]/[reagents.maximum_volume] - Purge All" return output || "None" -/obj/item/mecha_parts/mecha_equipment/syringe_gun/proc/load_syringe(obj/item/weapon/reagent_containers/syringe/S) +/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/proc/load_syringe(obj/item/weapon/reagent_containers/syringe/S) if(syringes.len= 2) occupant_message("The syringe is too far away.") @@ -463,7 +479,7 @@ occupant_message("The [src] syringe chamber is full.") return 0 -/obj/item/mecha_parts/mecha_equipment/syringe_gun/proc/analyze_reagents(atom/A) +/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/proc/analyze_reagents(atom/A) if(get_dist(src,A) >= 4) occupant_message("The object is too far away.") return 0 @@ -478,34 +494,33 @@ occupant_message("Analyzis complete.") return 1 -/obj/item/mecha_parts/mecha_equipment/syringe_gun/proc/add_known_reagent(r_id,r_name) +/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/proc/add_known_reagent(r_id,r_name) if(!(r_id in known_reagents)) known_reagents += r_id known_reagents[r_id] = r_name return 1 return 0 -/obj/item/mecha_parts/mecha_equipment/syringe_gun/update_equip_info() +/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/update_equip_info() if(..()) send_byjax(chassis.occupant,"msyringegun.browser","reagents",get_current_reagents()) send_byjax(chassis.occupant,"msyringegun.browser","reagents_form",get_reagents_form()) return 1 return -/obj/item/mecha_parts/mecha_equipment/syringe_gun/on_reagent_change() +/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/on_reagent_change() ..() update_equip_info() return -/obj/item/mecha_parts/mecha_equipment/syringe_gun/process() - if(!chassis) - SSobj.processing.Remove(src) +/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/process() + if(..()) return if(!processed_reagents.len || reagents.total_volume >= reagents.maximum_volume || !chassis.has_charge(energy_drain)) occupant_message("Reagent processing stopped.") log_message("Reagent processing stopped.") - SSobj.processing.Remove(src) + SSobj.processing -= src return if(anyprob(reliability)) critfail() @@ -514,3 +529,38 @@ reagents.add_reagent(reagent,amount) chassis.use_power(energy_drain) +///////////////////////////////// Medical Beam /////////////////////////////////////////////////////////////// + +/obj/item/mecha_parts/mecha_equipment/medical/mechmedbeam + name = "exosuit medical beamgun" + desc = "Equipment for medical exosuits. Generates a focused beam of medical nanites." + icon_state = "mecha_medigun" + energy_drain = 10 + range = MELEE|RANGED + equip_cooldown = 0 + origin_tech = "combat=5;materials=6;powerstorage=7;biotech=6" + var/obj/item/weapon/gun/medbeam/mech/medigun + materials = list(MAT_METAL = 15000, MAT_GLASS = 8000, MAT_PLASMA = 3000, MAT_GOLD = 8000, MAT_DIAMOND = 2000) + +/obj/item/mecha_parts/mecha_equipment/medical/mechmedbeam/New() + ..() + medigun = new(src) + + +/obj/item/mecha_parts/mecha_equipment/medical/mechmedbeam/Destroy() + qdel(medigun) + return ..() + +/obj/item/mecha_parts/mecha_equipment/medical/mechmedbeam/process() + if(..()) + return + medigun.process() + +/obj/item/mecha_parts/mecha_equipment/medical/mechmedbeam/action(atom/target) + medigun.process_fire(target, loc) + + +/obj/item/mecha_parts/mecha_equipment/medical/mechmedbeam/detach() + SSobj.processing -= src + medigun.LoseTarget() + return ..() diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm index 17255ba6ae5..08a80cb0711 100644 --- a/code/game/mecha/mecha.dm +++ b/code/game/mecha/mecha.dm @@ -169,7 +169,7 @@ qdel(cell) if(internal_tank) qdel(internal_tank) - SSobj.processing.Remove(src) + SSobj.processing -= src poi_list.Remove(src) equipment.Cut() cell = null diff --git a/code/game/objects/effects/overlays.dm b/code/game/objects/effects/overlays.dm index 2cf8d1553b1..7182cea7fd5 100644 --- a/code/game/objects/effects/overlays.dm +++ b/code/game/objects/effects/overlays.dm @@ -39,6 +39,14 @@ spawn(duration) qdel(src) +/obj/effect/overlay/temp/explosion + name = "explosion" + icon = 'icons/effects/96x96.dmi' + icon_state = "explosion" + pixel_x = -32 + pixel_y = -32 + duration = 8 + /obj/effect/overlay/temp/blob name = "blob" icon_state = "blob_attack" diff --git a/code/game/objects/items/devices/PDA/cart.dm b/code/game/objects/items/devices/PDA/cart.dm index e229630bb5c..575cb81c0b2 100644 --- a/code/game/objects/items/devices/PDA/cart.dm +++ b/code/game/objects/items/devices/PDA/cart.dm @@ -501,13 +501,13 @@ Code: menu += "
Current approved orders:
    " for(var/S in SSshuttle.shoppinglist) var/datum/supply_order/SO = S - menu += "
  1. #[SO.ordernum] - [SO.object.name] approved by [SO.orderedby] [SO.comment ? "([SO.comment])":""]
  2. " + menu += "
  3. #[SO.id] - [SO.pack.name] approved by [SO.orderer] [SO.reason ? "([SO.reason])":""]
  4. " menu += "
" menu += "Current requests:
    " for(var/S in SSshuttle.requestlist) var/datum/supply_order/SO = S - menu += "
  1. #[SO.ordernum] - [SO.object.name] requested by [SO.orderedby]
  2. " + menu += "
  3. #[SO.id] - [SO.pack.name] requested by [SO.orderer]
  4. " menu += "
Upgrade NOW to Space Parts & Space Vendors PLUS for full remote order control and inventory management." if (49) //janitorial locator diff --git a/code/game/objects/items/stacks/sheets/glass.dm b/code/game/objects/items/stacks/sheets/glass.dm index 4587104e2d1..51ecb4ad1fc 100644 --- a/code/game/objects/items/stacks/sheets/glass.dm +++ b/code/game/objects/items/stacks/sheets/glass.dm @@ -21,6 +21,9 @@ is_cyborg = 1 cost = 500 +/obj/item/stack/sheet/glass/fifty + amount = 50 + /obj/item/stack/sheet/glass/attack_self(mob/user) construct_window(user) diff --git a/code/game/objects/items/stacks/sheets/mineral.dm b/code/game/objects/items/stacks/sheets/mineral.dm index a976498469c..1670a24e98e 100644 --- a/code/game/objects/items/stacks/sheets/mineral.dm +++ b/code/game/objects/items/stacks/sheets/mineral.dm @@ -15,12 +15,20 @@ Mineral Sheets - Enriched Uranium */ +/obj/item/stack/sheet/mineral + icon = 'icons/obj/mining.dmi' + /* * Sandstone */ -/obj/item/stack/sheet/mineral - icon = 'icons/obj/mining.dmi' +var/global/list/datum/stack_recipe/sandstone_recipes = list ( \ + new/datum/stack_recipe("pile of dirt", /obj/machinery/hydroponics/soil, 3, time = 10, one_per_turf = 1, on_floor = 1), \ + new/datum/stack_recipe("sandstone door", /obj/structure/mineral_door/sandstone, 10, one_per_turf = 1, on_floor = 1), \ + new/datum/stack_recipe("Assistant Statue", /obj/structure/statue/sandstone/assistant, 5, one_per_turf = 1, on_floor = 1), \ +/* new/datum/stack_recipe("sandstone wall", ???), \ + new/datum/stack_recipe("sandstone floor", ???),\ */ + ) /obj/item/stack/sheet/mineral/sandstone name = "sandstone brick" @@ -33,20 +41,15 @@ Mineral Sheets materials = list(MAT_GLASS=MINERAL_MATERIAL_AMOUNT) sheettype = "sandstone" -var/global/list/datum/stack_recipe/sandstone_recipes = list ( \ - new/datum/stack_recipe("pile of dirt", /obj/machinery/hydroponics/soil, 3, time = 10, one_per_turf = 1, on_floor = 1), \ - new/datum/stack_recipe("sandstone door", /obj/structure/mineral_door/sandstone, 10, one_per_turf = 1, on_floor = 1), \ - new/datum/stack_recipe("Assistant Statue", /obj/structure/statue/sandstone/assistant, 5, one_per_turf = 1, on_floor = 1), \ -/* new/datum/stack_recipe("sandstone wall", ???), \ - new/datum/stack_recipe("sandstone floor", ???),\ */ - ) - /obj/item/stack/sheet/mineral/sandstone/New(var/loc, var/amount=null) recipes = sandstone_recipes pixel_x = rand(0,4)-4 pixel_y = rand(0,4)-4 ..() +/obj/item/stack/sheet/mineral/sandstone/thirty + amount = 30 + /* * Diamond */ diff --git a/code/game/objects/items/stacks/sheets/sheet_types.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm index 76977ceb339..619503cd778 100644 --- a/code/game/objects/items/stacks/sheets/sheet_types.dm +++ b/code/game/objects/items/stacks/sheets/sheet_types.dm @@ -57,6 +57,9 @@ var/global/list/datum/stack_recipe/metal_recipes = list ( \ flags = CONDUCT origin_tech = "materials=1" +/obj/item/stack/sheet/metal/fifty + amount = 50 + /obj/item/stack/sheet/metal/cyborg materials = list() is_cyborg = 1 @@ -66,13 +69,12 @@ var/global/list/datum/stack_recipe/metal_recipes = list ( \ recipes = metal_recipes return ..() - /* * Plasteel */ var/global/list/datum/stack_recipe/plasteel_recipes = list ( \ new/datum/stack_recipe("AI core", /obj/structure/AIcore, 4, time = 50, one_per_turf = 1), \ - ) +) /obj/item/stack/sheet/plasteel name = "plasteel" @@ -86,8 +88,14 @@ var/global/list/datum/stack_recipe/plasteel_recipes = list ( \ origin_tech = "materials=2" /obj/item/stack/sheet/plasteel/New(var/loc, var/amount=null) - recipes = plasteel_recipes - return ..() + recipes = plasteel_recipes + return ..() + +/obj/item/stack/sheet/plasteel/twenty + amount = 20 + +/obj/item/stack/sheet/plasteel/fifty + amount = 50 /* * Wood @@ -122,6 +130,9 @@ var/global/list/datum/stack_recipe/wood_recipes = list ( \ recipes = wood_recipes return ..() +/obj/item/stack/sheet/mineral/wood/fifty + amount = 50 + /* * Cloth */ @@ -160,9 +171,12 @@ var/global/list/datum/stack_recipe/cardboard_recipes = list ( \ recipes = cardboard_recipes return ..() +/obj/item/stack/sheet/cardboard/fifty + amount = 50 + /* * Runed Metal -*/ + */ var/global/list/datum/stack_recipe/runed_metal_recipes = list ( \ new/datum/stack_recipe("pylon", /obj/structure/cult/pylon, 4, time = 40, one_per_turf = 1, on_floor = 1), \ diff --git a/code/game/objects/items/stacks/tiles/tile_types.dm b/code/game/objects/items/stacks/tiles/tile_types.dm index 050eb3ed596..abf71e73b6d 100644 --- a/code/game/objects/items/stacks/tiles/tile_types.dm +++ b/code/game/objects/items/stacks/tiles/tile_types.dm @@ -114,6 +114,8 @@ turf_type = /turf/simulated/floor/noslip origin_tech = "materials=3" +/obj/item/stack/tile/noslip/thirty + amount = 30 //Plasteel (normal) /obj/item/stack/tile/plasteel diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm index 390ab2612bd..7ab9b6001ac 100755 --- a/code/game/objects/items/toys.dm +++ b/code/game/objects/items/toys.dm @@ -384,12 +384,12 @@ dat = "" /obj/item/toy/crayon/proc/crayon_text_strip(text) - var/list/base = splittext(lowertext(text),"") + var/list/base = char_split(lowertext(text)) var/list/out = list() for(var/a in base) if(a in (letters|numerals)) out += a - return jointext(out, null) + return jointext(out,"") /obj/item/toy/crayon/Topic(href, href_list, hsrc) var/temp = "a" diff --git a/code/game/objects/items/weapons/holy_weapons.dm b/code/game/objects/items/weapons/holy_weapons.dm new file mode 100644 index 00000000000..4afec1a157d --- /dev/null +++ b/code/game/objects/items/weapons/holy_weapons.dm @@ -0,0 +1,207 @@ +/obj/item/weapon/nullrod + name = "null rod" + desc = "A rod of pure obsidian, its very presence disrupts and dampens the powers of Nar-Sie's followers." + icon_state = "nullrod" + item_state = "nullrod" + force = 18 + throw_speed = 3 + throw_range = 4 + throwforce = 10 + w_class = 1 + var/reskinned = FALSE + +/obj/item/weapon/nullrod/suicide_act(mob/user) + user.visible_message("[user] is killing \himself with \the [src.name]! It looks like \he's trying get closer to god!") + return (BRUTELOSS|FIRELOSS) + +/obj/item/weapon/nullrod/attack_self(mob/user) + if(reskinned) + return + if(user.mind && (user.mind.assigned_role == "Chaplain")) + reskin_holy_weapon(user) + +/obj/item/weapon/nullrod/proc/reskin_holy_weapon(mob/M) + var/list/holy_weapons_list = typesof(/obj/item/weapon/nullrod) + var/list/display_names = list() + for(var/V in holy_weapons_list) + var/atom/A = V + display_names += initial(A.name) + + var/choice = input(M,"What theme would you like for your holy weapon?","Holy Weapon Theme") as null|anything in display_names + if(!src || !choice || M.stat || !in_range(M, src) || M.restrained() || !M.canmove || reskinned) + return + + var/index = display_names.Find(choice) + var/A = holy_weapons_list[index] + + var/obj/item/weapon/nullrod/holy_weapon = new A + + feedback_set_details("chaplain_weapon","[choice]") + + if(holy_weapon) + holy_weapon.reskinned = TRUE + M.unEquip(src) + M.put_in_active_hand(holy_weapon) + qdel(src) + +/obj/item/weapon/nullrod/godhand + icon_state = "disintegrate" + item_state = "disintegrate" + name = "god hand" + desc = "This hand of yours glows with an awesome power!" + flags = ABSTRACT | NODROP + w_class = 5 + hitsound = 'sound/weapons/sear.ogg' + damtype = BURN + attack_verb = list("punched", "cross countered", "pummeled") + +/obj/item/weapon/nullrod/staff + icon_state = "godstaff-red" + item_state = "godstaff-red" + name = "red holy staff" + desc = "It has a mysterious, protective aura." + w_class = 5 + force = 5 + slot_flags = SLOT_BACK + block_chance = 50 + var/shield_icon = "shield-red" + +/obj/item/weapon/nullrod/staff/worn_overlays(isinhands) + . = list() + if(isinhands) + . += image(icon = 'icons/effects/effects.dmi', icon_state = "[shield_icon]") + +/obj/item/weapon/nullrod/staff/blue + name = "blue holy staff" + icon_state = "godstaff-blue" + item_state = "godstaff-blue" + shield_icon = "shield-old" + +/obj/item/weapon/nullrod/claymore + icon_state = "claymore" + item_state = "claymore" + name = "holy claymore" + desc = "A weapon fit for a crusade!" + w_class = 5 + slot_flags = SLOT_BACK|SLOT_BELT + block_chance = 30 + sharpness = IS_SHARP + hitsound = 'sound/weapons/bladeslice.ogg' + attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") + + +/obj/item/weapon/nullrod/claymore/hit_reaction(mob/living/carbon/human/owner, attack_text, final_block_chance, damage, attack_type) + if(attack_type == PROJECTILE_ATTACK) + final_block_chance = 0 //Don't bring a sword to a gunfight + return ..() + + +/obj/item/weapon/nullrod/claymore/darkblade + icon_state = "cultblade" + item_state = "cultblade" + name = "dark blade" + desc = "Spread the glory of the dark gods!" + slot_flags = SLOT_BELT + hitsound = 'sound/hallucinations/growl1.ogg' + +/obj/item/weapon/nullrod/sord + name = "\improper UNREAL SORD" + desc = "This thing is so unspeakably HOLY you are having a hard time even holding it." + icon_state = "sord" + item_state = "sord" + slot_flags = SLOT_BELT + force = 2 + throwforce = 1 + hitsound = 'sound/weapons/bladeslice.ogg' + attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") + +/obj/item/weapon/nullrod/scythe + icon_state = "scythe0" + name = "reaper scythe" + desc = "Ask not for whom the bell tolls..." + w_class = 4 + armour_penetration = 100 + slot_flags = SLOT_BACK + sharpness = IS_SHARP + attack_verb = list("chopped", "sliced", "cut", "reaped") + +/obj/item/weapon/nullrod/chainsaw + name = "chainsaw hand" + desc = "Good? Bad? You're the guy with the chainsaw hand." + icon_state = "chainsaw_on" + item_state = "mounted_chainsaw" + w_class = 5 + flags = NODROP | ABSTRACT + sharpness = IS_SHARP + attack_verb = list("sawed", "torn", "cut", "chopped", "diced") + hitsound = 'sound/weapons/chainsawhit.ogg' + +/obj/item/weapon/nullrod/clown + icon = 'icons/obj/wizard.dmi' + icon_state = "honkrender" + item_state = "render" + name = "clown dagger" + desc = "Used for absolutely hilarious sacrafices." + hitsound = 'sound/items/bikehorn.ogg' + sharpness = IS_SHARP + attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") + +/obj/item/weapon/nullrod/whip + name = "holy whip" + desc = "What a terrible night to be on Space Station 13." + icon_state = "chain" + item_state = "chain" + slot_flags = SLOT_BELT + attack_verb = list("whipped", "lashed") + +/obj/item/weapon/nullrod/whip/afterattack(atom/movable/AM, mob/user, proximity) + if(!proximity) + return + if(istype(AM, /mob/living/carbon/human)) + var/mob/living/carbon/human/H = AM + if(is_shadow(H)) + var/phrase = pick("Die monster! You don't belong in this world!!!", "You steal men's souls and make them your slaves!!!", "Your words are as empty as your soul!!!", "Mankind ill needs a savior such as you!!!") + user.say("[phrase]") + H.adjustBruteLoss(8) //Bonus damage + +/obj/item/weapon/nullrod/fedora + name = "athiest's fedora" + desc = "The brim of the hat is as sharp as your wit. Throwing it at someone would hurt almost as much as disproving the existence of God." + icon_state = "fedora" + item_state = "fedora" + slot_flags = SLOT_HEAD + icon = 'icons/obj/clothing/hats.dmi' + force = 0 + throw_speed = 4 + throw_range = 7 + throwforce = 20 + +/obj/item/weapon/nullrod/armblade + name = "dark blessing" + desc = "Particularly twisted dieties grant gifts of dubious value." + icon_state = "arm_blade" + item_state = "arm_blade" + flags = ABSTRACT | NODROP + w_class = 5 + sharpness = IS_SHARP + +/obj/item/weapon/nullrod/carp + name = "carp-sie plushie" + desc = "An adorable stuffed toy that resembles the god of all carp. The teeth look pretty sharp. Activate it to recieve the blessing of Carp-Sie." + icon = 'icons/obj/toy.dmi' + icon_state = "carpplushie" + item_state = "carp_plushie" + force = 15 + attack_verb = list("bitten", "eaten", "fin slapped") + hitsound = 'sound/weapons/bite.ogg' + var/used_blessing = FALSE + + +/obj/item/weapon/nullrod/carp/attack_self(mob/living/user) + if(used_blessing) + return + if(user.mind && (user.mind.assigned_role != "Chaplain")) + return + user << "You are blessed by Carp-Sie. Wild space carp will no longer attack you." + user.faction |= "carp" + used_blessing = TRUE \ No newline at end of file diff --git a/code/game/objects/items/weapons/storage/backpack.dm b/code/game/objects/items/weapons/storage/backpack.dm index 3f813d7bba0..8cbf3b4aa9a 100644 --- a/code/game/objects/items/weapons/storage/backpack.dm +++ b/code/game/objects/items/weapons/storage/backpack.dm @@ -488,3 +488,10 @@ new /obj/item/ammo_box/foambox/riot(src) new /obj/item/weapon/grenade/chem_grenade/bioterrorfoam(src) return + +/obj/item/weapon/storage/backpack/dufflebag/syndie/c4/New() + ..() + contents = list() + for(var/i in 1 to 10) + new /obj/item/weapon/c4(src) + return diff --git a/code/game/objects/items/weapons/storage/belt.dm b/code/game/objects/items/weapons/storage/belt.dm index db6b4701830..f04f3e31090 100644 --- a/code/game/objects/items/weapons/storage/belt.dm +++ b/code/game/objects/items/weapons/storage/belt.dm @@ -185,7 +185,8 @@ /obj/item/device/flashlight, /obj/item/weapon/reagent_containers/spray, /obj/item/weapon/soap, - /obj/item/weapon/holosign_creator + /obj/item/weapon/holosign_creator, + /obj/item/key/janitor ) /obj/item/weapon/storage/belt/bandolier diff --git a/code/game/objects/items/weapons/tanks/jetpack.dm b/code/game/objects/items/weapons/tanks/jetpack.dm index fea4e6db9fc..76bf8a97fe2 100644 --- a/code/game/objects/items/weapons/tanks/jetpack.dm +++ b/code/game/objects/items/weapons/tanks/jetpack.dm @@ -1,69 +1,105 @@ +/datum/action/item_action/jetpack/cycle + name = "Jetpack Mode" + +/datum/action/item_action/jetpack/cycle/Trigger() + if(!Checks()) + return + + var/obj/item/weapon/tank/jetpack/J = target + J.cycle(owner) + return 1 + +/datum/action/item_action/jetpack/cycle/suit + name = "Internal Jetpack Mode" + +/datum/action/item_action/jetpack/cycle/suit/New() + ..() + check_flags &= ~AB_CHECK_INSIDE // The jetpack is inside the suit. + +/datum/action/item_action/jetpack/cycle/suit/CheckRemoval(mob/living/user) + return !(target.loc in user) // Check that the suit is on the user. + +/datum/action/item_action/jetpack/cycle/suit/IsAvailable() + var/mob/living/carbon/human/H = owner + if(!H.wear_suit) + return + return ..() + /obj/item/weapon/tank/jetpack name = "jetpack (empty)" desc = "A tank of compressed gas for use as propulsion in zero-gravity areas. Use with caution." icon_state = "jetpack" - w_class = 4 item_state = "jetpack" + w_class = 4 distribute_pressure = ONE_ATMOSPHERE * O2STANDARD - action_button_name = "Toggle Jetpack" - var/datum/effect_system/trail_follow/ion/ion_trail + var/gas_type = "o2" var/on = 0 var/stabilization_on = 0 - var/volume_rate = 500 //Needed for borg jetpack transfer + + var/datum/effect_system/trail_follow/ion/ion_trail + + var/datum/action/item_action/jetpack/cycle/cycle_action + var/cycle_action_type = /datum/action/item_action/jetpack/cycle /obj/item/weapon/tank/jetpack/New() ..() - ion_trail = new /datum/effect_system/trail_follow/ion() + air_contents.assert_gas(gas_type) + air_contents.gases[gas_type][MOLES] = (6 * ONE_ATMOSPHERE) * volume / (R_IDEAL_GAS_EQUATION * T20C) + + ion_trail = new ion_trail.set_up(src) + cycle_action = new cycle_action_type(src) -/obj/item/weapon/tank/jetpack/verb/toggle_rockets() - set name = "Toggle Jetpack Stabilization" - set category = "Object" - if(usr.stat || !usr.canmove || usr.restrained()) +/obj/item/weapon/tank/jetpack/pickup(mob/user) + ..() + cycle_action.Grant(user) + +/obj/item/weapon/tank/jetpack/dropped(mob/user) + ..() + cycle_action.Remove(user) + +/obj/item/weapon/tank/jetpack/proc/cycle(mob/user) + if(user.incapacitated()) return - src.stabilization_on = !( src.stabilization_on ) - usr << "You toggle the stabilization [stabilization_on? "on":"off"]." - return + if(!on && !stabilization_on) + turn_on() + user << "You turn the thrusters on." + else if(on && !stabilization_on) + stabilization_on = TRUE + user << "You turn the stabilizers on." + else if(on && stabilization_on) + turn_off() + stabilization_on = FALSE + user << "You turn the thrusters and stabilizers off." -/obj/item/weapon/tank/jetpack/verb/toggle() - set name = "Toggle Jetpack" - set category = "Object" - if(usr.stat || !usr.canmove || usr.restrained()) - return - on = !on - if(on) - icon_state = "[icon_state]-on" - // item_state = "[item_state]-on" - ion_trail.start() - else - icon_state = initial(icon_state) - // item_state = initial(item_state) - ion_trail.stop() - usr << "You toggle the jetpack [on? "on":"off"]." - return +/obj/item/weapon/tank/jetpack/proc/turn_on() + on = TRUE + icon_state = "[initial(icon_state)]-on" + ion_trail.start() +/obj/item/weapon/tank/jetpack/proc/turn_off() + on = FALSE + icon_state = initial(icon_state) + ion_trail.stop() /obj/item/weapon/tank/jetpack/proc/allow_thrust(num, mob/living/user) - if(!(src.on)) - return 0 - if((num < 0.005 || src.air_contents.total_moles() < num)) - src.ion_trail.stop() - return 0 + if(!on) + return + if((num < 0.005 || air_contents.total_moles() < num)) + turn_off() + return - var/datum/gas_mixture/G = src.air_contents.remove(num) + var/datum/gas_mixture/removed = air_contents.remove(num) + if(removed.total_moles() < 0.005) + turn_off() + return - var/allgases = G.total_moles() - if(allgases >= 0.005) - return 1 - - qdel(G) - return - -/obj/item/weapon/tank/jetpack/ui_action_click() - toggle() + var/turf/T = get_turf(user) + T.assume_air(removed) + return 1 /obj/item/weapon/tank/jetpack/void name = "void jetpack (oxygen)" @@ -71,23 +107,12 @@ icon_state = "jetpack-void" item_state = "jetpack-void" -/obj/item/weapon/tank/jetpack/void/New() - ..() - air_contents.assert_gas("o2") - air_contents.gases["o2"][MOLES] = (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) - - /obj/item/weapon/tank/jetpack/oxygen name = "jetpack (oxygen)" desc = "A tank of compressed oxygen for use as propulsion in zero-gravity areas. Use with caution." icon_state = "jetpack" item_state = "jetpack" -/obj/item/weapon/tank/jetpack/oxygen/New() - ..() - air_contents.assert_gas("o2") - air_contents.gases["o2"][MOLES] = (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) - /obj/item/weapon/tank/jetpack/oxygen/harness name = "jet harness (oxygen)" desc = "A lightweight tactical harness, used by those who don't want to be weighed down by traditional jetpacks." @@ -108,17 +133,10 @@ /obj/item/weapon/tank/jetpack/carbondioxide name = "jetpack (carbon dioxide)" desc = "A tank of compressed carbon dioxide for use as propulsion in zero-gravity areas. Painted black to indicate that it should not be used as a source for internals." - distribute_pressure = 0 icon_state = "jetpack-black" item_state = "jetpack-black" - -/obj/item/weapon/tank/jetpack/carbondioxide/New() - ..() - ion_trail = new /datum/effect_system/trail_follow/ion() - ion_trail.set_up(src) - air_contents.assert_gas("co2") - air_contents.gases["co2"][MOLES] = (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) - + distribute_pressure = 0 + gas_type = "co2" /obj/item/weapon/tank/jetpack/suit name = "suit inbuilt jetpack" @@ -126,51 +144,37 @@ icon_state = "jetpack-void" item_state = "jetpack-void" var/obj/item/weapon/tank/internals/tank = null - action_button_name = "Toggle Jetpack" - action_button_internal = 1 + cycle_action_type = /datum/action/item_action/jetpack/cycle/suit /obj/item/weapon/tank/jetpack/suit/New() ..() SSobj.processing -= src air_contents = null -/obj/item/weapon/tank/jetpack/suit/toggle() - set name = "Toggle Jetpack" - set category = "Object" +/obj/item/weapon/tank/jetpack/suit/cycle(mob/user) + var/mob/living/carbon/human/H = user + if(!istype(H.s_store, /obj/item/weapon/tank/internals)) + user << "You need a tank in your suit storage!" + return + ..() - if(istype(loc.loc,/mob/living/carbon/human)) - var/mob/living/carbon/human/H = loc.loc +/obj/item/weapon/tank/jetpack/suit/turn_on() + if(!ishuman(loc.loc)) + return + var/mob/living/carbon/human/H = loc.loc + tank = H.s_store + air_contents = tank.air_contents + SSobj.processing |= src + ..() - if(!H.wear_suit) - H << "You must be wearing the suit to use the inbuilt jetpack!" - return - if(!istype(H.s_store,/obj/item/weapon/tank/internals)) - H << "You must have a tank in your suit's storage to use the inbuilt jetpack!" - return - if(usr.stat || !usr.canmove || usr.restrained()) - return - - on = !on - if(on) - ion_trail.start() - tank = H.s_store - air_contents = tank.air_contents - SSobj.processing |= src - icon_state = "[icon_state]-on" - else - turn_off() - H << "You toggle the inbuilt jetpack [on? "on":"off"]." - -/obj/item/weapon/tank/jetpack/suit/proc/turn_off() - on = 0 - SSobj.processing -= src - ion_trail.stop() - air_contents = null +/obj/item/weapon/tank/jetpack/suit/turn_off() tank = null - icon_state = initial(icon_state) + air_contents = null + SSobj.processing -= src + ..() /obj/item/weapon/tank/jetpack/suit/process() - if(!istype(loc.loc,/mob/living/carbon/human)) + if(!ishuman(loc.loc)) turn_off() return var/mob/living/carbon/human/H = loc.loc diff --git a/code/game/objects/items/weapons/tanks/tanks.dm b/code/game/objects/items/weapons/tanks/tanks.dm index 1f79d8c98d9..2eb9fbb2904 100644 --- a/code/game/objects/items/weapons/tanks/tanks.dm +++ b/code/game/objects/items/weapons/tanks/tanks.dm @@ -1,3 +1,30 @@ +/datum/action/item_action/tank/internals + name = "Set Internals" + +/datum/action/item_action/tank/internals/Trigger() + if(!Checks()) + return + + var/mob/living/carbon/human/C = owner + if(!istype(C)) + return + + if(C.internal == target) + C.internal = null + C << "You close \the [target] valve." + C.update_internals_hud_icon(0) + else if(C.wear_mask && (C.wear_mask.flags & MASKINTERNALS)) + C.internal = target + C << "You open \the [target] valve." + C.update_internals_hud_icon(1) + return 1 + +/datum/action/item_action/tank/internals/IsAvailable() + var/mob/living/carbon/C = owner + if(!C.wear_mask || !(C.wear_mask.flags & MASKINTERNALS)) + return + return ..() + /obj/item/weapon/tank name = "tank" icon = 'icons/obj/tank.dmi' @@ -5,7 +32,7 @@ slot_flags = SLOT_BACK hitsound = 'sound/weapons/smash.ogg' - pressure_resistance = ONE_ATMOSPHERE*5 + pressure_resistance = ONE_ATMOSPHERE * 5 force = 5 throwforce = 10 @@ -17,48 +44,39 @@ var/integrity = 3 var/volume = 70 -/obj/item/weapon/tank/suicide_act(mob/user) - var/mob/living/carbon/human/H = user - user.visible_message("[user] is putting the [src]'s valve to their lips! I don't think they're gonna stop!") - playsound(loc, 'sound/effects/spray.ogg', 10, 1, -3) - if (H && !qdeleted(H)) - for(var/obj/item/W in H) - H.unEquip(W) - if(prob(50)) - step(W, pick(alldirs)) - H.hair_style = "Bald" - H.update_hair() - H.blood_max = 5 - gibs(H.loc, H.viruses, H.dna) - H.adjustBruteLoss(1000) //to make the body super-bloody - - return (BRUTELOSS) + var/datum/action/item_action/tank/internals/internals_action /obj/item/weapon/tank/New() ..() - src.air_contents = new /datum/gas_mixture() - src.air_contents.volume = volume //liters - src.air_contents.temperature = T20C + air_contents = new(volume) //liters + air_contents.temperature = T20C + + internals_action = new(src) SSobj.processing |= src - return - /obj/item/weapon/tank/Destroy() if(air_contents) qdel(air_contents) - SSobj.processing.Remove(src) - + SSobj.processing -= src return ..() +/obj/item/weapon/tank/pickup(mob/user) + ..() + internals_action.Grant(user) + +/obj/item/weapon/tank/dropped(mob/user) + ..() + internals_action.Remove(user) + /obj/item/weapon/tank/examine(mob/user) var/obj/icon = src ..() if (istype(src.loc, /obj/item/assembly)) icon = src.loc - if (!in_range(src, user)) + if(!in_range(src, user)) if (icon == src) user << "If you want any more information you'll need to get closer." return @@ -93,14 +111,31 @@ qdel(src) +/obj/item/weapon/tank/suicide_act(mob/user) + var/mob/living/carbon/human/H = user + user.visible_message("[user] is putting the [src]'s valve to their lips! I don't think they're gonna stop!") + playsound(loc, 'sound/effects/spray.ogg', 10, 1, -3) + if (H && !qdeleted(H)) + for(var/obj/item/W in H) + H.unEquip(W) + if(prob(50)) + step(W, pick(alldirs)) + H.hair_style = "Bald" + H.update_hair() + H.blood_max = 5 + gibs(H.loc, H.viruses, H.dna) + H.adjustBruteLoss(1000) //to make the body super-bloody + + return (BRUTELOSS) + /obj/item/weapon/tank/attackby(obj/item/weapon/W, mob/user, params) ..() add_fingerprint(user) - if (istype(src.loc, /obj/item/assembly)) + if(istype(src.loc, /obj/item/assembly)) icon = src.loc - if ((istype(W, /obj/item/device/analyzer)) && get_dist(user, src) <= 1) + if((istype(W, /obj/item/device/analyzer)) && get_dist(user, src) <= 1) atmosanalyzer_scan(air_contents, user) if(istype(W, /obj/item/device/assembly_holder)) @@ -113,7 +148,7 @@ ui = new(user, src, ui_key, "tanks", name, 420, 200, master_ui, state) ui.open() -/obj/item/weapon/tank/ui_data() +/obj/item/weapon/tank/ui_data(mob/user) var/list/data = list() data["tankPressure"] = round(air_contents.return_pressure() ? air_contents.return_pressure() : 0) data["releasePressure"] = round(distribute_pressure ? distribute_pressure : 0) @@ -121,21 +156,14 @@ data["minReleasePressure"] = round(TANK_MIN_RELEASE_PRESSURE) data["maxReleasePressure"] = round(TANK_MAX_RELEASE_PRESSURE) - var/mob/living/carbon/user = null - if(istype(loc, /mob/living/carbon)) - user = loc - else if(istype(loc.loc, /mob/living/carbon)) - user = loc.loc - - data["valveOpen"] = FALSE - data["maskConnected"] = FALSE - if(!istype(user)) + var/mob/living/carbon/C = user + if(!istype(C)) + C = loc.loc + if(!istype(C)) return data - if(user.internal == src) - data["valveOpen"] = TRUE - if(user.wear_mask && (user.wear_mask.flags & MASKINTERNALS) && user.internal == src) - data["maskConnected"] = TRUE + if(C.internal == src) + data["connected"] = TRUE return data @@ -163,24 +191,6 @@ . = TRUE if(.) distribute_pressure = Clamp(round(pressure), TANK_MIN_RELEASE_PRESSURE, TANK_MAX_RELEASE_PRESSURE) - if("valve") - var/mob/living/carbon/user = loc - if(!istype(user)) - return - if(user.internal == src) - user.internal = null - user << "You close the tank release valve." - user.update_internals_hud_icon(0) - . = TRUE - else - if(user.wear_mask && (user.wear_mask.flags & MASKINTERNALS)) - user.internal = src - user << "You open \the [src] valve." - user.update_internals_hud_icon(1) - . = TRUE - else - user << "You need something to connect to [src]!" - /obj/item/weapon/tank/remove_air(amount) return air_contents.remove(amount) diff --git a/code/game/objects/items/weapons/weaponry.dm b/code/game/objects/items/weapons/weaponry.dm index 910c3dfc84a..60dadbe2fa0 100644 --- a/code/game/objects/items/weapons/weaponry.dm +++ b/code/game/objects/items/weapons/weaponry.dm @@ -1,3 +1,5 @@ + + /obj/item/weapon/banhammer desc = "A banhammer" name = "banhammer" @@ -19,23 +21,6 @@ user << "You have BANNED [M]" playsound(loc, 'sound/effects/adminhelp.ogg', 15) //keep it at 15% volume so people don't jump out of their skin too much - -/obj/item/weapon/nullrod - name = "null rod" - desc = "A rod of pure obsidian, its very presence disrupts and dampens the powers of Nar-Sie's followers." - icon_state = "nullrod" - item_state = "nullrod" - slot_flags = SLOT_BELT - force = 15 - throw_speed = 3 - throw_range = 4 - throwforce = 10 - w_class = 1 - -/obj/item/weapon/nullrod/suicide_act(mob/user) - user.visible_message("[user] is impaling \himself with the [src.name]! It looks like \he's trying to commit suicide.") - return (BRUTELOSS|FIRELOSS) - /obj/item/weapon/sord name = "\improper SORD" desc = "This thing is so unspeakably shitty you are having a hard time even holding it." @@ -307,3 +292,4 @@ icon_state = "tailwhip" origin_tech = "combat=1" needs_permit = 0 + diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index 553d4a9ba01..0f038cc0e7c 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -198,8 +198,12 @@ being_shocked = 1 var/power_bounced = power / 2 tesla_zap(src, 3, power_bounced) - spawn(10) - being_shocked = 0 + addtimer(src, "reset_shocked", 10) + +/obj/proc/reset_shocked() + being_shocked = 0 /obj/proc/CanAStarPass() - . = !density + . = !density + + diff --git a/code/game/objects/structures/crates_lockers/bins.dm b/code/game/objects/structures/crates_lockers/bins.dm deleted file mode 100644 index 7bece78a795..00000000000 --- a/code/game/objects/structures/crates_lockers/bins.dm +++ /dev/null @@ -1,87 +0,0 @@ -/obj/structure/closet/crate/bin - desc = "A trash bin, place your trash here for the janitor to collect." - name = "trash bin" - icon_crate = "largebins" - icon_state = "largebins" - anchored = 1 - sound_effect_open = 'sound/effects/bin_open.ogg' - sound_effect_close = 'sound/effects/bin_close.ogg' - var/animation = "animate_largebins" - var/redlight = "largebinr" - var/greenlight = "largebing" - var/orangelight = "largebino" - -/obj/structure/closet/crate/bin/New() - ..() - update_icon() - -/obj/structure/closet/crate/bin/update_icon() - ..() - overlays.Cut() - if(contents.len == 0) - overlays += greenlight - else if(contents.len >= storage_capacity) - overlays += redlight - else - overlays += orangelight - -/obj/structure/closet/crate/bin/attackby(obj/item/weapon/W, mob/user, params) - if(istype(W, /obj/item/weapon/storage/bag/trash)) - var/obj/item/weapon/storage/bag/trash/T = W - user << "You fill the bag." - for(var/obj/item/O in src) - if(T.can_be_inserted(O, 1)) - O.loc = T - T.update_icon() - do_animate() - else if(istype(W, /obj/item/weapon/wrench)) - anchored = !anchored - playsound(src.loc, 'sound/items/Ratchet.ogg', 75, 1) - else - ..() - -/obj/structure/closet/crate/bin/MouseDrop_T(atom/movable/O as mob|obj, mob/user) - . = ..(O, user, 0, 0, 0) - if(.) - if(O != user) - user.visible_message("[user] tries to stuff [O] into [src].", \ - "You try to stuff [O] into [src].", \ - "You hear clanging.") - if (!do_after(user, 40, target = src)) - return - if(!..(O, user, 0, 0)) - return - user.visible_message("[user] stuffs [O] into[src].", \ - "You stuff [O] into [src].", \ - "You hear a loud metal bang.") - insert(O, 1, !opened) - if(opened) - close() - -/obj/structure/closet/crate/bin/open() - . = ..() - update_icon() - -/obj/structure/closet/crate/bin/close() - . = ..() - update_icon() - -/obj/structure/closet/crate/bin/proc/do_animate() - playsound(src.loc, sound_effect_open, 15, 1, -3) - flick(animation, src) - spawn(13) - playsound(src.loc, sound_effect_close, 15, 1, -3) - update_icon() - -/obj/structure/closet/crate/bin/insert(obj/item/I, include_mobs = 0, animate = 0) - . = ..(I, include_mobs) - if(animate && .) - do_animate() - -/obj/structure/closet/crate/bin/place(mob/user, obj/item/I) - if(contents.len >= storage_capacity) - return 1 - if(!opened && user.drop_item()) - insert(I, 0, 1) - return 1 - return 0 \ No newline at end of file diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm index 41c94f82650..97685abc4a7 100644 --- a/code/game/objects/structures/crates_lockers/closets.dm +++ b/code/game/objects/structures/crates_lockers/closets.dm @@ -5,22 +5,27 @@ icon_state = "generic" density = 1 var/icon_door = null - var/icon_door_override = 0 //override to have open overlay use icon different to its base's - var/secure = 0 //secure locker or not, also used if overriding a non-secure locker with a secure door overlay to add fancy lights - var/opened = 0 - var/welded = 0 - var/locked = 0 - var/broken = 0 - var/large = 1 + var/icon_door_override = FALSE //override to have open overlay use icon different to its base's + var/secure = FALSE //secure locker or not, also used if overriding a non-secure locker with a secure door overlay to add fancy lights + var/opened = FALSE + var/welded = FALSE + var/locked = FALSE + var/broken = FALSE + var/large = TRUE var/wall_mounted = 0 //never solid (You can always pass over it) var/health = 100 + var/breakout_time = 2 var/lastbang - var/can_weld_shut = 1 + var/can_weld_shut = TRUE + var/horizontal = FALSE + var/allow_objects = FALSE + var/allow_dense = FALSE var/max_mob_size = MOB_SIZE_HUMAN //Biggest mob_size accepted by the container var/mob_storage_capacity = 3 // how many human sized mob/living can fit together inside a closet. var/storage_capacity = 30 //This is so that someone can't pack hundreds of items in a locker/crate then open it in a populated area to crash clients. var/cutting_tool = /obj/item/weapon/weldingtool var/open_sound = 'sound/machines/click.ogg' + var/close_sound = 'sound/machines/click.ogg' var/cutting_sound = 'sound/items/Welder.ogg' var/material_drop = /obj/item/stack/sheet/metal @@ -63,18 +68,18 @@ /obj/structure/closet/examine(mob/user) ..() - if(secure) - if(broken || opened || !ishuman(user)) - return //Monkeys don't get a message, nor does anyone if it's open or emagged - else - user << "Alt-click the locker to [locked ? "unlock" : "lock"] it." + if(broken) + user << "It appears to be broken." + else if(secure && !opened) + user << "Alt-click to [locked ? "unlock" : "lock"]." /obj/structure/closet/alter_health() return get_turf(src) /obj/structure/closet/CanPass(atom/movable/mover, turf/target, height=0) - if(height==0 || wall_mounted) return 1 - return (!density) + if(height == 0 || wall_mounted) + return 1 + return !density /obj/structure/closet/proc/can_open() if(welded || locked) @@ -88,72 +93,70 @@ return 1 /obj/structure/closet/proc/dump_contents() - for(var/obj/O in src) - O.loc = loc - if(throwing) //you keep some momentum when getting out of a thrown closet - step(O, dir) - - for(var/mob/M in src) - M.loc = loc - M.reset_perspective(null) - if(throwing) - step(M, dir) + var/turf/T = get_turf(src) + for(var/atom/movable/AM in src) + AM.forceMove(T) + if(throwing) // you keep some momentum when getting out of a thrown closet + step(AM, dir) if(throwing) throwing = 0 /obj/structure/closet/proc/take_contents() - - for(var/atom/movable/AM in loc) + var/turf/T = get_turf(src) + for(var/atom/movable/AM in T) if(insert(AM) == -1) // limit reached break /obj/structure/closet/proc/open() if(opened || !can_open()) - return 0 - opened = 1 + return playsound(loc, open_sound, 15, 1, -3) + opened = 1 density = 0 dump_contents() update_icon() return 1 /obj/structure/closet/proc/insert(atom/movable/AM) - if(contents.len >= storage_capacity) return -1 - if(istype(AM, /mob/living)) - var/mob/living/L = AM - if(L.buckled || L.buckled_mob || L.mob_size > max_mob_size) //buckled mobs, mobs with another mob attached, and mobs too big for the container don't get inside closets. - return 0 - if(L.mob_size > MOB_SIZE_TINY) //decently sized mobs take more space than objects. + var/mob/living/L = AM + if(istype(L)) + if(L.buckled || L.buckled_mob) + return + if(L.mob_size > MOB_SIZE_TINY) // Tiny mobs are treated as items. + if(horizontal && !L.lying) + return + if(L.mob_size > max_mob_size) + return var/mobs_stored = 0 for(var/mob/living/M in contents) - mobs_stored++ - if(mobs_stored >= mob_storage_capacity) - return 0 - L.reset_perspective(src) + if(++mobs_stored >= mob_storage_capacity) + return L.stop_pulling() - else if(!istype(AM, /obj/item) && !istype(AM, /obj/effect/dummy/chameleon)) - return 0 - else if(AM.density || AM.anchored) - return 0 - else if(AM.flags & NODROP) - return 0 - AM.loc = src + else if(istype(AM, /obj/structure/closet)) + return + else if(isobj(AM)) + if(!allow_objects && !istype(AM, /obj/item) && !istype(AM, /obj/effect/dummy/chameleon)) + return + if(!allow_dense && AM.density) + return + if(AM.anchored || AM.buckled_mob || (AM.flags & NODROP)) + return + + AM.forceMove(src) if(AM.pulledby) AM.pulledby.stop_pulling() + return 1 /obj/structure/closet/proc/close() - if(!opened) - return 0 - if(!can_close()) + if(!opened || !can_close()) return 0 take_contents() - + playsound(loc, close_sound, 15, 1, -3) opened = 0 - playsound(loc, open_sound, 15, 1, -3) density = 1 update_icon() return 1 @@ -161,7 +164,8 @@ /obj/structure/closet/proc/toggle() if(opened) return close() - return open() + else + return open() /obj/structure/closet/ex_act(severity, target) contents_explosion(severity, target) @@ -170,13 +174,12 @@ qdel(src) ..() -/obj/structure/closet/bullet_act(obj/item/projectile/Proj) +/obj/structure/closet/bullet_act(obj/item/projectile/P) ..() - if((Proj.damage_type == BRUTE || Proj.damage_type == BURN)) - health -= Proj.damage + if(P.damage_type == BRUTE || P.damage_type == BURN) + health -= P.damage if(health <= 0) qdel(src) - return /obj/structure/closet/attack_animal(mob/living/simple_animal/user) if(user.environment_smash) @@ -188,81 +191,74 @@ if(prob(75)) qdel(src) - /obj/structure/closet/attackby(obj/item/weapon/W, mob/user, params) - if(user.loc == src) + if(user in src) return if(opened) - if(istype(W,/obj/item/tk_grab)) - return 0 if(istype(W, cutting_tool)) if(istype(cutting_tool, /obj/item/weapon/weldingtool)) var/obj/item/weapon/weldingtool/WT = W - if(!WT.remove_fuel(0,user)) + if(!WT.remove_fuel(0, user)) return user << "You begin cutting \the [src] apart..." playsound(loc, cutting_sound, 40, 1) - if(do_after(user,40/W.toolspeed,1, target = src)) - if( !opened || !istype(src, /obj/structure/closet) || !user || !WT || !WT.isOn() || !user.loc ) + if(do_after(user, 40/W.toolspeed, 1, target = src)) + if(!opened || !WT.isOn()) return playsound(loc, cutting_sound, 50, 1) new material_drop(loc) - visible_message("[user] has cut \the [src] apart with \the [WT].", "You hear welding.") + visible_message("[user] slices apart \the [src].", + "You cut \the [src] apart with \the [WT].", + "You hear welding.") qdel(src) - return - if(isrobot(user)) - return - if(user.drop_item()) + else if(user.drop_item()) W.Move(loc) else if(istype(W, /obj/item/stack/packageWrap)) return if(istype(W, /obj/item/weapon/weldingtool) && can_weld_shut) var/obj/item/weapon/weldingtool/WT = W - if(WT.remove_fuel(0,user)) - user << "You begin [welded ? "unwelding":"welding"] \the [src]..." - playsound(loc, 'sound/items/Welder2.ogg', 40, 1) - if(do_after(user,40,1, target = src)) - if(opened || !istype(src, /obj/structure/closet) || !user || !WT || !WT.isOn() || !user.loc ) - return - playsound(loc, 'sound/items/welder.ogg', 50, 1) - welded = !welded - user << "You [welded ? "weld [src] shut":"unweld [src]"]." - update_icon() - user.visible_message("[user.name] has [welded ? "welded [src] shut":"unwelded [src]"].", "You [welded ? "weld [src] shut":"unweld [src]"].") + if(!WT.remove_fuel(0, user)) return - if(secure && broken) - user << "The locker appears to be broken." - return - if(!place(user, W) && !isnull(W)) + user << "You begin [welded ? "unwelding":"welding"] \the [src]..." + playsound(loc, 'sound/items/Welder2.ogg', 40, 1) + if(do_after(user, 40, 1, target = src)) + if(opened || !WT.isOn()) + return + playsound(loc, 'sound/items/welder.ogg', 50, 1) + welded = !welded + visible_message("[user] [welded ? "welds shut" : "unweldeds"] \the [src].", + "You [welded ? "weld" : "unwelded"] \the [src] with \the [WT].", + "You hear welding.") + update_icon() + else attack_hand(user) -/obj/structure/closet/proc/place(mob/user, obj/item/I) - if(!opened && secure) - togglelock(user) - return 1 - return 0 +/obj/structure/closet/MouseDrop_T(atom/movable/O, mob/user) + if(!istype(O) || O.anchored || istype(O, /obj/screen)) + return + if(user.incapacitated() || user.lying) + return + if(!Adjacent(user) || !user.Adjacent(O)) + return + if(!opened || istype(O, /obj/structure/closet)) + return + if(user == O) + return -/obj/structure/closet/MouseDrop_T(atom/movable/O as mob|obj, mob/user, needs_opened = 1, show_message = 1, move_them = 1) - if(istype(O, /obj/screen)) //fix for HUD elements making their way into the world -Pete - return 0 - if(!isturf(O.loc)) - return 0 - if(user.restrained() || user.stat || user.weakened || user.stunned || user.paralysis || user.lying) - return 0 - if((!( istype(O, /atom/movable) ) || O.anchored || get_dist(user, src) > 1 || get_dist(user, O) > 1)) - return 0 - if(!istype(user.loc, /turf)) // are you in a container/closet/pod/etc? Will also check for null loc - return 0 - if(needs_opened && !opened) - return 0 - if(istype(O, /obj/structure/closet)) - return 0 - if(move_them) - step_towards(O, loc) - if(show_message && user != O) - user.show_viewers("[user] stuffs [O] into [src]!") add_fingerprint(user) + user.visible_message("[user] tries to stuff [O] into [src].", \ + "You try to stuff [O] into [src].", \ + "You hear clanging.") + if(do_after(user, 40, target = src)) + user.visible_message("[user] stuffs [O] into [src].", \ + "You stuff [O] into [src].", \ + "You hear a loud metal bang.") + var/mob/living/L = O + if(istype(L)) + L.Weaken(2) + step_towards(O, loc) + close() return 1 /obj/structure/closet/relaymove(mob/user) @@ -275,10 +271,6 @@ for(var/mob/M in get_hearers_in_view(src, null)) M.show_message("BANG, bang!", 2) - -/obj/structure/closet/attack_paw(mob/user) - return attack_hand(user) - /obj/structure/closet/attack_hand(mob/user) add_fingerprint(user) if(user.lying && get_dist(src, user) > 0) @@ -313,34 +305,28 @@ if(AM.loc == src) return 0 return 1 -/obj/structure/closet/container_resist() - var/mob/living/user = usr - var/breakout_time = 2 //2 minutes by default - if(istype(user.loc, /obj/structure/closet/critter) && !welded) - breakout_time = 0.75 //45 seconds if it's an unwelded critter crate - - if( opened || (!welded && !locked && !istype(loc, /obj/mecha)) ) +/obj/structure/closet/container_resist(mob/living/user) + if(opened || (!welded && !locked && !istype(loc, /obj/mecha))) return //Door's open, not locked or welded or inside a mech, no point in resisting. //okay, so the closet is either welded or locked... resist!!! user.changeNext_move(CLICK_CD_BREAKOUT) user.last_special = world.time + CLICK_CD_BREAKOUT - user << "You lean on the back of [src] and start pushing the door open. (this will take about [breakout_time] minutes.)" - for(var/mob/O in viewers(src)) - O << "[src] begins to shake violently!" - if(do_after(user,(breakout_time*60*10), target = src)) //minutes * 60seconds * 10deciseconds + user.visible_message("[src] begins to shake violently!", + "You lean on the back of [src] and start pushing the door open.") + if(do_after(user,(breakout_time * 60 * 10), target = src)) //minutes * 60seconds * 10deciseconds if(!user || user.stat != CONSCIOUS || user.loc != src || opened || (!locked && !welded && !istype(loc, /obj/mecha)) ) return //we check after a while whether there is a point of resisting anymore and whether the user is capable of resisting - welded = 0 //applies to all lockers lockers locked = 0 //applies to critter crates and secure lockers only broken = 1 //applies to secure lockers only - user.visible_message("[user] successfully broke out of [src]!", "You successfully break out of [src]!") - if(istype( loc, /obj/structure/bigDelivery)) + user.visible_message("[user] successfully broke out of [src]!", + "You successfully break out of [src]!") + if(istype(loc, /obj/structure/bigDelivery)) var/obj/structure/bigDelivery/D = loc qdel(D) - else if(istype( loc, /obj/mecha)) + else if(istype(loc, /obj/mecha)) loc = get_turf(loc) open() else @@ -348,7 +334,7 @@ /obj/structure/closet/AltClick(mob/user) ..() - if(!user.canUseTopic(user) || broken) + if(!user.canUseTopic(user)) user << "You can't do that right now!" return if(opened || !secure || !in_range(src, user)) @@ -356,46 +342,44 @@ else togglelock(user) +/obj/structure/closet/proc/togglelock(mob/living/user) + if(secure && !broken) + if(allowed(user)) + add_fingerprint(user) + locked = !locked + user.visible_message("[user] [locked ? null : "un"]locks [src].", + "You [locked ? null : "un"]locks [src].") + update_icon() + else + user << "Access Denied" + else if(secure && broken) + user << "\The [src] is broken!" + +/obj/structure/closet/emag_act(mob/user) + if(secure && !broken) + user.visible_message("Sparks fly from [src]!", + "You scramble [src]'s lock, breaking it open!", + "You hear a faint electrical spark.") + playsound(src.loc, 'sound/effects/sparks4.ogg', 50, 1) + broken = 1 + locked = 0 + update_icon() + +/obj/structure/closet/get_remote_view_fullscreens(mob/user) + if(!(user.sight & (SEEOBJS|SEEMOBS))) + user.overlay_fullscreen("remote_view", /obj/screen/fullscreen/impaired, 1) + /obj/structure/closet/emp_act(severity) for(var/obj/O in src) O.emp_act(severity) if(secure && !broken) - if(prob(50/severity)) + if(prob(50 / severity)) locked = !locked update_icon() - if(prob(20/severity) && !opened) + if(prob(20 / severity) && !opened) if(!locked) open() else req_access = list() req_access += pick(get_all_accesses()) ..() - -/obj/structure/closet/proc/togglelock(mob/user) - if(secure) - if(allowed(user)) - locked = !locked - add_fingerprint(user) - for(var/mob/O in viewers(user, 3)) - O.show_message("[user] has [locked ? null : "un"]locked the locker.", 1) - update_icon() - else - user << "Access Denied" - else - return - -/obj/structure/closet/emag_act(mob/user) - if(secure && !broken) - broken = 1 - locked = 0 - desc += " It appears to be broken." - update_icon() - if(user) - visible_message("The [name] has been broken by [user] with an electromagnetic card!", "You hear a faint electrical spark.") - overlays += "sparking" - spawn(4) //overlays don't support flick so we have to cheat - update_icon() - -/obj/structure/closet/get_remote_view_fullscreens(mob/user) - if(!(user.sight & (SEEOBJS|SEEMOBS))) - user.overlay_fullscreen("remote_view", /obj/screen/fullscreen/impaired, 1) diff --git a/code/game/objects/structures/crates_lockers/closets/crittercrate.dm b/code/game/objects/structures/crates_lockers/closets/crittercrate.dm deleted file mode 100644 index d665984dfe2..00000000000 --- a/code/game/objects/structures/crates_lockers/closets/crittercrate.dm +++ /dev/null @@ -1,88 +0,0 @@ -/obj/structure/closet/critter - name = "critter crate" - desc = "A crate designed for safe transport of animals. Only openable from the the outside." - icon_state = "critter" - var/already_opened = 0 - var/content_mob = null - var/amount = 1 - -/obj/structure/closet/critter/can_open() - if(locked || welded) - return 0 - return 1 - -/obj/structure/closet/critter/open() - if(!can_open()) - return 0 - - if(content_mob == null) //making sure we don't spawn anything too eldritch - already_opened = 1 - return ..() - - if(content_mob != null && already_opened == 0) - for(var/i = 1, i <= amount, i++) - new content_mob(loc) - already_opened = 1 - ..() - -/obj/structure/closet/critter/close() - ..() - locked = 1 - return 1 - -/obj/structure/closet/critter/attack_hand(mob/user) - src.add_fingerprint(user) - - if(src.loc == user.loc) - user << "It won't budge!" - toggle() - else - locked = 0 - toggle() - -/obj/structure/closet/critter/corgi - name = "corgi crate" - content_mob = /mob/living/simple_animal/pet/dog/corgi - -/obj/structure/closet/critter/corgi/New() - if(prob(50)) - content_mob = /mob/living/simple_animal/pet/dog/corgi/Lisa - ..() - -/obj/structure/closet/critter/cow - name = "cow crate" - content_mob = /mob/living/simple_animal/cow - -/obj/structure/closet/critter/goat - name = "goat crate" - content_mob = /mob/living/simple_animal/hostile/retaliate/goat - -/obj/structure/closet/critter/chick - name = "chicken crate" - content_mob = /mob/living/simple_animal/chick - -/obj/structure/closet/critter/chick/New() - amount = rand(1, 3) - ..() - -/obj/structure/closet/critter/cat - name = "cat crate" - content_mob = /mob/living/simple_animal/pet/cat - -/obj/structure/closet/critter/cat/New() - if(prob(50)) - content_mob = /mob/living/simple_animal/pet/cat/Proc - ..() - -/obj/structure/closet/critter/pug - name = "pug crate" - content_mob = /mob/living/simple_animal/pet/dog/pug - -/obj/structure/closet/critter/fox - name = "fox crate" - content_mob = /mob/living/simple_animal/pet/fox - -/obj/structure/closet/critter/butterfly - name = "butterflies crate" - content_mob = /mob/living/simple_animal/butterfly - amount = 50 \ No newline at end of file diff --git a/code/game/objects/structures/crates_lockers/closets/statue.dm b/code/game/objects/structures/crates_lockers/closets/statue.dm index 45fb2a474a5..f6060f510da 100644 --- a/code/game/objects/structures/crates_lockers/closets/statue.dm +++ b/code/game/objects/structures/crates_lockers/closets/statue.dm @@ -55,9 +55,9 @@ M.adjustFireLoss(intialFire - M.getFireLoss()) M.adjustBruteLoss(intialBrute - M.getBruteLoss()) M.setOxyLoss(intialOxy) - if (timer <= 0) + if(timer <= 0) dump_contents() - SSobj.processing.Remove(src) + SSobj.processing -= src qdel(src) /obj/structure/closet/statue/dump_contents() @@ -129,9 +129,6 @@ for(var/mob/M in src) shatter(M) -/obj/structure/closet/statue/place() - return - /obj/structure/closet/statue/MouseDrop_T() return @@ -148,7 +145,7 @@ return /obj/structure/closet/statue/proc/shatter(mob/user) - if (user) + if(user) user.dust() dump_contents() visible_message("[src] shatters!.") diff --git a/code/game/objects/structures/crates_lockers/crates.dm b/code/game/objects/structures/crates_lockers/crates.dm index e700e03c8cd..8e53bb6f579 100644 --- a/code/game/objects/structures/crates_lockers/crates.dm +++ b/code/game/objects/structures/crates_lockers/crates.dm @@ -1,49 +1,74 @@ -//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32 - /obj/structure/closet/crate name = "crate" desc = "A rectangular steel crate." icon = 'icons/obj/crates.dmi' - var/icon_crate = "crate" icon_state = "crate" req_access = null - var/rigged = 0 - var/sound_effect_open = 'sound/machines/click.ogg' - var/sound_effect_close = 'sound/machines/click.ogg' + can_weld_shut = FALSE + horizontal = TRUE + allow_objects = TRUE + allow_dense = TRUE var/obj/item/weapon/paper/manifest/manifest /obj/structure/closet/crate/New() ..() update_icon() - /obj/structure/closet/crate/update_icon() + icon_state = "[initial(icon_state)][opened ? "open" : ""]" + overlays.Cut() - if(opened) - icon_state = "[icon_crate]open" - else - icon_state = icon_crate if(manifest) overlays += "manifest" +/obj/structure/closet/crate/attack_hand(mob/user) + add_fingerprint(user) + if(manifest) + tear_manifest(user) + return + if(!toggle()) + togglelock(user) + +/obj/structure/closet/crate/proc/tear_manifest(mob/user) + user << "You tear the manifest off of the crate." + playsound(src, 'sound/items/poster_ripped.ogg', 75, 1) + + manifest.loc = loc + if(ishuman(user)) + user.put_in_hands(manifest) + manifest = null + update_icon() + /obj/structure/closet/crate/internals desc = "A internals crate." name = "internals crate" - icon_crate = "o2crate" icon_state = "o2crate" /obj/structure/closet/crate/trashcart desc = "A heavy, metal trashcart with wheels." name = "trash cart" - icon_crate = "trashcart" icon_state = "trashcart" /obj/structure/closet/crate/medical desc = "A medical crate." name = "medical crate" - icon_crate = "medicalcrate" icon_state = "medicalcrate" +/obj/structure/closet/crate/freezer + desc = "A freezer." + name = "freezer" + icon_state = "freezer" + +/obj/structure/closet/crate/radiation + desc = "A crate with a radiation sign on it." + name = "radiation crate" + icon_state = "radiation" + +/obj/structure/closet/crate/hydroponics + name = "hydroponics crate" + desc = "All you need to destroy those pesky weeds and pests." + icon_state = "hydrocrate" + /obj/structure/closet/crate/rcd desc = "A crate for the storage of an RCD." name = "\improper RCD crate" @@ -53,265 +78,3 @@ for(var/i in 1 to 4) new /obj/item/weapon/rcd_ammo(src) new /obj/item/weapon/rcd(src) - -/obj/structure/closet/crate/freezer - desc = "A freezer." - name = "freezer" - icon_crate = "freezer" - icon_state = "freezer" - var/target_temp = T0C - 40 - var/cooling_power = 40 - -/obj/structure/closet/crate/freezer/return_air() - var/datum/gas_mixture/gas = (..()) - if(!gas) - return null - - var/datum/gas_mixture/newgas = new/datum/gas_mixture() - newgas.copy_from(gas) - - if(newgas.temperature <= target_temp) - return - - if((newgas.temperature - cooling_power) > target_temp) - newgas.temperature -= cooling_power - else - newgas.temperature = target_temp - return newgas - - -/obj/structure/closet/crate/radiation - desc = "A crate with a radiation sign on it." - name = "radioactive gear crate" - icon_crate = "radiation" - icon_state = "radiation" - -/obj/structure/closet/crate/radiation/New() - ..() - for(var/i in 1 to 4) - new /obj/item/clothing/suit/radiation(src) - new /obj/item/clothing/head/radiation(src) - -/obj/structure/closet/crate/hydroponics - name = "hydroponics crate" - desc = "All you need to destroy those pesky weeds and pests." - icon_crate = "hydrocrate" - icon_state = "hydrocrate" - -/obj/structure/closet/crate/hydroponics/prespawned - -/obj/structure/closet/crate/hydroponics/prespawned/New() - ..() - new /obj/item/weapon/reagent_containers/spray/plantbgone(src) - new /obj/item/weapon/reagent_containers/spray/plantbgone(src) - new /obj/item/weapon/cultivator(src) - -/obj/structure/closet/crate/secure - desc = "A secure crate." - name = "secure crate" - icon_crate = "securecrate" - icon_state = "securecrate" - var/redlight = "securecrater" - var/greenlight = "securecrateg" - var/sparks = "securecratesparks" - var/emag = "securecrateemag" - locked = 1 - health = 1000 - -/obj/structure/closet/crate/secure/weapon - desc = "A secure weapons crate." - name = "weapons crate" - icon_crate = "weaponcrate" - icon_state = "weaponcrate" - -/obj/structure/closet/crate/secure/plasma - desc = "A secure plasma crate." - name = "plasma crate" - icon_crate = "plasmacrate" - icon_state = "plasmacrate" - -/obj/structure/closet/crate/secure/gear - desc = "A secure gear crate." - name = "gear crate" - icon_crate = "secgearcrate" - icon_state = "secgearcrate" - -/obj/structure/closet/crate/secure/hydrosec - desc = "A crate with a lock on it, painted in the scheme of the station's botanists." - name = "secure hydroponics crate" - icon_crate = "hydrosecurecrate" - icon_state = "hydrosecurecrate" - -/obj/structure/closet/crate/secure/update_icon() - ..() - if(locked) - overlays += redlight - else if(broken) - overlays += emag - else - overlays += greenlight - -/obj/structure/closet/crate/open() - playsound(src.loc, sound_effect_open, 15, 1, -3) - dump_contents() - src.opened = 1 - update_icon() - return 1 - -/obj/structure/closet/crate/close() - playsound(src.loc, sound_effect_close, 15, 1, -3) - take_contents() - src.opened = 0 - update_icon() - return 1 - -/obj/structure/closet/crate/insert(atom/movable/AM, include_mobs = 0) - - if(contents.len >= storage_capacity) - return -1 - if(include_mobs && isliving(AM)) - var/mob/living/L = AM - if(L.buckled) - return 0 - else if(isobj(AM)) - if(AM.density || AM.anchored || istype(AM,/obj/structure/closet)) - return 0 - else - return 0 - - if(istype(AM, /obj/structure/bed)) //This is only necessary because of rollerbeds and swivel chairs. - var/obj/structure/bed/B = AM - if(B.buckled_mob) - return 0 - - AM.loc = src - return 1 - -/obj/structure/closet/crate/proc/tear_manifest(mob/user) - user << "You tear the manifest off of the crate." - playsound(src.loc, 'sound/items/poster_ripped.ogg', 75, 1) - manifest.loc = loc - if(ishuman(user)) - user.put_in_hands(manifest) - manifest = null - overlays-="manifest" - -/obj/structure/closet/crate/attack_hand(mob/user) - if(manifest) - tear_manifest(user) - return - if(opened) - close() - else - if(rigged && locate(/obj/item/device/electropack) in src) - if(isliving(user)) - var/mob/living/L = user - if(L.electrocute_act(17, src)) - var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread - s.set_up(5, 1, src) - s.start() - return - open() - return - -/obj/structure/closet/crate/secure/attack_hand(mob/user) - if(manifest) - tear_manifest(user) - return - if(locked && !broken) - if (allowed(user)) - user << "You unlock [src]." - src.locked = 0 - update_icon() - add_fingerprint(user) - return - else - user << "[src] is locked." - return - else - ..() - -/obj/structure/closet/crate/secure/attackby(obj/item/weapon/W, mob/user, params) - if(istype(W, /obj/item/weapon/card) && src.allowed(user) && !locked && !opened && !broken) - user << "You lock \the [src]." - src.locked = 1 - update_icon() - add_fingerprint(user) - return - - return ..() - -/obj/structure/closet/crate/secure/emag_act(mob/user) - if(locked && !broken) - src.locked = 0 - src.broken = 1 - update_icon() - overlays += sparks - spawn(6) overlays -= sparks //Tried lots of stuff but nothing works right. so i have to use this *sadface* - playsound(src.loc, "sparks", 60, 1) - user << "You unlock \the [src]." - add_fingerprint(user) - -/obj/structure/closet/crate/attack_paw(mob/user) - return attack_hand(user) - -/obj/structure/closet/crate/attackby(obj/item/weapon/W, mob/user, params) - if(opened) - if(isrobot(user)) - return - if(!user.drop_item()) //couldn't drop the item - user << "\The [W] is stuck to your hand, you cannot put it in \the [src]!" - return - if(W) - W.loc = src.loc - else if(istype(W, /obj/item/stack/packageWrap)) - return - else if(istype(W, /obj/item/stack/cable_coil)) - if(rigged) - user << "[src] is already rigged!" - return - var/obj/item/stack/cable_coil/C = W - if (C.use(5)) - user << "You rig [src]." - rigged = 1 - else - user << "You need 5 lengths of cable to rig [src]!" - return - else if(istype(W, /obj/item/device/electropack)) - if(rigged) - if(!user.drop_item()) - return - user << "You attach [W] to [src]." - W.loc = src - return - else if(istype(W, /obj/item/weapon/wirecutters)) - if(rigged) - user << "You cut away the wiring." - playsound(loc, 'sound/items/Wirecutter.ogg', 100, 1) - rigged = 0 - return - else if(!place(user, W)) - return attack_hand(user) - -/obj/structure/closet/crate/secure/emp_act(severity) - for(var/obj/O in src) - O.emp_act(severity) - if(!broken && !opened && prob(50/severity)) - if(!locked) - src.locked = 1 - update_icon() - else - src.locked = 0 - src.broken = 1 - update_icon() - overlays += sparks - spawn(6) overlays -= sparks //Tried lots of stuff but nothing works right. so i have to use this *sadface* - playsound(src.loc, 'sound/effects/sparks4.ogg', 75, 1) - if(!opened && prob(20/severity)) - if(!locked) - open() - else - src.req_access = list() - src.req_access += pick(get_all_accesses()) - ..() - diff --git a/code/game/objects/structures/crates_lockers/crates/bins.dm b/code/game/objects/structures/crates_lockers/crates/bins.dm new file mode 100644 index 00000000000..6f46530219b --- /dev/null +++ b/code/game/objects/structures/crates_lockers/crates/bins.dm @@ -0,0 +1,44 @@ +/obj/structure/closet/crate/bin + desc = "A trash bin, place your trash here for the janitor to collect." + name = "trash bin" + icon_state = "largebins" + open_sound = 'sound/effects/bin_open.ogg' + close_sound = 'sound/effects/bin_close.ogg' + anchored = TRUE + horizontal = FALSE + +/obj/structure/closet/crate/bin/New() + ..() + update_icon() + +/obj/structure/closet/crate/bin/update_icon() + ..() + overlays.Cut() + if(contents.len == 0) + overlays += "largebing" + else if(contents.len >= storage_capacity) + overlays += "largebinr" + else + overlays += "largebino" + +/obj/structure/closet/crate/bin/attackby(obj/item/weapon/W, mob/user, params) + if(istype(W, /obj/item/weapon/storage/bag/trash)) + var/obj/item/weapon/storage/bag/trash/T = W + user << "You fill the bag." + for(var/obj/item/O in src) + if(T.can_be_inserted(O, 1)) + O.loc = T + T.update_icon() + do_animate() + else if(istype(W, /obj/item/weapon/wrench)) + anchored = !anchored + playsound(src.loc, 'sound/items/Ratchet.ogg', 75, 1) + else + ..() + +/obj/structure/closet/crate/bin/proc/do_animate() + playsound(loc, open_sound, 15, 1, -3) + flick("animate_largebins", src) + spawn(13) + playsound(loc, close_sound, 15, 1, -3) + update_icon() diff --git a/code/game/objects/structures/crates_lockers/crates/critter.dm b/code/game/objects/structures/crates_lockers/crates/critter.dm new file mode 100644 index 00000000000..3159d1e0eaa --- /dev/null +++ b/code/game/objects/structures/crates_lockers/crates/critter.dm @@ -0,0 +1,38 @@ +/obj/structure/closet/crate/critter + name = "critter crate" + desc = "A crate designed for safe transport of animals. It has an oxygen tank for safe transport in space." + icon_state = "crittercrate" + horizontal = FALSE + allow_objects = FALSE + breakout_time = 1 + material_drop = /obj/item/stack/sheet/mineral/wood + var/obj/item/weapon/tank/internals/emergency_oxygen/tank + +/obj/structure/closet/crate/critter/New() + ..() + tank = new + +/obj/structure/closet/crate/critter/Destroy() + var/turf/T = get_turf(src) + tank.loc = T + tank = null + + for(var/i in 1 to rand(2, 5)) + new material_drop(T) + + return ..() + +/obj/structure/closet/crate/critter/update_icon() + overlays.Cut() + if(opened) + overlays += "crittercrate_door_open" + else + overlays += "crittercrate_door" + if(manifest) + overlays += "manifest" + +/obj/structure/closet/crate/critter/return_air() + if(tank) + return tank.air_contents + else + return loc.return_air() \ No newline at end of file diff --git a/code/game/objects/structures/crates_lockers/crates/large.dm b/code/game/objects/structures/crates_lockers/crates/large.dm new file mode 100644 index 00000000000..8e346125205 --- /dev/null +++ b/code/game/objects/structures/crates_lockers/crates/large.dm @@ -0,0 +1,33 @@ +/obj/structure/closet/crate/large + name = "large crate" + desc = "A hefty wooden crate." + icon_state = "largecrate" + density = 1 + material_drop = /obj/item/stack/sheet/mineral/wood + +/obj/structure/closet/crate/large/attack_hand(mob/user) + add_fingerprint(user) + if(manifest) + tear_manifest(user) + else + user << "You need a crowbar to pry this open!" + +/obj/structure/closet/crate/large/attackby(obj/item/weapon/W, mob/user, params) + if(istype(W, /obj/item/weapon/crowbar)) + var/turf/T = get_turf(src) + if(manifest) + tear_manifest(user) + + user.visible_message("[user] pries \the [src] open.", \ + "You pry open \the [src].", \ + "You hear splitting wood.") + playsound(src.loc, 'sound/weapons/slashmiss.ogg', 75, 1) + + for(var/i in 1 to rand(2, 5)) + new material_drop(src) + for(var/atom/movable/AM in contents) + AM.forceMove(T) + + qdel(src) + else + ..() diff --git a/code/game/objects/structures/crates_lockers/crates/secure.dm b/code/game/objects/structures/crates_lockers/crates/secure.dm new file mode 100644 index 00000000000..ffcdd093a44 --- /dev/null +++ b/code/game/objects/structures/crates_lockers/crates/secure.dm @@ -0,0 +1,36 @@ +/obj/structure/closet/crate/secure + desc = "A secure crate." + name = "secure crate" + icon_state = "securecrate" + secure = 1 + locked = 1 + health = 1000 + +/obj/structure/closet/crate/secure/update_icon() + ..() + if(broken) + overlays += "securecrateemag" + else if(locked) + overlays += "securecrater" + else + overlays += "securecrateg" + +/obj/structure/closet/crate/secure/weapon + desc = "A secure weapons crate." + name = "weapons crate" + icon_state = "weaponcrate" + +/obj/structure/closet/crate/secure/plasma + desc = "A secure plasma crate." + name = "plasma crate" + icon_state = "plasmacrate" + +/obj/structure/closet/crate/secure/gear + desc = "A secure gear crate." + name = "gear crate" + icon_state = "secgearcrate" + +/obj/structure/closet/crate/secure/hydroponics + desc = "A crate with a lock on it, painted in the scheme of the station's botanists." + name = "secure hydroponics crate" + icon_state = "hydrosecurecrate" diff --git a/code/game/objects/structures/crates_lockers/largecrate.dm b/code/game/objects/structures/crates_lockers/largecrate.dm deleted file mode 100644 index 6e2ce331f0b..00000000000 --- a/code/game/objects/structures/crates_lockers/largecrate.dm +++ /dev/null @@ -1,53 +0,0 @@ -/obj/structure/largecrate - name = "large crate" - desc = "A hefty wooden crate." - icon = 'icons/obj/crates.dmi' - icon_state = "densecrate" - density = 1 - var/obj/item/weapon/paper/manifest/manifest - -/obj/structure/largecrate/New() - ..() - update_icon() - -/obj/structure/largecrate/update_icon() - ..() - overlays.Cut() - if(manifest) - overlays += "manifest" - -/obj/structure/largecrate/attack_hand(mob/user) - if(manifest) - user << "You tear the manifest off of the crate." - playsound(src.loc, 'sound/items/poster_ripped.ogg', 75, 1) - manifest.loc = loc - if(ishuman(user)) - user.put_in_hands(manifest) - manifest = null - update_icon() - return - else - user << "You need a crowbar to pry this open!" - return - -/obj/structure/largecrate/attackby(obj/item/weapon/W, mob/user, params) - if(istype(W, /obj/item/weapon/crowbar)) - if(manifest) - manifest.loc = loc - manifest = null - update_icon() - new /obj/item/stack/sheet/mineral/wood(src) - var/turf/T = get_turf(src) - for(var/atom/movable/AM in contents) - AM.loc = T - user.visible_message("[user] pries \the [src] open.", \ - "You pry open \the [src].", \ - "You hear splitting wood.") - playsound(src.loc, 'sound/items/Deconstruct.ogg', 75, 1) - qdel(src) - else - return attack_hand(user) - -/obj/structure/largecrate/mule - icon_state = "mulecrate" - diff --git a/code/game/turfs/simulated/walls_reinforced.dm b/code/game/turfs/simulated/walls_reinforced.dm index 0a38bd12535..15957c579be 100644 --- a/code/game/turfs/simulated/walls_reinforced.dm +++ b/code/game/turfs/simulated/walls_reinforced.dm @@ -23,6 +23,7 @@ /turf/simulated/wall/r_wall/attack_animal(mob/living/simple_animal/M) M.changeNext_move(CLICK_CD_MELEE) + M.do_attack_animation(src) if(M.environment_smash == 3) dismantle_wall(1) playsound(src, 'sound/effects/meteorimpact.ogg', 100, 1) diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index f023e7de493..0672ba1437f 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -619,21 +619,7 @@ var/global/BSACooldown = 0 if(!check_rights(R_SPAWN)) return - var/list/matches = get_fancy_list_of_types() - if (!isnull(object) && object!="") - matches = filter_fancy_list(matches, object) - - if(matches.len==0) - return - - var/chosen - if(matches.len==1) - chosen = matches[1] - else - chosen = input("Select an atom type", "Spawn Atom", matches[1]) as null|anything in matches - if(!chosen) - return - chosen = matches[chosen] + var/chosen = pick_closest_path(object) if(ispath(chosen,/turf)) var/turf/T = get_turf(usr.loc) diff --git a/code/modules/admin/verbs/buildmode.dm b/code/modules/admin/verbs/buildmode.dm index 934ba3d6df4..bd04c75653b 100644 --- a/code/modules/admin/verbs/buildmode.dm +++ b/code/modules/admin/verbs/buildmode.dm @@ -3,215 +3,246 @@ #define VAR_BUILDMODE 3 #define THROW_BUILDMODE 4 #define AREA_BUILDMODE 5 -#define NUM_BUILDMODES 5 +#define COPY_BUILDMODE 6 +#define NUM_BUILDMODES 6 + +//Buildmode Shuttle +//Builmode Move + +/obj/screen/buildmode + icon = 'icons/misc/buildmode.dmi' + var/datum/buildmode/bd + +/obj/screen/buildmode/New(bd) + ..() + src.bd = bd + +/obj/screen/buildmode/mode + icon_state = "buildmode1" + name = "Toggle Mode" + screen_loc = "NORTH,WEST" + +/obj/screen/buildmode/mode/Click(location, control, params) + var/list/pa = params2list(params) + + if(pa.Find("left")) + bd.toggle_modes() + else if(pa.Find("right")) + bd.change_settings(usr) + update_icon() + return 1 + +/obj/screen/buildmode/mode/update_icon() + icon_state = "buildmode[bd.mode]" + return + +/obj/screen/buildmode/help + icon_state = "buildhelp" + screen_loc = "NORTH,WEST+1" + name = "Buildmode Help" + +/obj/screen/buildmode/help/Click() + bd.show_help(usr) + return 1 + +/obj/screen/buildmode/bdir + icon_state = "build" + screen_loc = "NORTH,WEST+2" + name = "Change Dir" + + +/obj/screen/buildmode/bdir/update_icon() + dir = bd.build_dir + return + +/obj/screen/buildmode/quit + icon_state = "buildquit" + screen_loc = "NORTH,WEST+3" + name = "Quit Buildmode" + +/obj/screen/buildmode/quit/Click() + bd.quit() + return 1 + +/obj/screen/buildmode/dir/Click() + bd.change_dir() + update_icon() + return 1 + +/datum/buildmode + var/mode = BASIC_BUILDMODE + var/client/holder = null + var/list/obj/screen/buttons = list() + var/build_dir = SOUTH + var/atom/movable/throw_atom = null + var/turf/cornerA = null + var/turf/cornerB = null + var/generator_path = null + var/varholder = "name" + var/valueholder = "derp" + var/objholder = /obj/structure/closet + var/atom/movable/stored = null + +/datum/buildmode/New(client/c) + create_buttons() + holder = c + holder.click_intercept = src + holder.show_popup_menus = 0 + holder.screen += buttons + +/datum/buildmode/proc/quit() + holder.screen -= buttons + holder.click_intercept = null + holder.show_popup_menus = 1 + qdel(src) + return + +/datum/buildmode/Destroy() + stored = null + for(var/button in buttons) + qdel(button) + +/datum/buildmode/proc/create_buttons() + buttons += new /obj/screen/buildmode/mode(src) + buttons += new /obj/screen/buildmode/help(src) + buttons += new /obj/screen/buildmode/bdir(src) + buttons += new /obj/screen/buildmode/quit(src) + +/datum/buildmode/proc/toggle_modes() + mode = (mode % NUM_BUILDMODES) +1 + Reset() + return + +/datum/buildmode/proc/show_help(mob/user) + switch(mode) + if(BASIC_BUILDMODE) + user << "\blue ***********************************************************" + user << "\blue Left Mouse Button = Construct / Upgrade" + user << "\blue Right Mouse Button = Deconstruct / Delete / Downgrade" + user << "\blue Left Mouse Button + ctrl = R-Window" + user << "\blue Left Mouse Button + alt = Airlock" + user << "" + user << "\blue Use the button in the upper left corner to" + user << "\blue change the direction of built objects." + user << "\blue ***********************************************************" + if(ADV_BUILDMODE) + user << "\blue ***********************************************************" + user << "\blue Right Mouse Button on buildmode button = Set object type" + user << "\blue Left Mouse Button on turf/obj = Place objects" + user << "\blue Right Mouse Button = Delete objects" + user << "" + user << "\blue Use the button in the upper left corner to" + user << "\blue change the direction of built objects." + user << "\blue ***********************************************************" + if(VAR_BUILDMODE) + user << "\blue ***********************************************************" + user << "\blue Right Mouse Button on buildmode button = Select var(type) & value" + user << "\blue Left Mouse Button on turf/obj/mob = Set var(type) & value" + user << "\blue Right Mouse Button on turf/obj/mob = Reset var's value" + user << "\blue ***********************************************************" + if(THROW_BUILDMODE) + user << "\blue ***********************************************************" + user << "\blue Left Mouse Button on turf/obj/mob = Select" + user << "\blue Right Mouse Button on turf/obj/mob = Throw" + user << "\blue ***********************************************************" + if(AREA_BUILDMODE) + user << "\blue ***********************************************************" + user << "\blue Left Mouse Button on turf/obj/mob = Select corner" + user << "\blue Right Mouse Button on buildmode button = Select generator" + user << "\blue ***********************************************************" + if(COPY_BUILDMODE) + user << "\blue ***********************************************************" + user << "\blue Left Mouse Button on obj/turf/mob = Spawn a Copy of selected target" + user << "\blue Right Mouse Button on obj/mob = Select target to copy" + user << "\blue ***********************************************************" + +/datum/buildmode/proc/change_settings(mob/user) + switch(mode) + if(BASIC_BUILDMODE) + return 1 + if(ADV_BUILDMODE) + var/target_path = input(user,"Enter typepath:" ,"Typepath","/obj/structure/closet") + objholder = text2path(target_path) + if(!ispath(objholder)) + objholder = pick_closest_path(target_path) + if(!objholder) + objholder = /obj/structure/closet + alert("That path is not allowed.") + else + if(ispath(objholder,/mob) && !check_rights(R_DEBUG,0)) + objholder = /obj/structure/closet + if(VAR_BUILDMODE) + var/list/locked = list("vars", "key", "ckey", "client", "firemut", "ishulk", "telekinesis", "xray", "virus", "viruses", "cuffed", "ka", "last_eaten", "urine") + + varholder = input(user,"Enter variable name:" ,"Name", "name") + if(varholder in locked && !check_rights(R_DEBUG,0)) + return 1 + var/thetype = input(user,"Select variable type:" ,"Type") in list("text","number","mob-reference","obj-reference","turf-reference") + if(!thetype) return 1 + switch(thetype) + if("text") + valueholder = input(user,"Enter variable value:" ,"Value", "value") as text + if("number") + valueholder = input(user,"Enter variable value:" ,"Value", 123) as num + if("mob-reference") + valueholder = input(user,"Enter variable value:" ,"Value") as mob in mob_list + if("obj-reference") + valueholder = input(user,"Enter variable value:" ,"Value") as obj in world + if("turf-reference") + valueholder = input(user,"Enter variable value:" ,"Value") as turf in world + if(AREA_BUILDMODE) + var/list/gen_paths = subtypesof(/datum/mapGenerator) + + var/type = input(user,"Select Generator Type","Type") as null|anything in gen_paths + if(!type) return + + generator_path = type + cornerA = null + cornerB = null + +/datum/buildmode/proc/change_dir() + switch(build_dir) + if(NORTH) + build_dir = EAST + if(EAST) + build_dir = SOUTH + if(SOUTH) + build_dir = WEST + if(WEST) + build_dir = NORTHWEST + if(NORTHWEST) + build_dir = NORTH + return 1 + +/datum/buildmode/proc/Reset()//Reset temporary variables + cornerA = null + cornerB = null /proc/togglebuildmode(mob/M in player_list) set name = "Toggle Build Mode" set category = "Special Verbs" if(M.client) - if(M.client.buildmode) + if(istype(M.client.click_intercept,/datum/buildmode)) + var/datum/buildmode/B = M.client.click_intercept + B.quit() log_admin("[key_name(usr)] has left build mode.") - M.client.buildmode = 0 - M.client.show_popup_menus = 1 - for(var/obj/effect/bmode/buildholder/H) - if(H.cl == M.client) - qdel(H) else + new/datum/buildmode(M.client) message_admins("[key_name(usr)] has entered build mode.") log_admin("[key_name(usr)] has entered build mode.") - M.client.buildmode = 1 - M.client.show_popup_menus = 0 - var/obj/effect/bmode/buildholder/H = new/obj/effect/bmode/buildholder() - var/obj/effect/bmode/builddir/A = new/obj/effect/bmode/builddir(H) - A.master = H - var/obj/effect/bmode/buildhelp/B = new/obj/effect/bmode/buildhelp(H) - B.master = H - var/obj/effect/bmode/buildmode/C = new/obj/effect/bmode/buildmode(H) - C.master = H - var/obj/effect/bmode/buildquit/D = new/obj/effect/bmode/buildquit(H) - D.master = H - H.builddir = A - H.buildhelp = B - H.buildmode = C - H.buildquit = D - M.client.screen += A - M.client.screen += B - M.client.screen += C - M.client.screen += D - H.cl = M.client - -/obj/effect/bmode //Cleaning up the tree a bit - density = 1 - anchored = 1 - layer = 20 - dir = NORTH - icon = 'icons/misc/buildmode.dmi' - var/obj/effect/bmode/buildholder/master = null - -/obj/effect/bmode/builddir - icon_state = "build" - screen_loc = "NORTH,WEST" - -/obj/effect/bmode/builddir/Click() - switch(dir) - if(NORTH) - dir = EAST - if(EAST) - dir = SOUTH - if(SOUTH) - dir = WEST - if(WEST) - dir = NORTHWEST - if(NORTHWEST) - dir = NORTH - return 1 - -/obj/effect/bmode/buildhelp - icon = 'icons/misc/buildmode.dmi' - icon_state = "buildhelp" - screen_loc = "NORTH,WEST+1" - -/obj/effect/bmode/buildhelp/Click() - switch(master.cl.buildmode) - if(BASIC_BUILDMODE) - usr << "\blue ***********************************************************" - usr << "\blue Left Mouse Button = Construct / Upgrade" - usr << "\blue Right Mouse Button = Deconstruct / Delete / Downgrade" - usr << "\blue Left Mouse Button + ctrl = R-Window" - usr << "\blue Left Mouse Button + alt = Airlock" - usr << "" - usr << "\blue Use the button in the upper left corner to" - usr << "\blue change the direction of built objects." - usr << "\blue ***********************************************************" - if(ADV_BUILDMODE) - usr << "\blue ***********************************************************" - usr << "\blue Right Mouse Button on buildmode button = Set object type" - usr << "\blue Left Mouse Button on turf/obj = Place objects" - usr << "\blue Right Mouse Button = Delete objects" - usr << "" - usr << "\blue Use the button in the upper left corner to" - usr << "\blue change the direction of built objects." - usr << "\blue ***********************************************************" - if(VAR_BUILDMODE) - usr << "\blue ***********************************************************" - usr << "\blue Right Mouse Button on buildmode button = Select var(type) & value" - usr << "\blue Left Mouse Button on turf/obj/mob = Set var(type) & value" - usr << "\blue Right Mouse Button on turf/obj/mob = Reset var's value" - usr << "\blue ***********************************************************" - if(THROW_BUILDMODE) - usr << "\blue ***********************************************************" - usr << "\blue Left Mouse Button on turf/obj/mob = Select" - usr << "\blue Right Mouse Button on turf/obj/mob = Throw" - usr << "\blue ***********************************************************" - if(AREA_BUILDMODE) - usr << "\blue ***********************************************************" - usr << "\blue Left Mouse Button on turf/obj/mob = Select corner" - usr << "\blue Right Mouse Button on buildmode button = Select generator" - usr << "\blue ***********************************************************" - - return 1 - -/obj/effect/bmode/buildquit - icon_state = "buildquit" - screen_loc = "NORTH,WEST+3" - -/obj/effect/bmode/buildquit/Click() - togglebuildmode(master.cl.mob) - return 1 - -/obj/effect/bmode/buildholder - density = 0 - anchored = 1 - var/client/cl = null - var/obj/effect/bmode/builddir/builddir = null - var/obj/effect/bmode/buildhelp/buildhelp = null - var/obj/effect/bmode/buildmode/buildmode = null - var/obj/effect/bmode/buildquit/buildquit = null - var/atom/movable/throw_atom = null - var/turf/cornerA = null - var/turf/cornerB = null - var/generator_path = null - -/obj/effect/bmode/buildholder/proc/Reset()//Reset temporary variables - cornerA = null - cornerB = null - -/obj/effect/bmode/buildmode - icon_state = "buildmode1" - screen_loc = "NORTH,WEST+2" - var/varholder = "name" - var/valueholder = "derp" - var/objholder = /obj/structure/closet - -/obj/effect/bmode/buildmode/Click(location, control, params) +/datum/buildmode/proc/ClickOn(user,params,atom/object) //Click Intercept var/list/pa = params2list(params) + var/right_click = pa.Find("right") + var/left_click = pa.Find("left") + var/alt_click = pa.Find("alt") + var/ctrl_click = pa.Find("ctrl") - if(pa.Find("left")) - master.cl.buildmode = (master.cl.buildmode % NUM_BUILDMODES) +1 - master.Reset() - src.icon_state = "buildmode[master.cl.buildmode]" - - else if(pa.Find("right")) - switch(master.cl.buildmode) - if(BASIC_BUILDMODE) - return 1 - if(ADV_BUILDMODE) - objholder = text2path(input(usr,"Enter typepath:" ,"Typepath","/obj/structure/closet")) - if(!ispath(objholder)) - objholder = /obj/structure/closet - alert("That path is not allowed.") - else - if(ispath(objholder,/mob) && !check_rights(R_DEBUG,0)) - objholder = /obj/structure/closet - if(VAR_BUILDMODE) - var/list/locked = list("vars", "key", "ckey", "client", "firemut", "ishulk", "telekinesis", "xray", "virus", "viruses", "cuffed", "ka", "last_eaten", "urine") - - master.buildmode.varholder = input(usr,"Enter variable name:" ,"Name", "name") - if(master.buildmode.varholder in locked && !check_rights(R_DEBUG,0)) - return 1 - var/thetype = input(usr,"Select variable type:" ,"Type") in list("text","number","mob-reference","obj-reference","turf-reference") - if(!thetype) return 1 - switch(thetype) - if("text") - master.buildmode.valueholder = input(usr,"Enter variable value:" ,"Value", "value") as text - if("number") - master.buildmode.valueholder = input(usr,"Enter variable value:" ,"Value", 123) as num - if("mob-reference") - master.buildmode.valueholder = input(usr,"Enter variable value:" ,"Value") as mob in mob_list - if("obj-reference") - master.buildmode.valueholder = input(usr,"Enter variable value:" ,"Value") as obj in world - if("turf-reference") - master.buildmode.valueholder = input(usr,"Enter variable value:" ,"Value") as turf in world - if(AREA_BUILDMODE) - var/list/gen_paths = subtypesof(/datum/mapGenerator) - - var/type = input(usr,"Select Generator Type","Type") as null|anything in gen_paths - if(!type) return - - master.generator_path = type - master.cornerA = null - master.cornerB = null - - return 1 - - -/proc/build_click(mob/user, buildmode, params, obj/object) - var/obj/effect/bmode/buildholder/holder = null - for(var/obj/effect/bmode/buildholder/H) - if(H.cl == user.client) - holder = H - break - if(!holder) return - var/list/pa = params2list(params) - - if(istype(object,/obj/effect/bmode)) - return - - switch(buildmode) + . = 1 + switch(mode) if(BASIC_BUILDMODE) - if(istype(object,/turf) && pa.Find("left") && !pa.Find("alt") && !pa.Find("ctrl") ) + if(istype(object,/turf) && left_click && !alt_click && !ctrl_click) var/turf/T = object if(istype(object,/turf/space)) T.ChangeTurf(/turf/simulated/floor/plasteel) @@ -219,10 +250,10 @@ T.ChangeTurf(/turf/simulated/wall) else if(istype(object,/turf/simulated/wall)) T.ChangeTurf(/turf/simulated/wall/r_wall) - log_admin("Build Mode: [key_name(usr)] built [T] at ([T.x],[T.y],[T.z])") + log_admin("Build Mode: [key_name(user)] built [T] at ([T.x],[T.y],[T.z])") return - else if(pa.Find("right")) - log_admin("Build Mode: [key_name(usr)] deleted [object] at ([object.x],[object.y],[object.z])") + else if(right_click) + log_admin("Build Mode: [key_name(user)] deleted [object] at ([object.x],[object.y],[object.z])") if(istype(object,/turf/simulated/wall)) var/turf/T = object T.ChangeTurf(/turf/simulated/floor/plasteel) @@ -235,11 +266,11 @@ else if(istype(object,/obj)) qdel(object) return - else if(istype(object,/turf) && pa.Find("alt") && pa.Find("left")) - log_admin("Build Mode: [key_name(usr)] built an airlock at ([object.x],[object.y],[object.z])") + else if(istype(object,/turf) && alt_click && left_click) + log_admin("Build Mode: [key_name(user)] built an airlock at ([object.x],[object.y],[object.z])") new/obj/machinery/door/airlock(get_turf(object)) - else if(istype(object,/turf) && pa.Find("ctrl") && pa.Find("left")) - switch(holder.builddir.dir) + else if(istype(object,/turf) && ctrl_click && left_click) + switch(build_dir) if(NORTH) var/obj/structure/window/reinforced/WIN = new/obj/structure/window/reinforced(get_turf(object)) WIN.dir = NORTH @@ -255,74 +286,70 @@ if(NORTHWEST) var/obj/structure/window/reinforced/WIN = new/obj/structure/window/reinforced(get_turf(object)) WIN.dir = NORTHWEST - log_admin("Build Mode: [key_name(usr)] built a window at ([object.x],[object.y],[object.z])") + log_admin("Build Mode: [key_name(user)] built a window at ([object.x],[object.y],[object.z])") if(ADV_BUILDMODE) - if(pa.Find("left")) - if(ispath(holder.buildmode.objholder,/turf)) + if(left_click) + if(ispath(objholder,/turf)) var/turf/T = get_turf(object) - log_admin("Build Mode: [key_name(usr)] modified [T] ([T.x],[T.y],[T.z]) to [holder.buildmode.objholder]") - T.ChangeTurf(holder.buildmode.objholder) + log_admin("Build Mode: [key_name(user)] modified [T] ([T.x],[T.y],[T.z]) to [objholder]") + T.ChangeTurf(objholder) else - var/obj/A = new holder.buildmode.objholder (get_turf(object)) - A.dir = holder.builddir.dir - log_admin("Build Mode: [key_name(usr)] modified [A]'s ([A.x],[A.y],[A.z]) dir to [holder.builddir.dir]") - else if(pa.Find("right")) + var/obj/A = new objholder (get_turf(object)) + A.dir = build_dir + log_admin("Build Mode: [key_name(user)] modified [A]'s ([A.x],[A.y],[A.z]) dir to [build_dir]") + else if(right_click) if(isobj(object)) - log_admin("Build Mode: [key_name(usr)] deleted [object] at ([object.x],[object.y],[object.z])") + log_admin("Build Mode: [key_name(user)] deleted [object] at ([object.x],[object.y],[object.z])") qdel(object) if(VAR_BUILDMODE) - if(pa.Find("left")) //I cant believe this shit actually compiles. - if(object.vars.Find(holder.buildmode.varholder)) - log_admin("Build Mode: [key_name(usr)] modified [object.name]'s [holder.buildmode.varholder] to [holder.buildmode.valueholder]") - object.vars[holder.buildmode.varholder] = holder.buildmode.valueholder + if(left_click) //I cant believe this shit actually compiles. + if(object.vars.Find(varholder)) + log_admin("Build Mode: [key_name(user)] modified [object.name]'s [varholder] to [valueholder]") + object.vars[varholder] = valueholder else - usr << "[initial(object.name)] does not have a var called '[holder.buildmode.varholder]'" - if(pa.Find("right")) - if(object.vars.Find(holder.buildmode.varholder)) - log_admin("Build Mode: [key_name(usr)] modified [object.name]'s [holder.buildmode.varholder] to [holder.buildmode.valueholder]") - object.vars[holder.buildmode.varholder] = initial(object.vars[holder.buildmode.varholder]) + user << "[initial(object.name)] does not have a var called '[varholder]'" + if(right_click) + if(object.vars.Find(varholder)) + log_admin("Build Mode: [key_name(user)] modified [object.name]'s [varholder] to [valueholder]") + object.vars[varholder] = initial(object.vars[varholder]) else - usr << "[initial(object.name)] does not have a var called '[holder.buildmode.varholder]'" + user << "[initial(object.name)] does not have a var called '[varholder]'" if(THROW_BUILDMODE) - if(pa.Find("left")) + if(left_click) if(isturf(object)) return - holder.throw_atom = object - if(pa.Find("right")) - if(holder.throw_atom) - holder.throw_atom.throw_at(object, 10, 1,user) - log_admin("Build Mode: [key_name(usr)] threw [holder.throw_atom] at [object] ([object.x],[object.y],[object.z])") + throw_atom = object + if(right_click) + if(throw_atom) + throw_atom.throw_at(object, 10, 1,user) + log_admin("Build Mode: [key_name(user)] threw [throw_atom] at [object] ([object.x],[object.y],[object.z])") if(AREA_BUILDMODE) - if(!holder.cornerA) - holder.cornerA = get_turf(object) + if(!cornerA) + cornerA = get_turf(object) return - if(holder.cornerA && !holder.cornerB) - holder.cornerB = get_turf(object) + if(cornerA && !cornerB) + cornerB = get_turf(object) - if(pa.Find("left")) //rectangular - if(holder.cornerA && holder.cornerB) - if(!holder.generator_path) - usr << "Select generator type first." - var/datum/mapGenerator/G = new holder.generator_path - G.defineRegion(holder.cornerA,holder.cornerB,1) + if(left_click) //rectangular + if(cornerA && cornerB) + if(!generator_path) + user << "Select generator type first." + var/datum/mapGenerator/G = new generator_path + G.defineRegion(cornerA,cornerB,1) G.generate() - holder.cornerA = null - holder.cornerB = null + cornerA = null + cornerB = null return - /* Something wrong with this, will check later - if(pa.Find("right")) // circular - if(holder.cornerA && holder.cornerB) - if(!holder.generator_path) - usr << "Select generator type first." - var/datum/mapGenerator/G = new holder.generator_path - G.defineCircularRegion(holder.cornerA,holder.cornerB,1) - G.generate() - holder.cornerA = null - holder.cornerB = null - return - */ //Something wrong - Reset - holder.cornerA = null - holder.cornerB = null \ No newline at end of file + cornerA = null + cornerB = null + if(COPY_BUILDMODE) + if(left_click) + var/turf/T = get_turf(object) + if(stored) + DuplicateObject(stored,perfectcopy=1,newloc=T) + else if(right_click) + if(ismovableatom(object)) // No copying turfs for now. + stored = object \ No newline at end of file diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm index e250f21cc81..25d3d42a9cd 100644 --- a/code/modules/admin/verbs/randomverbs.dm +++ b/code/modules/admin/verbs/randomverbs.dm @@ -186,7 +186,7 @@ log_admin("[key_name(usr)] has [muteunmute] [key_name(whom)] from [mute_string]") message_admins("[key_name_admin(usr)] has [muteunmute] [key_name_admin(whom)] from [mute_string].") if(C) - C << "You have been [muteunmute] from [mute_string]." + C << "You have been [muteunmute] from [mute_string] by [key_name(usr, include_name = FALSE)]." feedback_add_details("admin_verb","MUTE") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! diff --git a/code/modules/assembly/voice.dm b/code/modules/assembly/voice.dm index 71ef85ef8c5..81d027e4757 100644 --- a/code/modules/assembly/voice.dm +++ b/code/modules/assembly/voice.dm @@ -70,6 +70,8 @@ user << "You set [src] into a [modes[mode]] mode." listening = 0 recorded = "" + else + return ..() /obj/item/device/assembly/voice/activate() if(secured) diff --git a/code/modules/atmospherics/gasmixtures/gas_mixture.dm b/code/modules/atmospherics/gasmixtures/gas_mixture.dm index 490f7adc035..9fe10a439ca 100644 --- a/code/modules/atmospherics/gasmixtures/gas_mixture.dm +++ b/code/modules/atmospherics/gasmixtures/gas_mixture.dm @@ -12,10 +12,12 @@ var/list/meta_gas_info = meta_gas_list() //see ATMOSPHERICS/gas_types.dm var/list/gaslist_cache = null /proc/gaslist(id) var/list/cached_gas - + + //only instantiate the first time it's needed if(!gaslist_cache) gaslist_cache = new(meta_gas_info.len) - + + //only setup the individual lists the first time they're needed if(!gaslist_cache[id]) if(!meta_gas_info[id]) CRASH("Gas [id] does not exist!") @@ -27,13 +29,14 @@ var/list/gaslist_cache = null cached_gas[GAS_META] = meta_gas_info[id] else cached_gas = gaslist_cache[id] + //Copy() it because only GAS_META is static return cached_gas.Copy() /datum/gas_mixture var/list/gases - var/temperature // Kelvins + var/temperature //kelvins var/tmp/temperature_archived - var/volume + var/volume //liters var/last_share var/tmp/fuel_burnt @@ -54,7 +57,7 @@ var/list/gaslist_cache = null var/cached_gases = gases if(cached_gases[gas_id]) return - cached_gases[gas_id] = gaslist(gas_id) //see ATMOSPHERICS/gas_types.dm + cached_gases[gas_id] = gaslist(gas_id) //assert_gases(args) - shorthand for calling assert_gas() once for each gas type. /datum/gas_mixture/proc/assert_gases() @@ -73,46 +76,47 @@ var/list/gaslist_cache = null add_gas(id) //garbage_collect() - removes any gas list which is empty. + //If called with a list as an argument, only removes gas lists with IDs from that list. //Must be used after subtracting from a gas. Must be used after assert_gas() //if assert_gas() was called only to read from the gas. //By removing empty gases, processing speed is increased. -/datum/gas_mixture/proc/garbage_collect() +/datum/gas_mixture/proc/garbage_collect(list/tocheck) var/list/cached_gases = gases - for(var/id in cached_gases) + for(var/id in (tocheck || cached_gases)) if(cached_gases[id][MOLES] <= 0 && cached_gases[id][ARCHIVE] <= 0) cached_gases -= id //PV = nRT -/datum/gas_mixture/proc/heat_capacity() +/datum/gas_mixture/proc/heat_capacity() //joules per kelvin var/list/cached_gases = gases . = 0 for(var/id in cached_gases) . += cached_gases[id][MOLES] * cached_gases[id][GAS_META][META_GAS_SPECIFIC_HEAT] -/datum/gas_mixture/proc/heat_capacity_archived() +/datum/gas_mixture/proc/heat_capacity_archived() //joules per kelvin var/list/cached_gases = gases . = 0 for(var/id in cached_gases) . += cached_gases[id][ARCHIVE] * cached_gases[id][GAS_META][META_GAS_SPECIFIC_HEAT] -/datum/gas_mixture/proc/total_moles() +/datum/gas_mixture/proc/total_moles() //moles var/list/cached_gases = gases . = 0 for(var/id in cached_gases) . += cached_gases[id][MOLES] -/datum/gas_mixture/proc/return_pressure() +/datum/gas_mixture/proc/return_pressure() //kilopascals if(volume > 0) // to prevent division by zero return total_moles() * R_IDEAL_GAS_EQUATION * temperature / volume return 0 -/datum/gas_mixture/proc/return_temperature() +/datum/gas_mixture/proc/return_temperature() //kelvins return temperature -/datum/gas_mixture/proc/return_volume() +/datum/gas_mixture/proc/return_volume() //liters return max(0, volume) -/datum/gas_mixture/proc/thermal_energy() +/datum/gas_mixture/proc/thermal_energy() //joules return temperature * heat_capacity() //Procedures used for very specific events @@ -125,6 +129,7 @@ var/list/gaslist_cache = null temperature = TCMB if(cached_gases["agent_b"] && temperature > 900 && cached_gases["plasma"] && cached_gases["co2"]) + //agent b converts hot co2 to o2 (endothermic) if(cached_gases["plasma"][MOLES] > MINIMUM_HEAT_CAPACITY && cached_gases["co2"][MOLES] > MINIMUM_HEAT_CAPACITY) var/reaction_rate = min(cached_gases["co2"][MOLES]*0.75, cached_gases["plasma"][MOLES]*0.25, cached_gases["agent_b"][MOLES]*0.05) @@ -143,6 +148,7 @@ var/list/gaslist_cache = null /* if(thermal_energy() > (PLASMA_BINDING_ENERGY*10)) if(cached_gases["plasma"] && cached_gases["co2"] && cached_gases["plasma"][MOLES] > MINIMUM_HEAT_CAPACITY && cached_gases["co2"][MOLES] > MINIMUM_HEAT_CAPACITY && (cached_gases["plasma"][MOLES]+cached_gases["co2"][MOLES])/total_moles() >= FUSION_PURITY_THRESHOLD)//Fusion wont occur if the level of impurities is too high. + //fusion converts plasma and co2 to o2 and n2 (exothermic) //world << "pre [temperature, [cached_gases["plasma"][MOLES]], [cached_gases["co2"][MOLES]] var/old_heat_capacity = heat_capacity() var/carbon_efficency = min(cached_gases["plasma"][MOLES]/cached_gases["co2"][MOLES],MAX_CARBON_EFFICENCY) @@ -183,6 +189,7 @@ var/list/gaslist_cache = null return reacting /datum/gas_mixture/proc/fire() + //combustion of plasma and volatile fuel, which both act as hydrocarbons (exothermic) var/energy_released = 0 var/old_heat_capacity = heat_capacity() var/list/cached_gases = gases //this speeds things up because accessing datum vars is slow @@ -266,9 +273,11 @@ var/list/gaslist_cache = null /datum/gas_mixture/proc/copy_from(datum/gas_mixture/sample) //Copies variables from sample + //Returns: 1 in all cases /datum/gas_mixture/proc/copy_from_turf(turf/model) //Copies all gas info from the turf into the gas list along with temperature + //Returns: 1 in all cases /datum/gas_mixture/proc/share(datum/gas_mixture/sharer) //Performs air sharing calculations between two gas_mixtures assuming only 1 boundary length @@ -279,13 +288,17 @@ var/list/gaslist_cache = null //Return: amount of gas exchanged /datum/gas_mixture/proc/check_turf(turf/model) + //Similar to compare(...), except for turfs without their own gas mixtures //Returns: 0 if self-check failed or 1 if check passes -/datum/gas_mixture/proc/temperature_mimic(turf/model, conduction_coefficient) //I want this proc to die a painful death - /datum/gas_mixture/proc/temperature_share(datum/gas_mixture/sharer, conduction_coefficient) + //Performs temperature sharing calculations (via conduction) between two gas_mixtures assuming only 1 boundary length -/datum/gas_mixture/proc/temperature_turf_share(turf/simulated/sharer, conduction_coefficient) +/datum/gas_mixture/proc/temperature_mimic(turf/model, conduction_coefficient) //I want this proc to die a painful death + //Similar to temperature_share(...), except between a gas_mixture and a turf without its own gas_mixture + +/datum/gas_mixture/proc/temperature_turf_share(turf/simulated/sharer, conduction_coefficient) //I want this proc to die a painful death + //Similar to temperature_share(...), except between a gas_mixture and a simulated turf /datum/gas_mixture/proc/compare(datum/gas_mixture/sample) //Compares sample to self to see if within acceptable ranges that group processing may be enabled @@ -303,16 +316,18 @@ var/list/gaslist_cache = null /datum/gas_mixture/merge(datum/gas_mixture/giver) if(!giver) return 0 - + + //heat transfer if(abs(temperature - giver.temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER) var/self_heat_capacity = heat_capacity() var/giver_heat_capacity = giver.heat_capacity() var/combined_heat_capacity = giver_heat_capacity + self_heat_capacity if(combined_heat_capacity) temperature = (giver.temperature * giver_heat_capacity + temperature * self_heat_capacity) / combined_heat_capacity - + var/list/cached_gases = gases //accessing datum vars is slower than proc vars var/list/giver_gases = giver.gases + //gas transfer for(var/giver_id in giver_gases) assert_gas(giver_id) cached_gases[giver_id][MOLES] += giver_gases[giver_id][MOLES] @@ -376,19 +391,28 @@ var/list/gaslist_cache = null for(var/id in sample_gases) assert_gas(id) cached_gases[id][MOLES] = sample_gases[id][MOLES] + //remove all gases not in the sample cached_gases &= sample_gases return 1 /datum/gas_mixture/copy_from_turf(turf/model) var/list/cached_gases = gases - + temperature = model.temperature - assert_gases(arglist(hardcoded_gases)) - cached_gases["o2"][MOLES] = model.oxygen - cached_gases["n2"][MOLES] = model.nitrogen - cached_gases["plasma"][MOLES] = model.toxins - cached_gases["co2"][MOLES] = model.carbon_dioxide + if(model.oxygen) + assert_gas("o2") + cached_gases["o2"][MOLES] = model.oxygen + if(model.nitrogen) + assert_gas("n2") + cached_gases["n2"][MOLES] = model.nitrogen + if(model.toxins) + assert_gas("plasma") + cached_gases["plasma"][MOLES] = model.toxins + if(model.carbon_dioxide) + assert_gas("co2") + cached_gases["co2"][MOLES] = model.carbon_dioxide + //remove all gases not handled by turfs cached_gases &= hardcoded_gases return 1 @@ -462,13 +486,16 @@ var/list/gaslist_cache = null if(abs(old_sharer_heat_capacity) > MINIMUM_HEAT_CAPACITY) if(abs(new_sharer_heat_capacity/old_sharer_heat_capacity - 1) < 0.10) // <10% change in sharer heat capacity temperature_share(sharer, OPEN_HEAT_TRANSFER_COEFFICIENT) - + + var/list/unique_gases = cached_gases ^ sharer_gases + if(unique_gases.len) //if all gases were present in both mixtures, we know that no gases are 0 + garbage_collect(cached_gases - sharer_gases) //any gases the sharer had, we are guaranteed to have. gases that it didn't have we are not. + sharer.garbage_collect(sharer_gases - cached_gases) //the reverse is equally true + if(temperature_delta > MINIMUM_TEMPERATURE_TO_MOVE || abs(moved_moles) > MINIMUM_MOLES_DELTA_TO_MOVE) var/delta_pressure = temperature_archived*(total_moles() + moved_moles) - sharer.temperature_archived*(sharer.total_moles() - moved_moles) - . = delta_pressure * R_IDEAL_GAS_EQUATION / volume - - garbage_collect() - sharer.garbage_collect() + return delta_pressure * R_IDEAL_GAS_EQUATION / volume + /datum/gas_mixture/mimic(turf/model, atmos_adjacent_turfs = 4) var/datum/gas_mixture/copied = new @@ -490,6 +517,7 @@ var/list/gaslist_cache = null sharer.temperature = max(sharer.temperature + heat/sharer_heat_capacity, TCMB) //thermal energy of the system (self and sharer) is unchanged +//see above /datum/gas_mixture/temperature_mimic(turf/model, conduction_coefficient) var/temperature_delta = temperature - model.temperature if(abs(temperature_delta) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER) @@ -501,6 +529,7 @@ var/list/gaslist_cache = null temperature = max(temperature - heat/self_heat_capacity, TCMB) +//see above /datum/gas_mixture/temperature_turf_share(turf/simulated/sharer, conduction_coefficient) var/temperature_delta = temperature_archived - sharer.temperature if(abs(temperature_delta) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER) diff --git a/code/modules/atmospherics/machinery/airalarm.dm b/code/modules/atmospherics/machinery/airalarm.dm index d1dd417493d..d08ec5689ed 100644 --- a/code/modules/atmospherics/machinery/airalarm.dm +++ b/code/modules/atmospherics/machinery/airalarm.dm @@ -412,110 +412,107 @@ if(AALARM_MODE_SCRUBBING) for(var/device_id in alarm_area.air_scrub_names) send_signal(device_id, list( - "power"= 1, - "co2_scrub"= 1, - "tox_scrub"= 0, - "n2o_scrub"= 0, - "scrubbing"= 1, - "widenet"= 0, + "power" = 1, + "co2_scrub" = 1, + "tox_scrub" = 0, + "n2o_scrub" = 0, + "scrubbing" = 1, + "widenet" = 0, )) for(var/device_id in alarm_area.air_vent_names) send_signal(device_id, list( - "power"= 1, - "checks"= 1, - "set_external_pressure"= ONE_ATMOSPHERE + "power" = 1, + "checks" = 1, + "set_external_pressure" = ONE_ATMOSPHERE )) if(AALARM_MODE_CONTAMINATED) for(var/device_id in alarm_area.air_scrub_names) send_signal(device_id, list( - "power"= 1, - "co2_scrub"= 1, - "tox_scrub"= 1, - "n2o_scrub"= 1, - "scrubbing"= 1, - "widenet"= 1, + "power" = 1, + "co2_scrub" = 1, + "tox_scrub" = 1, + "n2o_scrub" = 1, + "scrubbing" = 1, + "widenet" = 1, )) for(var/device_id in alarm_area.air_vent_names) send_signal(device_id, list( - "power"= 1, - "checks"= 1, - "set_external_pressure"= ONE_ATMOSPHERE + "power" = 1, + "checks" = 1, + "set_external_pressure" = ONE_ATMOSPHERE )) if(AALARM_MODE_VENTING) for(var/device_id in alarm_area.air_scrub_names) send_signal(device_id, list( - "power"= 1, - "widenet"= 0, - "scrubbing"= 0 + "power" = 1, + "widenet" = 0, + "scrubbing" = 0 )) for(var/device_id in alarm_area.air_vent_names) send_signal(device_id, list( - "power"= 1, - "checks"= 1, + "power" = 1, + "checks" = 1, "set_external_pressure" = ONE_ATMOSPHERE*2 )) if(AALARM_MODE_REFILL) for(var/device_id in alarm_area.air_scrub_names) send_signal(device_id, list( - "power"= 1, - "co2_scrub"= 1, - "tox_scrub"= 0, - "n2o_scrub"= 0, - "scrubbing"= 1, - "widenet"= 0, + "power" = 1, + "co2_scrub" = 1, + "tox_scrub" = 0, + "n2o_scrub" = 0, + "scrubbing" = 1, + "widenet" = 0, )) for(var/device_id in alarm_area.air_vent_names) send_signal(device_id, list( - "power"= 1, - "checks"= 1, - "set_external_pressure" = ONE_ATMOSPHERE*3 + "power" = 1, + "checks" = 1, + "set_external_pressure" = ONE_ATMOSPHERE * 3 )) - if( - AALARM_MODE_PANIC, - AALARM_MODE_REPLACEMENT - ) + if(AALARM_MODE_PANIC, + AALARM_MODE_REPLACEMENT) for(var/device_id in alarm_area.air_scrub_names) send_signal(device_id, list( - "power"= 1, - "widenet"= 1, - "scrubbing"= 0 + "power" = 1, + "widenet" = 1, + "scrubbing" = 0 )) for(var/device_id in alarm_area.air_vent_names) send_signal(device_id, list( - "power"= 0 + "power" = 0 )) - if( - AALARM_MODE_SIPHON - ) + if(AALARM_MODE_SIPHON) for(var/device_id in alarm_area.air_scrub_names) send_signal(device_id, list( - "power"= 1, - "widenet"= 0, - "scrubbing"= 0 + "power" = 1, + "widenet" = 0, + "scrubbing" = 0 )) for(var/device_id in alarm_area.air_vent_names) send_signal(device_id, list( - "power"= 0 + "power" = 0 )) if(AALARM_MODE_OFF) for(var/device_id in alarm_area.air_scrub_names) send_signal(device_id, list( - "power"= 0 + "power" = 0 )) for(var/device_id in alarm_area.air_vent_names) send_signal(device_id, list( - "power"= 0 + "power" = 0 )) if(AALARM_MODE_FLOOD) for(var/device_id in alarm_area.air_scrub_names) send_signal(device_id, list( - "power"=0 + "power" = 0 )) for(var/device_id in alarm_area.air_vent_names) send_signal(device_id, list( - "power"= 1, - "checks"= 0, + "power" = 1, + "checks" = 2, + "set_internal_pressure" = 0 )) /obj/machinery/airalarm/update_icon() diff --git a/code/modules/atmospherics/machinery/atmosmachinery.dm b/code/modules/atmospherics/machinery/atmosmachinery.dm index b73d3aa5dea..17937f11682 100644 --- a/code/modules/atmospherics/machinery/atmosmachinery.dm +++ b/code/modules/atmospherics/machinery/atmosmachinery.dm @@ -45,8 +45,7 @@ Pipelines + Other Objects -> Pipe network qdel(stored) stored = null - for(var/mob/living/L in src) - L.forceMove(get_turf(src)) + dropContents() if(pipe_vision_img) qdel(pipe_vision_img) @@ -298,4 +297,7 @@ Pipelines + Other Objects -> Pipe network /obj/machinery/atmospherics/update_remote_sight(mob/user) user.sight |= (SEE_TURFS|BLIND) - user.update_pipe_vision(src) + +//Used for certain children of obj/machinery/atmospherics to not show pipe vision when mob is inside it. +/obj/machinery/atmospherics/proc/can_see_pipes() + return 1 diff --git a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm index bead3040a35..d99c28cedb7 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm @@ -46,8 +46,6 @@ conduction_coefficient = initial(conduction_coefficient) * C /obj/machinery/atmospherics/components/unary/cryo_cell/Destroy() - var/turf/T = loc - T.contents += contents beaker = null return ..() @@ -143,12 +141,12 @@ return occupant /obj/machinery/atmospherics/components/unary/cryo_cell/container_resist(mob/user) - usr << "You struggle inside the cryotube, kicking the release with your foot." + usr << "You struggle inside the cryotube, kicking the release with your foot... (This will take around 30 seconds and you need to stand still.)" audible_message("You hear a thump from [src].") addtimer(src, "resist_open", 300, FALSE, user) /obj/machinery/atmospherics/components/unary/cryo_cell/proc/resist_open(mob/user) - if(occupant && (user in src)) // Check they're still here. + if(occupant && occupant == user) // Check they're still here. open_machine() /obj/machinery/atmospherics/components/unary/cryo_cell/examine(mob/user) @@ -256,3 +254,15 @@ beaker = null . = TRUE update_icon() + +/obj/machinery/atmospherics/components/unary/cryo_cell/update_remote_sight(mob/living/user) + return //we don't see the pipe network while inside cryo. + +/obj/machinery/atmospherics/components/unary/cryo_cell/get_remote_view_fullscreens(mob/user) + user.overlay_fullscreen("remote_view", /obj/screen/fullscreen/impaired, 1) + +/obj/machinery/atmospherics/components/unary/cryo_cell/can_crawl_through() + return //can't ventcrawl in or out of cryo. + +/obj/machinery/atmospherics/components/unary/cryo_cell/can_see_pipes() + return 0 //you can't see the pipe network when inside a cryo cell. \ No newline at end of file diff --git a/code/modules/atmospherics/machinery/portable/canister.dm b/code/modules/atmospherics/machinery/portable/canister.dm index 5bef5a4ffd7..057bfd5f9d2 100644 --- a/code/modules/atmospherics/machinery/portable/canister.dm +++ b/code/modules/atmospherics/machinery/portable/canister.dm @@ -9,7 +9,7 @@ density = 1 var/valve_open = FALSE - var/obj/machinery/atmospherics/components/binary/pump/pump + var/obj/machinery/atmospherics/components/binary/passive_gate/pump var/release_log = "" volume = 1000 @@ -82,11 +82,11 @@ /obj/machinery/portable_atmospherics/canister/proc/create_gas() if(gas_type) - air_contents.assert_gas(gas_type) + air_contents.add_gas(gas_type) air_contents.gases[gas_type][MOLES] = (maximum_pressure * filled) * air_contents.volume / (R_IDEAL_GAS_EQUATION * air_contents.temperature) /obj/machinery/portable_atmospherics/canister/air/create_gas() - air_contents.assert_gases("o2","n2") + air_contents.add_gases("o2","n2") air_contents.gases["o2"][MOLES] = (O2STANDARD * maximum_pressure * filled) * air_contents.volume / (R_IDEAL_GAS_EQUATION * air_contents.temperature) air_contents.gases["n2"][MOLES] = (N2STANDARD * maximum_pressure * filled) * air_contents.volume / (R_IDEAL_GAS_EQUATION * air_contents.temperature) @@ -167,9 +167,12 @@ holding = null /obj/machinery/portable_atmospherics/canister/process_atmos() + ..() if(destroyed) return PROCESS_KILL if(!valve_open) + pump.AIR1 = null + pump.AIR2 = null return var/turf/T = get_turf(src) diff --git a/code/modules/atmospherics/machinery/portable/pump.dm b/code/modules/atmospherics/machinery/portable/pump.dm index 2c9d8b93510..1d40bba7e9c 100644 --- a/code/modules/atmospherics/machinery/portable/pump.dm +++ b/code/modules/atmospherics/machinery/portable/pump.dm @@ -42,6 +42,8 @@ /obj/machinery/portable_atmospherics/pump/process_atmos() ..() if(!on) + pump.AIR1 = null + pump.AIR2 = null return var/turf/T = get_turf(src) diff --git a/code/modules/atmospherics/machinery/portable/scrubber.dm b/code/modules/atmospherics/machinery/portable/scrubber.dm index 9a0bcdde173..6aa17ea78e2 100644 --- a/code/modules/atmospherics/machinery/portable/scrubber.dm +++ b/code/modules/atmospherics/machinery/portable/scrubber.dm @@ -25,6 +25,7 @@ overlays += "scrubber-connector" /obj/machinery/portable_atmospherics/scrubber/process_atmos() + ..() if(!on) return @@ -44,7 +45,7 @@ filtered.temperature = filtering.temperature for(var/gas in filtering.gases & scrubbing) - filtered.assert_gas(gas) + filtered.add_gas(gas) filtered.gases[gas][MOLES] = filtering.gases[gas][MOLES] // Shuffle the "bad" gasses to the filtered mixture. filtering.gases[gas][MOLES] = 0 filtering.garbage_collect() // Now that the gasses are set to 0, clean up the mixture. diff --git a/code/modules/awaymissions/bluespaceartillery.dm b/code/modules/awaymissions/bluespaceartillery.dm index 5dd9120c6f0..7a489bfe815 100644 --- a/code/modules/awaymissions/bluespaceartillery.dm +++ b/code/modules/awaymissions/bluespaceartillery.dm @@ -1,8 +1,10 @@ #define ARTILLERY_RELOAD_TIME 60 +#define EXPLOSION_SIZE 3 /obj/machinery/artillerycontrol var/reload = ARTILLERY_RELOAD_TIME + var/explosionsize = EXPLOSION_SIZE name = "bluespace artillery control" icon_state = "control_boxp1" icon = 'icons/obj/machines/particle_accelerator.dmi' @@ -48,7 +50,7 @@ for(var/turf/T in get_area_turfs(thearea.type)) L+=T var/loc = pick(L) - explosion(loc,2,5,11) + explosion(loc,explosionsize,explosionsize*2,explosionsize*4) reload = 0 /*/mob/proc/openfire() diff --git a/code/modules/awaymissions/capture_the_flag.dm b/code/modules/awaymissions/capture_the_flag.dm index 41342e2afbf..625a12c01be 100644 --- a/code/modules/awaymissions/capture_the_flag.dm +++ b/code/modules/awaymissions/capture_the_flag.dm @@ -1,8 +1,9 @@ #define WHITE_TEAM "white" #define RED_TEAM "red" #define BLUE_TEAM "blue" -#define CTF_RESPAWN_COOLDOWN 150 // 15 seconds #define FLAG_RETURN_TIME 200 // 20 seconds +#define INSTAGIB_RESPAWN 50 //5 seconds +#define DEFAULT_RESPAWN 150 //15 seconds @@ -97,12 +98,14 @@ //Capture the Flag scoring var/points = 0 var/points_to_win = 3 + var/respawn_cooldown = DEFAULT_RESPAWN //Capture Point/King of the Hill scoring var/control_points = 0 var/control_points_to_win = 180 var/list/team_members = list() var/ctf_enabled = FALSE var/ctf_gear = /datum/outfit/ctf + var/instagib_gear = /datum/outfit/ctf/instagib /obj/machinery/capture_the_flag/New() ..() @@ -117,12 +120,14 @@ icon_state = "syndbeacon" team = RED_TEAM ctf_gear = /datum/outfit/ctf/red + instagib_gear = /datum/outfit/ctf/red/instagib /obj/machinery/capture_the_flag/blue name = "Blue CTF Controller" icon_state = "bluebeacon" team = BLUE_TEAM ctf_gear = /datum/outfit/ctf/blue + instagib_gear = /datum/outfit/ctf/blue/instagib /obj/machinery/capture_the_flag/attack_ghost(mob/user) if(ctf_enabled == FALSE) @@ -130,8 +135,8 @@ if(ticker.current_state != GAME_STATE_PLAYING) return if(user.ckey in team_members) - if(user.mind.current && user.mind.current.timeofdeath + CTF_RESPAWN_COOLDOWN > world.time) - user << "It must be more than 15 seconds from your last death to respawn!" + if(user.mind.current && user.mind.current.timeofdeath + respawn_cooldown > world.time) + user << "It must be more than [respawn_cooldown/10] seconds from your last death to respawn!" return var/client/new_team_member = user.client dust_old(user) @@ -154,8 +159,8 @@ /obj/machinery/capture_the_flag/proc/dust_old(mob/user) if(user.mind && user.mind.current && user.mind.current.z == src.z) - new /obj/item/ammo_box/magazine/wt550m9 (get_turf(user.mind.current)) - new /obj/item/ammo_box/magazine/wt550m9 (get_turf(user.mind.current)) + new /obj/item/ammo_box/magazine/recharge/ctf (get_turf(user.mind.current)) + new /obj/item/ammo_box/magazine/recharge/ctf (get_turf(user.mind.current)) user.mind.current.dust() @@ -180,8 +185,6 @@ if(points >= points_to_win) victory() - - /obj/machinery/capture_the_flag/proc/victory() for(var/mob/M in mob_list) var/area/mob_area = get_area(M) @@ -203,14 +206,31 @@ spawn(300) CTF.ctf_enabled = TRUE + +/obj/machinery/capture_the_flag/proc/instagib_mode() + for(var/obj/machinery/capture_the_flag/CTF in machines) + if(CTF.ctf_enabled == TRUE) + CTF.ctf_gear = CTF.instagib_gear + CTF.respawn_cooldown = INSTAGIB_RESPAWN + /obj/item/weapon/gun/projectile/automatic/pistol/deagle/CTF desc = "This looks like it could really hurt in melee." force = 75 -/obj/item/weapon/gun/projectile/automatic/wt550/CTF +/obj/item/weapon/gun/projectile/automatic/laser/ctf + mag_type = /obj/item/ammo_box/magazine/recharge/ctf desc = "This looks like it could really hurt in melee." force = 50 +/obj/item/ammo_box/magazine/recharge/ctf + ammo_type = /obj/item/ammo_casing/caseless/laser/ctf + +/obj/item/ammo_casing/caseless/laser/ctf + projectile_type = /obj/item/projectile/beam/ctf + +/obj/item/projectile/beam/ctf + damage = 150 + /datum/outfit/ctf name = "CTF" /obj/item/device/radio/headset @@ -220,18 +240,30 @@ gloves = /obj/item/clothing/gloves/combat id = /obj/item/weapon/card/id/syndicate belt = /obj/item/weapon/gun/projectile/automatic/pistol/deagle/CTF - l_pocket = /obj/item/ammo_box/magazine/wt550m9 - r_pocket = /obj/item/ammo_box/magazine/wt550m9 - r_hand = /obj/item/weapon/gun/projectile/automatic/wt550/CTF + l_pocket = /obj/item/ammo_box/magazine/recharge/ctf + r_pocket = /obj/item/ammo_box/magazine/recharge/ctf + r_hand = /obj/item/weapon/gun/projectile/automatic/laser/ctf + +/datum/outfit/ctf/instagib + r_hand = /obj/item/weapon/gun/energy/laser/instakill + shoes = /obj/item/clothing/shoes/jackboots/fast /datum/outfit/ctf/red ears = /obj/item/device/radio/headset/syndicate/alt suit = /obj/item/clothing/suit/space/hardsuit/shielded/ctf/red +/datum/outfit/ctf/red/instagib + r_hand = /obj/item/weapon/gun/energy/laser/instakill/red + shoes = /obj/item/clothing/shoes/jackboots/fast + /datum/outfit/ctf/blue ears = /obj/item/device/radio/headset/headset_cent/commander suit = /obj/item/clothing/suit/space/hardsuit/shielded/ctf/blue +/datum/outfit/ctf/blue/instagib + r_hand = /obj/item/weapon/gun/energy/laser/instakill/blue + shoes = /obj/item/clothing/shoes/jackboots/fast + /datum/outfit/ctf/red/post_equip(mob/living/carbon/human/H) var/obj/item/device/radio/R = H.ears R.set_frequency(SYND_FREQ) @@ -340,4 +372,8 @@ if(CTF.ctf_enabled && (user.ckey in CTF.team_members)) controlling = CTF icon_state = "dominator-[CTF.team]" + for(var/mob/M in player_list) + var/area/mob_area = get_area(M) + if(istype(mob_area, /area/ctf)) + M << "[user.real_name] has captured \the [src], claiming it for [CTF.team]! Go take it back!" break diff --git a/code/modules/awaymissions/maploader/reader.dm b/code/modules/awaymissions/maploader/reader.dm index f6a29a2f3ac..f43073fd5a7 100644 --- a/code/modules/awaymissions/maploader/reader.dm +++ b/code/modules/awaymissions/maploader/reader.dm @@ -3,7 +3,8 @@ ////////////////////////////////////////////////////////////// //global datum that will preload variables on atoms instanciation -var/global/dmm_suite/preloader/_preloader = null +var/global/use_preloader = FALSE +var/global/dmm_suite/preloader/_preloader = new /** @@ -174,14 +175,14 @@ var/global/dmm_suite/preloader/_preloader = null //first instance the /area and remove it from the members list index = members.len var/atom/instance - _preloader = new(members_attributes[index])//preloader for assigning set variables on atom creation + _preloader.setup(members_attributes[index])//preloader for assigning set variables on atom creation instance = locate(members[index]) var/turf/crds = locate(xcrd,ycrd,zcrd) if(crds) instance.contents.Add(crds) - if(_preloader && instance) + if(use_preloader && instance) _preloader.load(instance) members.Remove(members[index]) @@ -216,13 +217,13 @@ var/global/dmm_suite/preloader/_preloader = null //Instance an atom at (x,y,z) and gives it the variables in attributes /dmm_suite/proc/instance_atom(path,list/attributes, x, y, z) var/atom/instance - _preloader = new(attributes, path) + _preloader.setup(attributes, path) var/turf/T = locate(x,y,z) if(T) instance = new path (T)//first preloader pass - if(_preloader && instance)//second preloader pass, for those atoms that don't ..() in New() + if(use_preloader && instance)//second preloader pass, for those atoms that don't ..() in New() _preloader.load(instance) return instance @@ -321,7 +322,7 @@ var/global/dmm_suite/preloader/_preloader = null //atom creation method that preloads variables at creation /atom/New() - if(_preloader && (src.type == _preloader.target_path))//in case the instanciated atom is creating other atoms in New() + if(use_preloader && (src.type == _preloader.target_path))//in case the instanciated atom is creating other atoms in New() _preloader.load(src) . = ..() @@ -339,15 +340,13 @@ var/global/dmm_suite/preloader/_preloader = null var/list/attributes var/target_path -/dmm_suite/preloader/New(list/the_attributes, path) - .=..() - if(!the_attributes.len) - qdel(src) - return - attributes = the_attributes - target_path = path +/dmm_suite/preloader/proc/setup(list/the_attributes, path) + if(the_attributes.len) + use_preloader = TRUE + attributes = the_attributes + target_path = path /dmm_suite/preloader/proc/load(atom/what) for(var/attribute in attributes) what.vars[attribute] = attributes[attribute] - qdel(src) + use_preloader = FALSE diff --git a/code/modules/cargo/console.dm b/code/modules/cargo/console.dm index 65bc46f890e..42c71e8da14 100644 --- a/code/modules/cargo/console.dm +++ b/code/modules/cargo/console.dm @@ -18,9 +18,10 @@ var/obj/item/weapon/circuitboard/cargo/board = circuit contraband = board.contraband -/obj/machinery/computer/cargo/emag_act(mob/user) +/obj/machinery/computer/cargo/emag_act(mob/living/user) if(!emagged) - user << "Special supplies unlocked." + user.visible_message("[user] swipes a suspicious card through [src]!", + "You adjust [src]'s routing, unlocking special supplies.") emagged = TRUE /obj/machinery/computer/cargo/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, \ @@ -41,40 +42,38 @@ data["loan_dispatched"] = SSshuttle.shuttle_loan && SSshuttle.shuttle_loan.dispatched data["message"] = SSshuttle.centcom_message || "Remember to stamp and send back the supply manifests." - var/list/supplies = list() - supplies.len = all_supply_groups.len - for(var/group in all_supply_groups) - supplies[group] = list( - "name" = get_supply_group_name(group), - "packs" = list() - ) + data["supplies"] = list() for(var/pack in SSshuttle.supply_packs) - var/datum/supply_packs/P = SSshuttle.supply_packs[pack] + var/datum/supply_pack/P = SSshuttle.supply_packs[pack] + if(!data["supplies"][P.group]) + data["supplies"][P.group] = list( + "name" = P.group, + "packs" = list() + ) if((P.hidden && !emagged) || (P.contraband && !contraband)) continue - supplies[P.group]["packs"] += list(list( + data["supplies"][P.group]["packs"] += list(list( "name" = P.name, "cost" = P.cost, "id" = pack )) - data["supplies"] = supplies data["cart"] = list() for(var/datum/supply_order/SO in SSshuttle.shoppinglist) data["cart"] += list(list( - "object" = SO.object.name, - "cost" = SO.object.cost, - "id" = SO.ordernum + "object" = SO.pack.name, + "cost" = SO.pack.cost, + "id" = SO.id )) data["requests"] = list() for(var/datum/supply_order/SO in SSshuttle.requestlist) data["requests"] += list(list( - "object" = SO.object.name, - "cost" = SO.object.cost, - "orderedby" = SO.orderedby, - "comment" = SO.comment, - "id" = SO.ordernum + "object" = SO.pack.name, + "cost" = SO.pack.cost, + "orderer" = SO.orderer, + "reason" = SO.reason, + "id" = SO.id )) return data @@ -92,9 +91,9 @@ if(SSshuttle.supply.getDockedId() == "supply_home") SSshuttle.moveShuttle("supply", "supply_away", TRUE) say("The supply shuttle has departed.") - investigate_log("[key_name(usr)] has sent the supply shuttle away. Points: [SSshuttle.points]. Contents: [SSshuttle.sold_atoms].", "cargo") + investigate_log("[key_name(usr)] sent the supply shuttle away.", "cargo") else - investigate_log("[key_name(usr)] has called the supply shuttle. Points: [SSshuttle.points].", "cargo") // TODO: more robust logging here + investigate_log("[key_name(usr)] called the supply shuttle.", "cargo") say("The supply shuttle has been called and will arrive in [SSshuttle.supply.timeLeft(600)] minutes.") SSshuttle.moveShuttle("supply", "supply_home", TRUE) . = TRUE @@ -112,6 +111,7 @@ var/name = "*None Provided*" var/rank = "*None Provided*" + var/ckey = usr.ckey if(ishuman(usr)) var/mob/living/carbon/human/H = usr name = H.get_authentification_name() @@ -127,7 +127,7 @@ return var/turf/T = get_turf(src) - var/datum/supply_order/SO = SSshuttle.generateSupplyOrder(id, name, rank, reason) + var/datum/supply_order/SO = new(id, name, rank, ckey, reason) SO.generateRequisition(T) if(requestonly) SSshuttle.requestlist += SO @@ -137,7 +137,7 @@ if("remove") var/id = text2num(params["id"]) for(var/datum/supply_order/SO in SSshuttle.shoppinglist) - if(SO.ordernum == id) + if(SO.id == id) SSshuttle.shoppinglist -= SO . = TRUE break @@ -147,7 +147,7 @@ if("approve") var/id = text2num(params["id"]) for(var/datum/supply_order/SO in SSshuttle.requestlist) - if(SO.ordernum == id) + if(SO.id == id) SSshuttle.requestlist -= SO SSshuttle.shoppinglist += SO . = TRUE @@ -155,7 +155,7 @@ if("deny") var/id = text2num(params["id"]) for(var/datum/supply_order/SO in SSshuttle.requestlist) - if(SO.ordernum == id) + if(SO.id == id) SSshuttle.requestlist -= SO . = TRUE break diff --git a/code/modules/cargo/order.dm b/code/modules/cargo/order.dm index 3dff08e2173..1d73bb0332c 100644 --- a/code/modules/cargo/order.dm +++ b/code/modules/cargo/order.dm @@ -1,121 +1,91 @@ +/obj/item/weapon/paper/manifest + var/order_cost = 0 + var/order_id = 0 + var/errors = 0 + +/obj/item/weapon/paper/manifest/New(atom/A, id, cost) + ..() + order_id = id + order_cost = cost + + if(prob(MANIFEST_ERROR_CHANCE)) + errors |= MANIFEST_ERROR_NAME + if(prob(MANIFEST_ERROR_CHANCE)) + errors |= MANIFEST_ERROR_CONTENTS + if(prob(MANIFEST_ERROR_CHANCE)) + errors |= MANIFEST_ERROR_ITEM /datum/supply_order - var/ordernum - var/datum/supply_packs/object = null - var/orderedby = null - var/orderedbyRank - var/comment = null + var/id + var/orderer + var/orderer_rank + var/orderer_ckey + var/reason + var/datum/supply_pack/pack -/datum/supply_order/proc/generateRequisition(atom/_loc) - if(!object) - return +/datum/supply_order/New(pack, orderer, orderer_rank, orderer_ckey, reason) + id = SSshuttle.ordernum++ + src.pack = SSshuttle.supply_packs[pack] + src.orderer = orderer + src.orderer_rank = orderer_rank + src.orderer_ckey = orderer_ckey + src.reason = reason - var/obj/item/weapon/paper/reqform = new /obj/item/weapon/paper(_loc) - reqform.name = "requisition form - [object.name]" - reqform.info += "

[station_name] Supply Requisition Form


" - reqform.info += "INDEX: #[ordernum]
" - reqform.info += "REQUESTED BY: [orderedby]
" - reqform.info += "RANK: [orderedbyRank]
" - reqform.info += "REASON: [comment]
" - reqform.info += "SUPPLY CRATE TYPE: [object.name]
" - reqform.info += "ACCESS RESTRICTION: [get_access_desc(object.access)]
" - reqform.info += "CONTENTS:
" - reqform.info += object.manifest - reqform.info += "
" - reqform.info += "STAMP BELOW TO APPROVE THIS REQUISITION:
" +/datum/supply_order/proc/generateRequisition(turf/T) + var/obj/item/weapon/paper/P = new(T) - reqform.update_icon() //Fix for appearing blank when printed. + P.name = "requisition form - #[id] ([pack.name])" + P.info += "

[station_name()] Supply Requisition

" + P.info += "
" + P.info += "Order #[id]
" + P.info += "Item: [pack.name]
" + P.info += "Access Restrictions: [get_access_desc(pack.access)]
" + P.info += "Requested by: [orderer]
" + P.info += "Rank: [orderer_rank]
" + P.info += "Comment: [reason]
" - return reqform + P.update_icon() + return P -/datum/supply_order/proc/createObject(atom/_loc, errors=0) - if(!object) - return +/datum/supply_order/proc/generateManifest(obj/structure/closet/crate/C) + var/obj/item/weapon/paper/manifest/P = new(C, id, pack.cost) - //create the crate - var/atom/Crate = new object.containertype(_loc) - Crate.name = "[object.containername] [comment ? "([comment])":"" ]" - if(object.access) - Crate:req_access = list(text2num(object.access)) + var/station_name = (P.errors & MANIFEST_ERROR_NAME) ? new_station_name() : station_name() - //create the manifest slip - var/obj/item/weapon/paper/manifest/slip = new /obj/item/weapon/paper/manifest() - slip.erroneous = errors - slip.points = object.cost - slip.ordernumber = ordernum + P.name = "shipping manifest - #[id] ([pack.name])" + P.info += "

[command_name()] Shipping Manifest

" + P.info += "
" + P.info += "Order #[id]
" + P.info += "Destination: [station_name]
" + P.info += "Item: [pack.name]
" + P.info += "Contents:
" + P.info += "
    " + for(var/atom/movable/AM in C.contents - P) + if((P.errors & MANIFEST_ERROR_CONTENTS)) + if(prob(50)) + P.info += "
  • [AM.name]
  • " + else + continue + P.info += "
  • [AM.name]
  • " + P.info += "
" + P.info += "

Stamp below to confirm receipt of goods:

" - var/stationName = (errors & MANIFEST_ERROR_NAME) ? new_station_name() : station_name() - var/packagesAmt = SSshuttle.shoppinglist.len + ((errors & MANIFEST_ERROR_COUNT) ? rand(1,2) : 0) + P.update_icon() + P.loc = C + C.manifest = P + C.update_icon() - slip.info = "

[command_name()] Shipping Manifest



" - slip.info +="Order #[ordernum]
" - slip.info +="Destination: [stationName]
" - slip.info +="[packagesAmt] PACKAGES IN THIS SHIPMENT
" - slip.info +="CONTENTS:
    " + return P - //we now create the actual contents - var/list/contains - if(istype(object, /datum/supply_packs/misc/randomised)) - var/datum/supply_packs/misc/randomised/SO = object - contains = list() - if(object.contains.len) - for(var/j=1, j<=SO.num_contained, j++) - contains += pick(object.contains) - else - contains = object.contains +/datum/supply_order/proc/generate(turf/T) + var/obj/structure/closet/crate/C = pack.generate(T) + var/obj/item/weapon/paper/manifest/M = generateManifest(C) - for(var/typepath in contains) - if(!typepath) - continue - var/atom/A = new typepath(Crate) - if(object.amount && A.vars.Find("amount") && A:amount) - A:amount = object.amount - slip.info += "
  • [A.name]
  • " //add the item to the manifest (even if it was misplaced) - - if(istype(Crate, /obj/structure/closet/critter)) // critter crates do not actually spawn mobs yet and have no contains var, but the manifest still needs to list them - var/obj/structure/closet/critter/CritCrate = Crate - if(CritCrate.content_mob) - var/mob/crittername = CritCrate.content_mob - slip.info += "
  • [initial(crittername.name)]
  • " - - if((errors & MANIFEST_ERROR_ITEM)) - //secure and large crates cannot lose items - if(findtext("[object.containertype]", "/secure/") || findtext("[object.containertype]","/largecrate/")) - errors &= ~MANIFEST_ERROR_ITEM + if(M.errors & MANIFEST_ERROR_ITEM) + if(istype(C, /obj/structure/closet/crate/secure) || istype(C, /obj/structure/closet/crate/large)) + M.errors &= ~MANIFEST_ERROR_ITEM else - var/lostAmt = max(round(Crate.contents.len/10), 1) - //lose some of the items - while(--lostAmt >= 0) - qdel(pick(Crate.contents)) - - //manifest finalisation - slip.info += "

" - slip.info += "CHECK CONTENTS AND STAMP BELOW THE LINE TO CONFIRM RECEIPT OF GOODS
" // And now this is actually meaningful. - slip.loc = Crate - if(istype(Crate, /obj/structure/closet/crate)) - var/obj/structure/closet/crate/CR = Crate - CR.manifest = slip - CR.update_icon() - if(istype(Crate, /obj/structure/largecrate)) - var/obj/structure/largecrate/LC = Crate - LC.manifest = slip - LC.update_icon() - - return Crate - -/datum/subsystem/shuttle/proc/generateSupplyOrder(packId, _orderedby, _orderedbyRank, _comment) - if(!packId) - return - var/datum/supply_packs/P = supply_packs[packId] - if(!P) - return - - var/datum/supply_order/O = new() - O.ordernum = ordernum++ - O.object = P - O.orderedby = _orderedby - O.orderedbyRank = _orderedbyRank - O.comment = _comment - - return O - + var/lost = max(round(C.contents.len / 10), 1) + while(--lost >= 0) + qdel(pick(C.contents)) + return C diff --git a/code/datums/supplypacks.dm b/code/modules/cargo/packs.dm similarity index 66% rename from code/datums/supplypacks.dm rename to code/modules/cargo/packs.dm index 8c6aa69ebdb..efdb9522d1b 100644 --- a/code/datums/supplypacks.dm +++ b/code/modules/cargo/packs.dm @@ -1,79 +1,33 @@ -//SUPPLY PACKS -//NOTE: only secure crate types use the access var (and are lockable) -//NOTE: hidden packs only show up when the computer has been hacked. -//ANOTHER NOTE: Contraband is obtainable through modified supplycomp circuitboards. -//BIG NOTE: Don't add living things to crates, that's bad, it will break the shuttle. -//NEW NOTE: Do NOT set the price of any crates below 7 points. Doing so allows infinite points. +/datum/supply_pack + var/name = "Crate" + var/group = "" + var/hidden = FALSE + var/contraband = FALSE + var/cost = 7 // Minimum cost, or infinite points are possible. + var/access = FALSE + var/list/contains = null + var/crate_name = "crate" + var/crate_type = /obj/structure/closet/crate + var/dangerous = FALSE // Should we message admins? -// Supply Groups -var/const/supply_emergency = 1 -var/const/supply_security = 2 -var/const/supply_engineer = 3 -var/const/supply_medical = 4 -var/const/supply_science = 5 -var/const/supply_organic = 6 -var/const/supply_materials = 7 -var/const/supply_misc = 8 +/datum/supply_pack/proc/generate(turf/T) + var/obj/structure/closet/crate/C = new crate_type(T) + C.name = crate_name -var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engineer,supply_medical,supply_science,supply_organic,supply_materials,supply_misc) - -/proc/get_supply_group_name(cat) - switch(cat) - if(1) - return "Emergency" - if(2) - return "Security" - if(3) - return "Engineering" - if(4) - return "Medical" - if(5) - return "Science" - if(6) - return "Food & Livestock" - if(7) - return "Raw Materials" - if(8) - return "Miscellaneous" - - -/datum/supply_packs - var/name = null - var/list/contains = list() - var/manifest = "" - var/amount = null - var/cost = null - var/containertype = /obj/structure/closet/crate - var/containername = null - var/access = null - var/hidden = 0 - var/contraband = 0 - var/group = supply_misc - - -/datum/supply_packs/New() - manifest += "
    " - for(var/path in contains) - if(!path) - continue - var/atom/movable/AM = path - manifest += "
  • [initial(AM.name)]
  • " - manifest += "
" - -////// Use the sections to keep things tidy please /Malkevin + for(var/item in contains) + new item(C) + return C ////////////////////////////////////////////////////////////////////////////// //////////////////////////// Emergency /////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// -/datum/supply_packs/emergency // Section header - use these to set default supply group and crate type for sections - name = "HEADER" // Use "HEADER" to denote section headers, this is needed for the supply computers to filter them - containertype = /obj/structure/closet/crate/internals - group = supply_emergency +/datum/supply_pack/emergency + group = "Emergency" - -/datum/supply_packs/emergency/evac - name = "Emergency equipment" +/datum/supply_pack/emergency/equipment + name = "Emergency Equipment" + cost = 35 contains = list(/mob/living/simple_animal/bot/floorbot, /mob/living/simple_animal/bot/floorbot, /mob/living/simple_animal/bot/medbot, @@ -88,23 +42,24 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine /obj/item/clothing/mask/gas, /obj/item/clothing/mask/gas, /obj/item/clothing/mask/gas) - cost = 35 - containertype = /obj/structure/closet/crate/internals - containername = "emergency crate" + crate_name = "emergency crate" + crate_type = /obj/structure/closet/crate/internals -/datum/supply_packs/emergency/internals +/datum/supply_pack/emergency/internals name = "Internals Crate" + cost = 10 contains = list(/obj/item/clothing/mask/gas, /obj/item/clothing/mask/gas, /obj/item/clothing/mask/gas, /obj/item/weapon/tank/internals/air, /obj/item/weapon/tank/internals/air, /obj/item/weapon/tank/internals/air) - cost = 10 - containername = "internals crate" + crate_name = "internals crate" + crate_type = /obj/structure/closet/crate/internals -/datum/supply_packs/emergency/firefighting +/datum/supply_pack/emergency/firefighting name = "Firefighting Crate" + cost = 10 contains = list(/obj/item/clothing/suit/fire/firefighter, /obj/item/clothing/suit/fire/firefighter, /obj/item/clothing/mask/gas, @@ -117,176 +72,175 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine /obj/item/weapon/extinguisher, /obj/item/clothing/head/hardhat/red, /obj/item/clothing/head/hardhat/red) - cost = 10 - containertype = /obj/structure/closet/crate - containername = "firefighting crate" + crate_name = "firefighting crate" -/datum/supply_packs/emergency/atmostank +/datum/supply_pack/emergency/atmostank name = "Firefighting Watertank" - contains = list(/obj/item/weapon/watertank/atmos) cost = 10 - containertype = /obj/structure/closet/crate/secure - containername = "firefighting watertank crate" access = access_atmospherics + contains = list(/obj/item/weapon/watertank/atmos) + crate_name = "firefighting watertank crate" + crate_type = /obj/structure/closet/crate/secure -/datum/supply_packs/emergency/weedcontrol +/datum/supply_pack/emergency/radiation + name = "Radiation Protection Crate" + cost = 10 + contains = list(/obj/item/clothing/head/radiation, + /obj/item/clothing/head/radiation, + /obj/item/clothing/suit/radiation, + /obj/item/clothing/suit/radiation) + crate_name = "radiation protection crate" + crate_type = /obj/structure/closet/crate/radiation + +/datum/supply_pack/emergency/weedcontrol name = "Weed Control Crate" + cost = 15 + access = access_hydroponics contains = list(/obj/item/weapon/scythe, /obj/item/clothing/mask/gas, /obj/item/weapon/grenade/chem_grenade/antiweed, /obj/item/weapon/grenade/chem_grenade/antiweed) - cost = 15 - containertype = /obj/structure/closet/crate/secure/hydrosec - containername = "weed control crate" - access = access_hydroponics + crate_name = "weed control crate" + crate_type = /obj/structure/closet/crate/secure/hydroponics -/datum/supply_packs/emergency/specialops - name = "Special Ops supplies" +/datum/supply_pack/emergency/specialops + name = "Special Ops Supplies" + hidden = TRUE + cost = 20 contains = list(/obj/item/weapon/storage/box/emps, /obj/item/weapon/grenade/smokebomb, /obj/item/weapon/grenade/smokebomb, /obj/item/weapon/grenade/smokebomb, /obj/item/weapon/pen/sleepy, /obj/item/weapon/grenade/chem_grenade/incendiary) - cost = 20 - containertype = /obj/structure/closet/crate - containername = "special ops crate" - hidden = 1 + crate_name = "special ops crate" + crate_type = /obj/structure/closet/crate -/datum/supply_packs/emergency/syndicate - name = "ERROR_NULL_ENTRY" - contains = list(/obj/item/weapon/storage/box/syndicate) +/datum/supply_pack/emergency/syndicate + name = "NULL_ENTRY" + hidden = TRUE cost = 140 - containertype = /obj/structure/closet/crate - containername = "crate" - hidden = 1 + contains = list(/obj/item/weapon/storage/box/syndicate) + crate_name = "crate" + crate_type = /obj/structure/closet/crate + dangerous = TRUE ////////////////////////////////////////////////////////////////////////////// //////////////////////////// Security //////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// -/datum/supply_packs/security - name = "HEADER" - containertype = /obj/structure/closet/crate/secure/gear +/datum/supply_pack/security + group = "Security" access = access_security - group = supply_security + crate_type = /obj/structure/closet/crate/secure/gear - -/datum/supply_packs/security/supplies +/datum/supply_pack/security/supplies name = "Security Supplies Crate" + cost = 10 contains = list(/obj/item/weapon/storage/box/flashbangs, /obj/item/weapon/storage/box/teargas, /obj/item/weapon/storage/box/flashes, /obj/item/weapon/storage/box/handcuffs) - cost = 10 - containername = "security supply crate" + crate_name = "security supply crate" -////// Armor: Basic - -/datum/supply_packs/security/helmets +/datum/supply_pack/security/helmets name = "Helmets Crate" + cost = 10 contains = list(/obj/item/clothing/head/helmet/sec, /obj/item/clothing/head/helmet/sec, /obj/item/clothing/head/helmet/sec) - cost = 10 - containername = "helmet crate" + crate_name = "helmet crate" -/datum/supply_packs/security/armor +/datum/supply_pack/security/armor name = "Armor Crate" + cost = 10 contains = list(/obj/item/clothing/suit/armor/vest, /obj/item/clothing/suit/armor/vest, /obj/item/clothing/suit/armor/vest) - cost = 10 - containername = "armor crate" + crate_name = "armor crate" -////// Weapons: Basic - -/datum/supply_packs/security/baton +/datum/supply_pack/security/baton name = "Stun Batons Crate" + cost = 10 contains = list(/obj/item/weapon/melee/baton/loaded, /obj/item/weapon/melee/baton/loaded, /obj/item/weapon/melee/baton/loaded) - cost = 10 - containername = "stun baton crate" + crate_name = "stun baton crate" -/datum/supply_packs/security/laser +/datum/supply_pack/security/laser name = "Lasers Crate" + cost = 15 contains = list(/obj/item/weapon/gun/energy/laser, /obj/item/weapon/gun/energy/laser, /obj/item/weapon/gun/energy/laser) - cost = 15 - containername = "laser crate" + crate_name = "laser crate" -/datum/supply_packs/security/taser - name = "Stun Guns Crate" +/datum/supply_pack/security/taser + name = "Taser Crate" + cost = 15 contains = list(/obj/item/weapon/gun/energy/gun/advtaser, /obj/item/weapon/gun/energy/gun/advtaser, /obj/item/weapon/gun/energy/gun/advtaser) - cost = 15 - containername = "stun gun crate" + crate_name = "taser crate" -/datum/supply_packs/security/disabler +/datum/supply_pack/security/disabler name = "Disabler Crate" + cost = 10 contains = list(/obj/item/weapon/gun/energy/disabler, /obj/item/weapon/gun/energy/disabler, /obj/item/weapon/gun/energy/disabler) - cost = 10 - containername = "disabler crate" + crate_name = "disabler crate" -/datum/supply_packs/security/forensics +/datum/supply_pack/security/forensics name = "Forensics Crate" + cost = 20 contains = list(/obj/item/device/detective_scanner, /obj/item/weapon/storage/box/evidence, /obj/item/device/camera, /obj/item/device/taperecorder, /obj/item/toy/crayon/white, /obj/item/clothing/head/det_hat) - cost = 20 - containername ="forensics crate" + crate_name = "forensics crate" -///// Armory stuff - -/datum/supply_packs/security/armory - name = "HEADER" - containertype = /obj/structure/closet/crate/secure/weapon +/datum/supply_pack/security/armory access = access_armory + crate_type = /obj/structure/closet/crate/secure/weapon -///// Armor: Specialist - -/datum/supply_packs/security/armory/riothelmets +/datum/supply_pack/security/armory/riothelmets name = "Riot Helmets Crate" + cost = 15 contains = list(/obj/item/clothing/head/helmet/riot, /obj/item/clothing/head/helmet/riot, /obj/item/clothing/head/helmet/riot) - cost = 15 - containername = "riot helmets crate" + crate_name = "riot helmets crate" -/datum/supply_packs/security/armory/riotarmor +/datum/supply_pack/security/armory/riotarmor name = "Riot Armor Crate" + cost = 15 contains = list(/obj/item/clothing/suit/armor/riot, /obj/item/clothing/suit/armor/riot, /obj/item/clothing/suit/armor/riot) - cost = 15 - containername = "riot armor crate" + crate_name = "riot armor crate" -/datum/supply_packs/security/armory/riotshields +/datum/supply_pack/security/armory/riotshields name = "Riot Shields Crate" + cost = 20 contains = list(/obj/item/weapon/shield/riot, /obj/item/weapon/shield/riot, /obj/item/weapon/shield/riot) - cost = 20 - containername = "riot shields crate" + crate_name = "riot shields crate" -/datum/supply_packs/security/armory/bulletarmor +/datum/supply_pack/security/armory/bulletarmor name = "Bulletproof Armor Crate" + cost = 15 contains = list(/obj/item/clothing/suit/armor/bulletproof, /obj/item/clothing/suit/armor/bulletproof, /obj/item/clothing/suit/armor/bulletproof) - cost = 15 - containername = "tactical armor crate" + crate_name = "bulletproof armor crate" -/datum/supply_packs/security/armory/swat - name = "SWAT gear crate" +/datum/supply_pack/security/armory/swat + name = "SWAT Crate" + cost = 60 contains = list(/obj/item/clothing/head/helmet/swat/nanotrasen, /obj/item/clothing/head/helmet/swat/nanotrasen, /obj/item/clothing/suit/space/swat, @@ -297,40 +251,39 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine /obj/item/clothing/mask/gas/sechailer/swat, /obj/item/weapon/storage/belt/military/assault, /obj/item/weapon/storage/belt/military/assault) - cost = 60 - containername = "assault armor crate" + crate_name = "swat crate" -/datum/supply_packs/security/armory/laserarmor +/datum/supply_pack/security/armory/laserarmor name = "Reflector Vest Crate" - contains = list(/obj/item/clothing/suit/armor/laserproof, - /obj/item/clothing/suit/armor/laserproof) // Only two vests to keep costs down for balance cost = 20 - containertype = /obj/structure/closet/crate/secure/plasma - containername = "reflector vest crate" + contains = list(/obj/item/clothing/suit/armor/laserproof, + /obj/item/clothing/suit/armor/laserproof) + crate_name = "reflector vest crate" + crate_type = /obj/structure/closet/crate/secure/plasma -/////// Weapons: Specialist - -/datum/supply_packs/security/armory/ballistic +/datum/supply_pack/security/armory/ballistic name = "Combat Shotguns Crate" + cost = 20 contains = list(/obj/item/weapon/gun/projectile/shotgun/automatic/combat, /obj/item/weapon/gun/projectile/shotgun/automatic/combat, /obj/item/weapon/gun/projectile/shotgun/automatic/combat, /obj/item/weapon/storage/belt/bandolier, /obj/item/weapon/storage/belt/bandolier, /obj/item/weapon/storage/belt/bandolier) - cost = 20 - containername = "combat shotgun crate" + crate_name = "combat shotguns crate" -/datum/supply_packs/security/armory/expenergy +/datum/supply_pack/security/armory/energy name = "Energy Guns Crate" - contains = list(/obj/item/weapon/gun/energy/gun, - /obj/item/weapon/gun/energy/gun) // Only two guns to keep costs down cost = 25 - containertype = /obj/structure/closet/crate/secure/plasma - containername = "energy gun crate" + contains = list(/obj/item/weapon/gun/energy/gun, + /obj/item/weapon/gun/energy/gun) + crate_name = "energy gun crate" + crate_type = /obj/structure/closet/crate/secure/plasma -/datum/supply_packs/security/armory/eweapons +/datum/supply_pack/security/armory/fire name = "Incendiary Weapons Crate" + cost = 15 + access = access_heads contains = list(/obj/item/weapon/flamethrower/full, /obj/item/weapon/tank/internals/plasma, /obj/item/weapon/tank/internals/plasma, @@ -338,71 +291,69 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine /obj/item/weapon/grenade/chem_grenade/incendiary, /obj/item/weapon/grenade/chem_grenade/incendiary, /obj/item/weapon/grenade/chem_grenade/incendiary) - cost = 15 // its a fecking flamethrower and some plasma, why the shit did this cost so much before!? - containertype = /obj/structure/closet/crate/secure/plasma - containername = "incendiary weapons crate" - access = access_heads + crate_name = "incendiary weapons crate" + crate_type = /obj/structure/closet/crate/secure/plasma + dangerous = TRUE -/datum/supply_packs/security/armory/wt550 +/datum/supply_pack/security/armory/wt550 name = "WT-550 Auto Rifle Crate" + cost = 35 contains = list(/obj/item/weapon/gun/projectile/automatic/wt550, /obj/item/weapon/gun/projectile/automatic/wt550) - cost = 35 - containername = "auto rifle crate" + crate_name = "auto rifle crate" -/datum/supply_packs/security/armory/wt550ammo - name = "WT-550 Rifle Ammo Crate" +/datum/supply_pack/security/armory/wt550ammo + name = "WT-550 Auto Rifle Ammo Crate" + cost = 30 contains = list(/obj/item/ammo_box/magazine/wt550m9, /obj/item/ammo_box/magazine/wt550m9, /obj/item/ammo_box/magazine/wt550m9, - /obj/item/ammo_box/magazine/wt550m9,) - cost = 30 - containername = "auto rifle ammo crate" + /obj/item/ammo_box/magazine/wt550m9) + crate_name = "auto rifle ammo crate" -/////// Implants & etc - -/datum/supply_packs/security/armory/loyalty +/datum/supply_pack/security/armory/loyalty name = "Loyalty Implants Crate" - contains = list (/obj/item/weapon/storage/lockbox/loyalty) cost = 40 - containername = "loyalty implant crate" + contains = list(/obj/item/weapon/storage/lockbox/loyalty) + crate_name = "loyalty implant crate" -/datum/supply_packs/security/armory/trackingimp +/datum/supply_pack/security/armory/trackingimp name = "Tracking Implants Crate" - contains = list (/obj/item/weapon/storage/box/trackimp) cost = 20 - containername = "tracking implant crate" + contains = list(/obj/item/weapon/storage/box/trackimp) + crate_name = "tracking implant crate" -/datum/supply_packs/security/armory/chemimp +/datum/supply_pack/security/armory/chemimp name = "Chemical Implants Crate" - contains = list (/obj/item/weapon/storage/box/chemimp) cost = 20 - containername = "chemical implant crate" + contains = list(/obj/item/weapon/storage/box/chemimp) + crate_name = "chemical implant crate" -/datum/supply_packs/security/armory/exileimp +/datum/supply_pack/security/armory/exileimp name = "Exile Implants Crate" - contains = list (/obj/item/weapon/storage/box/exileimp) cost = 30 - containername = "exile implant crate" + contains = list(/obj/item/weapon/storage/box/exileimp) + crate_name = "exile implant crate" -/datum/supply_packs/security/securitybarriers +/datum/supply_pack/security/securitybarriers name = "Security Barriers Crate" contains = list(/obj/item/weapon/grenade/barrier, /obj/item/weapon/grenade/barrier, /obj/item/weapon/grenade/barrier, /obj/item/weapon/grenade/barrier) cost = 20 - containername = "security barriers crate" + crate_name = "security barriers crate" -/datum/supply_packs/security/firingpins +/datum/supply_pack/security/firingpins name = "Standard Firing Pins Crate" + cost = 10 contains = list(/obj/item/weapon/storage/box/firingpins, /obj/item/weapon/storage/box/firingpins) - cost = 10 - containername = "firing pins crate" + crate_name = "firing pins crate" -/datum/supply_packs/security/securityclothes +/datum/supply_pack/security/securityclothes name = "Security Clothing Crate" + cost = 30 contains = list(/obj/item/clothing/under/rank/security/navyblue, /obj/item/clothing/under/rank/security/navyblue, /obj/item/clothing/suit/security/officer, @@ -415,36 +366,30 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine /obj/item/clothing/under/rank/head_of_security/navyblue, /obj/item/clothing/suit/security/hos, /obj/item/clothing/head/beret/sec/navyhos) - cost = 30 - containername = "security clothing crate" + crate_name = "security clothing crate" -/////// Joke Crate Inbound - -/datum/supply_packs/security/justiceinbound +/datum/supply_pack/security/justiceinbound name = "Standard Justice Enforcer Crate" + cost = 80 //justice comes at a price. An expensive, noisy price. contains = list(/obj/item/clothing/head/helmet/justice, /obj/item/clothing/mask/gas/sechailer) - cost = 80 //justice comes at a price. An expensive, noisy price. - containername = "justice enforcer crate" - + crate_name = "justice enforcer crate" ////////////////////////////////////////////////////////////////////////////// //////////////////////////// Engineering ///////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// -/datum/supply_packs/engineering - name = "HEADER" - group = supply_engineer +/datum/supply_pack/engineering + group = "Engineering" - -/datum/supply_packs/engineering/fueltank +/datum/supply_pack/engineering/fueltank name = "Fuel Tank Crate" - contains = list(/obj/structure/reagent_dispensers/fueltank) cost = 8 - containertype = /obj/structure/largecrate - containername = "fuel tank crate" + contains = list(/obj/structure/reagent_dispensers/fueltank) + crate_name = "fuel tank crate" + crate_type = /obj/structure/closet/crate/large -/datum/supply_packs/engineering/tools //the most robust crate +/datum/supply_pack/engineering/tools name = "Toolbox Crate" contains = list(/obj/item/weapon/storage/toolbox/electrical, /obj/item/weapon/storage/toolbox/electrical, @@ -453,26 +398,27 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine /obj/item/weapon/storage/toolbox/mechanical, /obj/item/weapon/storage/toolbox/mechanical) cost = 10 - containername = "electrical maintenance crate" + crate_name = "toolbox crate" -/datum/supply_packs/engineering/powergamermitts +/datum/supply_pack/engineering/powergamermitts name = "Insulated Gloves Crate" + cost = 20 //Made of pure-grade bullshittinium contains = list(/obj/item/clothing/gloves/color/yellow, /obj/item/clothing/gloves/color/yellow, /obj/item/clothing/gloves/color/yellow) - cost = 20 //Made of pure-grade bullshittinium - containername = "insulated gloves crate" + crate_name = "insulated gloves crate" -/datum/supply_packs/engineering/power +/datum/supply_pack/engineering/power name = "Powercell Crate" - contains = list(/obj/item/weapon/stock_parts/cell/high, //Changed to an extra high powercell because normal cells are useless + cost = 10 + contains = list(/obj/item/weapon/stock_parts/cell/high, /obj/item/weapon/stock_parts/cell/high, /obj/item/weapon/stock_parts/cell/high) - cost = 10 - containername = "electrical maintenance crate" + crate_name = "electrical maintenance crate" -/datum/supply_packs/engineering/engiequipment +/datum/supply_pack/engineering/engiequipment name = "Engineering Gear Crate" + cost = 10 contains = list(/obj/item/weapon/storage/belt/utility, /obj/item/weapon/storage/belt/utility, /obj/item/weapon/storage/belt/utility, @@ -485,11 +431,24 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine /obj/item/clothing/head/hardhat, /obj/item/clothing/head/hardhat, /obj/item/clothing/head/hardhat) - cost = 10 - containername = "engineering gear crate" + crate_name = "engineering gear crate" -/datum/supply_packs/engineering/solar - name = "Solar Pack Crate" +/datum/supply_pack/engineering/engine/spacesuit + name = "Space Suit Crate" + cost = 30 + access = access_eva + contains = list(/obj/item/clothing/suit/space, + /obj/item/clothing/suit/space, + /obj/item/clothing/head/helmet/space, + /obj/item/clothing/head/helmet/space, + /obj/item/clothing/mask/breath, + /obj/item/clothing/mask/breath,) + crate_name = "space suit crate" + crate_type = /obj/structure/closet/crate/secure + +/datum/supply_pack/engineering/solar + name = "Solar Panel Crate" + cost = 20 contains = list(/obj/item/solar_assembly, /obj/item/solar_assembly, /obj/item/solar_assembly, @@ -510,45 +469,46 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine /obj/item/solar_assembly, /obj/item/solar_assembly, /obj/item/solar_assembly, - /obj/item/solar_assembly, // 21 Solar Assemblies. 1 Extra for the controller + /obj/item/solar_assembly, /obj/item/weapon/circuitboard/solar_control, /obj/item/weapon/electronics/tracker, /obj/item/weapon/paper/solar) - cost = 20 - containername = "solar pack crate" + crate_name = "solar panel crate" -/datum/supply_packs/engineering/engine +/datum/supply_pack/engineering/engine name = "Emitter Crate" + cost = 10 + access = access_ce contains = list(/obj/machinery/power/emitter, /obj/machinery/power/emitter) - cost = 10 - containertype = /obj/structure/closet/crate/secure - containername = "emitter crate" - access = access_ce + crate_name = "emitter crate" + crate_type = /obj/structure/closet/crate/secure + dangerous = TRUE -/datum/supply_packs/engineering/engine/field_gen +/datum/supply_pack/engineering/engine/field_gen name = "Field Generator Crate" + cost = 10 contains = list(/obj/machinery/field/generator, /obj/machinery/field/generator) - cost = 10 - containername = "field generator crate" + crate_name = "field generator crate" -/datum/supply_packs/engineering/engine/sing_gen +/datum/supply_pack/engineering/engine/sing_gen name = "Singularity Generator Crate" - contains = list(/obj/machinery/the_singularitygen) cost = 10 - containername = "singularity generator crate" + contains = list(/obj/machinery/the_singularitygen) + crate_name = "singularity generator crate" -/datum/supply_packs/engineering/engine/collector +/datum/supply_pack/engineering/engine/collector name = "Collector Crate" + cost = 10 contains = list(/obj/machinery/power/rad_collector, /obj/machinery/power/rad_collector, /obj/machinery/power/rad_collector) - cost = 10 - containername = "collector crate" + crate_name = "collector crate" -/datum/supply_packs/engineering/engine/PA +/datum/supply_pack/engineering/engine/PA name = "Particle Accelerator Crate" + cost = 25 contains = list(/obj/structure/particle_accelerator/fuel_chamber, /obj/machinery/particle_accelerator/control_box, /obj/structure/particle_accelerator/particle_emitter/center, @@ -556,34 +516,28 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine /obj/structure/particle_accelerator/particle_emitter/right, /obj/structure/particle_accelerator/power_box, /obj/structure/particle_accelerator/end_cap) - cost = 25 - containername = "particle accelerator crate" + crate_name = "particle accelerator crate" -/datum/supply_packs/engineering/engine/spacesuit - name = "Space Suit Crate" - contains = list(/obj/item/clothing/suit/space, - /obj/item/clothing/suit/space, - /obj/item/clothing/head/helmet/space, - /obj/item/clothing/head/helmet/space, - /obj/item/clothing/mask/breath, - /obj/item/clothing/mask/breath,) - cost = 30 - containertype = /obj/structure/closet/crate/secure - containername = "space suit crate" - access = access_eva +/datum/supply_pack/engineering/engine/supermatter_shard + name = "Supermatter Shard Crate" + cost = 100 + access = access_ce + contains = list(/obj/machinery/power/supermatter_shard) + crate_name = "supermatter shard crate" + crate_type = /obj/structure/closet/crate/secure + dangerous = TRUE ////////////////////////////////////////////////////////////////////////////// //////////////////////////// Medical ///////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// -/datum/supply_packs/medical - name = "HEADER" - containertype = /obj/structure/closet/crate/medical - group = supply_medical +/datum/supply_pack/medical + group = "Medical" + crate_type = /obj/structure/closet/crate/medical - -/datum/supply_packs/medical/supplies +/datum/supply_pack/medical/supplies name = "Medical Supplies Crate" + cost = 20 contains = list(/obj/item/weapon/reagent_containers/glass/bottle/charcoal, /obj/item/weapon/reagent_containers/glass/bottle/charcoal, /obj/item/weapon/reagent_containers/glass/bottle/epinephrine, @@ -606,54 +560,53 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine /obj/item/weapon/storage/box/beakers, /obj/item/weapon/storage/box/syringes, /obj/item/weapon/storage/box/bodybags) - cost = 20 - containertype = /obj/structure/closet/crate/medical - containername = "medical supplies crate" + crate_name = "medical supplies crate" -/datum/supply_packs/medical/firstaid - name = "First Aid Kits Crate" +/datum/supply_pack/medical/firstaid + name = "First Aid Kit Crate" + cost = 10 contains = list(/obj/item/weapon/storage/firstaid/regular, /obj/item/weapon/storage/firstaid/regular, /obj/item/weapon/storage/firstaid/regular, /obj/item/weapon/storage/firstaid/regular) - cost = 10 - containername = "first aid kits crate" + crate_name = "first aid kit crate" -/datum/supply_packs/medical/firstaidbruises - name = "Bruise Treatment Kits Crate" +/datum/supply_pack/medical/firstaidbruises + name = "Bruise Treatment Kit Crate" + cost = 10 contains = list(/obj/item/weapon/storage/firstaid/brute, /obj/item/weapon/storage/firstaid/brute, /obj/item/weapon/storage/firstaid/brute) - cost = 10 - containername = "brute trauma first aid kits crate" + crate_name = "brute treatment kit crate" -/datum/supply_packs/medical/firstaidburns - name = "Burns Treatment Kits Crate" +/datum/supply_pack/medical/firstaidburns + name = "Burn Treatment Kit Crate" + cost = 10 contains = list(/obj/item/weapon/storage/firstaid/fire, /obj/item/weapon/storage/firstaid/fire, /obj/item/weapon/storage/firstaid/fire) - cost = 10 - containername = "fire first aid kits crate" + crate_name = "burn treatment kit crate" -/datum/supply_packs/medical/firstaidtoxins - name = "Toxin Treatment Kits Crate" +/datum/supply_pack/medical/firstaidtoxins + name = "Toxin Treatment Kit Crate" + cost = 10 contains = list(/obj/item/weapon/storage/firstaid/toxin, /obj/item/weapon/storage/firstaid/toxin, /obj/item/weapon/storage/firstaid/toxin) - cost = 10 - containername = "toxin first aid kits crate" + crate_name = "toxin treatment kit crate" -/datum/supply_packs/medical/firstaidoxygen - name = "Oxygen Deprivation Kits Crate" +/datum/supply_pack/medical/firstaidoxygen + name = "Oxygen Deprivation Kit Crate" + cost = 10 contains = list(/obj/item/weapon/storage/firstaid/o2, /obj/item/weapon/storage/firstaid/o2, /obj/item/weapon/storage/firstaid/o2) - cost = 10 - containername = "oxygen deprivation kits crate" + crate_name = "oxygen deprivation kit crate" - -/datum/supply_packs/medical/virus +/datum/supply_pack/medical/virus name = "Virus Crate" + cost = 25 + access = access_cmo contains = list(/obj/item/weapon/reagent_containers/glass/bottle/flu_virion, /obj/item/weapon/reagent_containers/glass/bottle/cold, /obj/item/weapon/reagent_containers/glass/bottle/epiglottis_virion, @@ -668,14 +621,13 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine /obj/item/weapon/storage/box/syringes, /obj/item/weapon/storage/box/beakers, /obj/item/weapon/reagent_containers/glass/bottle/mutagen) - cost = 25 - containertype = /obj/structure/closet/crate/secure/plasma - containername = "virus crate" - access = access_cmo + crate_name = "virus crate" + crate_type = /obj/structure/closet/crate/secure/plasma + dangerous = TRUE - -/datum/supply_packs/medical/bloodpacks +/datum/supply_pack/medical/bloodpacks name = "Blood Pack Variety Crate" + cost = 35 contains = list(/obj/item/weapon/reagent_containers/blood/empty, /obj/item/weapon/reagent_containers/blood/empty, /obj/item/weapon/reagent_containers/blood/APlus, @@ -684,29 +636,28 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine /obj/item/weapon/reagent_containers/blood/BMinus, /obj/item/weapon/reagent_containers/blood/OPlus, /obj/item/weapon/reagent_containers/blood/OMinus) - cost = 35 - containertype = /obj/structure/closet/crate/freezer - containername = "blood pack crate" + crate_name = "blood pack crate" + crate_type = /obj/structure/closet/crate/freezer -/datum/supply_packs/medical/iv_drip +/datum/supply_pack/medical/iv_drip name = "IV Drip Crate" - contains = list(/obj/machinery/iv_drip) cost = 30 - containertype = /obj/structure/closet/crate/secure - containername = "iv drip crate" access = access_cmo + contains = list(/obj/machinery/iv_drip) + crate_name = "iv drip crate" + crate_type = /obj/structure/closet/crate/secure ////////////////////////////////////////////////////////////////////////////// //////////////////////////// Science ///////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// -/datum/supply_packs/science - name = "HEADER" - group = supply_science +/datum/supply_pack/science + group = "Science" - -/datum/supply_packs/science/robotics +/datum/supply_pack/science/robotics name = "Robotics Assembly Crate" + cost = 10 + access = access_robotics contains = list(/obj/item/device/assembly/prox_sensor, /obj/item/device/assembly/prox_sensor, /obj/item/device/assembly/prox_sensor, @@ -714,30 +665,32 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine /obj/item/weapon/storage/box/flashes, /obj/item/weapon/stock_parts/cell/high, /obj/item/weapon/stock_parts/cell/high) - cost = 10 - containertype = /obj/structure/closet/crate/secure - containername = "robotics assembly crate" - access = access_robotics + crate_name = "robotics assembly crate" + crate_type = /obj/structure/closet/crate/secure -/datum/supply_packs/science/robotics/mecha_ripley +/datum/supply_pack/science/robotics/mecha_ripley name = "Circuit Crate (Ripley APLU)" - contains = list(/obj/item/weapon/book/manual/ripley_build_and_repair, - /obj/item/weapon/circuitboard/mecha/ripley/main, //TEMPORARY due to lack of circuitboard printer - /obj/item/weapon/circuitboard/mecha/ripley/peripherals) //TEMPORARY due to lack of circuitboard printer cost = 30 - containertype = /obj/structure/closet/crate/secure - containername = "\improper APLU Ripley circuit crate" + access = access_robotics + contains = list(/obj/item/weapon/book/manual/ripley_build_and_repair, + /obj/item/weapon/circuitboard/mecha/ripley/main, + /obj/item/weapon/circuitboard/mecha/ripley/peripherals) + crate_name = "\improper APLU Ripley circuit crate" + crate_type = /obj/structure/closet/crate/secure -/datum/supply_packs/science/robotics/mecha_odysseus +/datum/supply_pack/science/robotics/mecha_odysseus name = "Circuit Crate (Odysseus)" - contains = list(/obj/item/weapon/circuitboard/mecha/odysseus/peripherals, //TEMPORARY due to lack of circuitboard printer - /obj/item/weapon/circuitboard/mecha/odysseus/main) //TEMPORARY due to lack of circuitboard printer cost = 25 - containertype = /obj/structure/closet/crate/secure - containername = "\improper Odysseus circuit crate" + access = access_robotics + contains = list(/obj/item/weapon/circuitboard/mecha/odysseus/peripherals, + /obj/item/weapon/circuitboard/mecha/odysseus/main) + crate_name = "\improper Odysseus circuit crate" + crate_type = /obj/structure/closet/crate/secure -/datum/supply_packs/science/plasma +/datum/supply_pack/science/plasma name = "Plasma Assembly Crate" + cost = 10 + access = access_tox_storage contains = list(/obj/item/weapon/tank/internals/plasma, /obj/item/weapon/tank/internals/plasma, /obj/item/weapon/tank/internals/plasma, @@ -750,45 +703,42 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine /obj/item/device/assembly/timer, /obj/item/device/assembly/timer, /obj/item/device/assembly/timer) - cost = 10 - containertype = /obj/structure/closet/crate/secure/plasma - containername = "plasma assembly crate" - access = access_tox_storage - group = supply_science + crate_name = "plasma assembly crate" + crate_type = /obj/structure/closet/crate/secure/plasma -/datum/supply_packs/science/shieldwalls +/datum/supply_pack/science/shieldwalls name = "Shield Generators" + cost = 20 + access = access_teleporter contains = list(/obj/machinery/shieldwallgen, /obj/machinery/shieldwallgen, /obj/machinery/shieldwallgen, /obj/machinery/shieldwallgen) - cost = 20 - containertype = /obj/structure/closet/crate/secure - containername = "shield generators crate" - access = access_teleporter + crate_name = "shield generators crate" + crate_type = /obj/structure/closet/crate/secure -/datum/supply_packs/science/transfer_valves - name = "Tank Transfer Valves" +/datum/supply_pack/science/transfer_valves + name = "Tank Transfer Valves Crate" + cost = 60 + access = access_rd contains = list(/obj/item/device/transfer_valve, /obj/item/device/transfer_valve) - cost = 60 - containertype = /obj/structure/closet/crate/secure - containername = "transfer valves crate" - access = access_rd + crate_name = "tank transfer valves crate crate" + crate_type = /obj/structure/closet/crate/secure + dangerous = TRUE ////////////////////////////////////////////////////////////////////////////// //////////////////////////// Organic ///////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// -/datum/supply_packs/organic - name = "HEADER" - group = supply_organic - containertype = /obj/structure/closet/crate/freezer +/datum/supply_pack/organic + group = "Food & Livestock" + crate_type = /obj/structure/closet/crate/freezer - -/datum/supply_packs/organic/food +/datum/supply_pack/organic/food name = "Food Crate" + cost = 10 contains = list(/obj/item/weapon/reagent_containers/food/condiment/flour, /obj/item/weapon/reagent_containers/food/condiment/rice, /obj/item/weapon/reagent_containers/food/condiment/milk, @@ -802,26 +752,26 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine /obj/item/weapon/reagent_containers/food/snacks/grown/banana, /obj/item/weapon/reagent_containers/food/snacks/grown/banana, /obj/item/weapon/reagent_containers/food/snacks/grown/banana) - cost = 10 - containername = "food crate" + crate_name = "food crate" -/datum/supply_packs/organic/pizza +/datum/supply_pack/organic/pizza name = "Pizza Crate" + cost = 60 // Best prices this side of the galaxy. contains = list(/obj/item/pizzabox/margherita, /obj/item/pizzabox/mushroom, /obj/item/pizzabox/meat, /obj/item/pizzabox/vegetable) - cost = 60 - containername = "Pizza crate" + crate_name = "pizza crate" -/datum/supply_packs/organic/monkey +/datum/supply_pack/organic/monkey name = "Monkey Crate" - contains = list (/obj/item/weapon/storage/box/monkeycubes) cost = 20 - containername = "monkey crate" + contains = list (/obj/item/weapon/storage/box/monkeycubes) + crate_name = "monkey crate" -/datum/supply_packs/organic/party - name = "Party equipment" +/datum/supply_pack/organic/party + name = "Party Equipment" + cost = 20 contains = list(/obj/item/weapon/storage/box/drinkingglasses, /obj/item/weapon/reagent_containers/food/drinks/shaker, /obj/item/weapon/reagent_containers/food/drinks/bottle/patron, @@ -832,68 +782,87 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine /obj/item/weapon/reagent_containers/food/drinks/beer, /obj/item/weapon/reagent_containers/food/drinks/beer, /obj/item/weapon/reagent_containers/food/drinks/beer) - cost = 20 - containername = "party equipment" + crate_name = "party equipment" -//////// livestock -/datum/supply_packs/organic/cow +/datum/supply_pack/organic/critter + crate_type = /obj/structure/closet/crate/critter + +/datum/supply_pack/organic/critter/cow name = "Cow Crate" cost = 30 - containertype = /obj/structure/closet/critter/cow - containername = "cow crate" + contains = list(/mob/living/simple_animal/cow) + crate_name = "cow crate" -/datum/supply_packs/organic/goat +/datum/supply_pack/organic/critter/goat name = "Goat Crate" cost = 25 - containertype = /obj/structure/closet/critter/goat - containername = "goat crate" + contains = list(/mob/living/simple_animal/hostile/retaliate/goat) + crate_name = "goat crate" -/datum/supply_packs/organic/chicken +/datum/supply_pack/organic/critter/chick name = "Chicken Crate" cost = 20 - containertype = /obj/structure/closet/critter/chick - containername = "chicken crate" + contains = list( /mob/living/simple_animal/chick) + crate_name = "chicken crate" -/datum/supply_packs/organic/corgi +/datum/supply_pack/organic/critter/corgi name = "Corgi Crate" cost = 50 - containertype = /obj/structure/closet/critter/corgi - contains = list(/obj/item/clothing/tie/petcollar) - containername = "corgi crate" + contains = list(/mob/living/simple_animal/pet/dog/corgi, + /obj/item/clothing/tie/petcollar) + crate_name = "corgi crate" -/datum/supply_packs/organic/cat +/datum/supply_pack/organic/critter/corgi/generate() + . = ..() + if(prob(50)) + var/mob/living/simple_animal/pet/dog/corgi/D = locate() in . + qdel(D) + new /mob/living/simple_animal/pet/dog/corgi/Lisa(.) + +/datum/supply_pack/organic/critter/cat name = "Cat Crate" cost = 50 //Cats are worth as much as corgis. - containertype = /obj/structure/closet/critter/cat - contains = list(/obj/item/clothing/tie/petcollar, + contains = list(/mob/living/simple_animal/pet/cat, + /obj/item/clothing/tie/petcollar, /obj/item/toy/cattoy) - containername = "cat crate" + crate_name = "cat crate" -/datum/supply_packs/organic/pug +/datum/supply_pack/organic/critter/cat/generate() + . = ..() + if(prob(50)) + var/mob/living/simple_animal/pet/cat/C = locate() in . + qdel(C) + new /mob/living/simple_animal/pet/cat/Proc(.) + +/datum/supply_pack/organic/critter/pug name = "Pug Crate" cost = 50 - containertype = /obj/structure/closet/critter/pug - contains = list(/obj/item/clothing/tie/petcollar) - containername = "pug crate" + contains = list(/mob/living/simple_animal/pet/dog/pug, + /obj/item/clothing/tie/petcollar) + crate_name = "pug crate" -/datum/supply_packs/organic/fox +/datum/supply_pack/organic/critter/fox name = "Fox Crate" - cost = 55 //Foxes are cool. - containertype = /obj/structure/closet/critter/fox - contains = list(/obj/item/clothing/tie/petcollar) - containername = "fox crate" - -/datum/supply_packs/organic/butterfly - name = "Butterflies Crate" cost = 50 - containertype = /obj/structure/closet/critter/butterfly - containername = "butterflies crate" - contraband = 1 + contains = list(/mob/living/simple_animal/pet/fox, + /obj/item/clothing/tie/petcollar) + crate_name = "fox crate" -////// hippy gear +/datum/supply_pack/organic/critter/butterfly + name = "Butterflies Crate" + contraband = TRUE + cost = 50 + contains = list(/mob/living/simple_animal/butterfly) + crate_name = "butterflies crate" -/datum/supply_packs/organic/hydroponics // -- Skie - name = "Hydroponics Supply Crate" +/datum/supply_pack/organic/critter/butterfly/generate() + . = ..() + for(var/i in 1 to 49) + new /mob/living/simple_animal/butterfly(.) + +/datum/supply_pack/organic/hydroponics + name = "Hydroponics Crate" + cost = 15 contains = list(/obj/item/weapon/reagent_containers/spray/plantbgone, /obj/item/weapon/reagent_containers/spray/plantbgone, /obj/item/weapon/reagent_containers/glass/bottle/ammonia, @@ -902,21 +871,21 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine /obj/item/weapon/cultivator, /obj/item/device/analyzer/plant_analyzer, /obj/item/clothing/gloves/botanic_leather, - /obj/item/clothing/suit/apron) // Updated with new things - cost = 15 - containertype = /obj/structure/closet/crate/hydroponics - containername = "hydroponics crate" + /obj/item/clothing/suit/apron) + crate_name = "hydroponics crate" + crate_type = /obj/structure/closet/crate/hydroponics -/datum/supply_packs/misc/hydroponics/hydrotank - name = "Hydroponics Watertank Backpack Crate" - contains = list(/obj/item/weapon/watertank) +/datum/supply_pack/misc/hydroponics/hydrotank + name = "Hydroponics Backpack Crate" cost = 10 - containertype = /obj/structure/closet/crate/secure - containername = "hydroponics watertank crate" access = access_hydroponics + contains = list(/obj/item/weapon/watertank) + crate_name = "hydroponics backpack crate" + crate_type = /obj/structure/closet/crate/secure -/datum/supply_packs/organic/hydroponics/seeds +/datum/supply_pack/organic/hydroponics/seeds name = "Seeds Crate" + cost = 10 contains = list(/obj/item/seeds/chiliseed, /obj/item/seeds/berryseed, /obj/item/seeds/cornseed, @@ -930,11 +899,11 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine /obj/item/seeds/chantermycelium, /obj/item/seeds/potatoseed, /obj/item/seeds/sugarcaneseed) - cost = 10 - containername = "seeds crate" + crate_name = "seeds crate" -/datum/supply_packs/organic/hydroponics/exoticseeds +/datum/supply_pack/organic/hydroponics/exoticseeds name = "Exotic Seeds Crate" + cost = 15 contains = list(/obj/item/seeds/nettleseed, /obj/item/seeds/replicapod, /obj/item/seeds/replicapod, @@ -945,113 +914,109 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine /obj/item/seeds/reishimycelium, /obj/item/seeds/bananaseed, /obj/item/seeds/eggyseed) - cost = 15 - containername = "exotic seeds crate" + crate_name = "exotic seeds crate" -/datum/supply_packs/organic/vending +/datum/supply_pack/organic/vending name = "Bartending Supply Crate" + cost = 20 contains = list(/obj/item/weapon/vending_refill/boozeomat, /obj/item/weapon/vending_refill/boozeomat, /obj/item/weapon/vending_refill/boozeomat, /obj/item/weapon/vending_refill/coffee, /obj/item/weapon/vending_refill/coffee, /obj/item/weapon/vending_refill/coffee) - cost = 20 - containername = "bartending supply crate" + crate_name = "bartending supply crate" -/datum/supply_packs/organic/vending/snack +/datum/supply_pack/organic/vending/snack name = "Snack Supply Crate" + cost = 15 contains = list(/obj/item/weapon/vending_refill/snack, /obj/item/weapon/vending_refill/snack, /obj/item/weapon/vending_refill/snack) - cost = 15 - containername = "snacks supply crate" + crate_name = "snacks supply crate" -/datum/supply_packs/organic/vending/cola +/datum/supply_pack/organic/vending/cola name = "Softdrinks Supply Crate" + cost = 15 contains = list(/obj/item/weapon/vending_refill/cola, /obj/item/weapon/vending_refill/cola, /obj/item/weapon/vending_refill/cola) - cost = 15 - containername = "softdrinks supply crate" + crate_name = "softdrinks supply crate" -/datum/supply_packs/organic/vending/cigarette +/datum/supply_pack/organic/vending/cigarette name = "Cigarette Supply Crate" + cost = 15 contains = list(/obj/item/weapon/vending_refill/cigarette, /obj/item/weapon/vending_refill/cigarette, /obj/item/weapon/vending_refill/cigarette) - cost = 15 - containername = "cigarette supply crate" + crate_name = "cigarette supply crate" ////////////////////////////////////////////////////////////////////////////// //////////////////////////// Materials /////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// -/datum/supply_packs/materials - name = "HEADER" - group = supply_materials +/datum/supply_pack/materials + group = "Raw Materials" - -/datum/supply_packs/materials/metal50 +/datum/supply_pack/materials/metal50 name = "50 Metal Sheets" - contains = list(/obj/item/stack/sheet/metal) - amount = 50 cost = 10 - containername = "metal sheets crate" + contains = list(/obj/item/stack/sheet/metal/fifty) + crate_name = "metal sheets crate" -/datum/supply_packs/materials/plasteel20 +/datum/supply_pack/materials/plasteel20 name = "20 Plasteel Sheets" - contains = list(/obj/item/stack/sheet/plasteel) - amount = 20 cost = 30 - containername = "plasteel sheets crate" + contains = list(/obj/item/stack/sheet/plasteel/twenty) + crate_name = "plasteel sheets crate" -/datum/supply_packs/materials/plasteel50 +/datum/supply_pack/materials/plasteel50 name = "50 Plasteel Sheets" - contains = list(/obj/item/stack/sheet/plasteel) - amount = 50 cost = 50 - containername = "plasteel sheets crate" + contains = list(/obj/item/stack/sheet/plasteel/fifty) + crate_name = "plasteel sheets crate" -/datum/supply_packs/materials/glass50 +/datum/supply_pack/materials/glass50 name = "50 Glass Sheets" - contains = list(/obj/item/stack/sheet/glass) - amount = 50 cost = 10 - containername = "glass sheets crate" + contains = list(/obj/item/stack/sheet/glass/fifty) + crate_name = "glass sheets crate" -/datum/supply_packs/materials/cardboard50 +/datum/supply_pack/materials/wood50 + name = "50 Wood Planks" + cost = 10 + contains = list(/obj/item/stack/sheet/mineral/wood/fifty) + crate_name = "wood planks crate" + +/datum/supply_pack/materials/cardboard50 name = "50 Cardboard Sheets" - contains = list(/obj/item/stack/sheet/cardboard) - amount = 50 cost = 10 - containername = "cardboard sheets crate" + contains = list(/obj/item/stack/sheet/cardboard/fifty) + crate_name = "cardboard sheets crate" -/datum/supply_packs/materials/sandstone30 +/datum/supply_pack/materials/sandstone30 name = "30 Sandstone Blocks" - contains = list(/obj/item/stack/sheet/mineral/sandstone) - amount = 30 cost = 20 - containername = "sandstone blocks crate" - + contains = list(/obj/item/stack/sheet/mineral/sandstone/thirty) + crate_name = "sandstone blocks crate" ////////////////////////////////////////////////////////////////////////////// //////////////////////////// Miscellaneous /////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// -/datum/supply_packs/misc - name = "HEADER" - group = supply_misc +/datum/supply_pack/misc + group = "Miscellaneous Supplies" -/datum/supply_packs/misc/mule +/datum/supply_pack/misc/mule name = "MULEbot Crate" - contains = list(/mob/living/simple_animal/bot/mulebot) cost = 20 - containertype = /obj/structure/largecrate/mule - containername = "\improper MULEbot Crate" + contains = list(/mob/living/simple_animal/bot/mulebot) + crate_name = "\improper MULEbot Crate" + crate_type = /obj/structure/closet/crate/large -/datum/supply_packs/misc/conveyor +/datum/supply_pack/misc/conveyor name = "Conveyor Assembly Crate" + cost = 15 contains = list(/obj/item/conveyor_construct, /obj/item/conveyor_construct, /obj/item/conveyor_construct, @@ -1060,18 +1025,18 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine /obj/item/conveyor_construct, /obj/item/conveyor_switch_construct, /obj/item/weapon/paper/conveyor) - cost = 15 - containername = "conveyor assembly crate" + crate_name = "conveyor assembly crate" -/datum/supply_packs/misc/watertank +/datum/supply_pack/misc/watertank name = "Water Tank Crate" - contains = list(/obj/structure/reagent_dispensers/watertank) cost = 8 - containertype = /obj/structure/largecrate - containername = "water tank crate" + contains = list(/obj/structure/reagent_dispensers/watertank) + crate_name = "water tank crate" + crate_type = /obj/structure/closet/crate/large -/datum/supply_packs/misc/lasertag +/datum/supply_pack/misc/lasertag name = "Laser Tag Crate" + cost = 15 contains = list(/obj/item/weapon/gun/energy/laser/redtag, /obj/item/weapon/gun/energy/laser/redtag, /obj/item/weapon/gun/energy/laser/redtag, @@ -1086,35 +1051,32 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine /obj/item/clothing/suit/bluetag, /obj/item/clothing/head/helmet/redtaghelm, /obj/item/clothing/head/helmet/bluetaghelm) - cost = 15 - containername = "laser tag crate" + crate_name = "laser tag crate" -/datum/supply_packs/misc/religious_supplies +/datum/supply_pack/misc/religious_supplies name = "Religious Supplies Crate" + cost = 40 // it costs so much because the Space Church is ran by Space Jews contains = list(/obj/item/weapon/reagent_containers/food/drinks/bottle/holywater, /obj/item/weapon/reagent_containers/food/drinks/bottle/holywater, /obj/item/weapon/storage/book/bible/booze, /obj/item/weapon/storage/book/bible/booze, /obj/item/clothing/suit/hooded/chaplain_hoodie, /obj/item/clothing/suit/hooded/chaplain_hoodie) - cost = 40 // it costs so much because the Space Church is ran by Space Jews - containername = "religious supplies crate" + crate_name = "religious supplies crate" -/datum/supply_packs/misc/posters +/datum/supply_pack/misc/posters name = "Corporate Posters Crate" + cost = 8 contains = list(/obj/item/weapon/poster/legit, /obj/item/weapon/poster/legit, /obj/item/weapon/poster/legit, /obj/item/weapon/poster/legit, /obj/item/weapon/poster/legit) - cost = 8 - containername = "Corporate Posters Crate" + crate_name = "Corporate Posters Crate" - -///////////// Paper Work - -/datum/supply_packs/misc/paper +/datum/supply_pack/misc/paper name = "Bureaucracy Crate" + cost = 15 contains = list(/obj/structure/filingcabinet/chestdrawer/wheeled, /obj/item/device/camera_film, /obj/item/weapon/hand_labeler, @@ -1131,25 +1093,22 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine /obj/item/weapon/folder/yellow, /obj/item/weapon/clipboard, /obj/item/weapon/clipboard) - cost = 15 - containername = "bureaucracy crate" + crate_name = "bureaucracy crate" -/datum/supply_packs/misc/toner - name = "Toner Cartridges crate" +/datum/supply_pack/misc/toner + name = "Toner Crate" + cost = 10 contains = list(/obj/item/device/toner, /obj/item/device/toner, /obj/item/device/toner, /obj/item/device/toner, /obj/item/device/toner, /obj/item/device/toner) - cost = 10 - containername = "toner cartridges crate" + crate_name = "toner crate" - -///////////// Janitor Supplies - -/datum/supply_packs/misc/janitor +/datum/supply_pack/misc/janitor name = "Janitorial Supplies Crate" + cost = 10 contains = list(/obj/item/weapon/reagent_containers/glass/bucket, /obj/item/weapon/reagent_containers/glass/bucket, /obj/item/weapon/reagent_containers/glass/bucket, @@ -1163,55 +1122,53 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine /obj/item/weapon/grenade/chem_grenade/cleaner, /obj/item/weapon/grenade/chem_grenade/cleaner, /obj/item/weapon/grenade/chem_grenade/cleaner) - cost = 10 - containername = "janitorial supplies crate" + crate_name = "janitorial supplies crate" -/datum/supply_packs/misc/janitor/janicart +/datum/supply_pack/misc/janitor/janicart name = "Janitorial Cart and Galoshes Crate" + cost = 20 contains = list(/obj/structure/janitorialcart, /obj/item/clothing/shoes/galoshes) - cost = 10 - containertype = /obj/structure/largecrate - containername = "janitorial cart crate" + crate_name = "janitorial cart crate" + crate_type = /obj/structure/closet/crate/large -/datum/supply_packs/misc/janitor/janitank - name = "Janitor Watertank Backpack" - contains = list(/obj/item/weapon/watertank/janitor) +/datum/supply_pack/misc/janitor/janitank + name = "Janitor Backpack Crate" cost = 10 - containertype = /obj/structure/closet/crate/secure - containername = "janitor watertank crate" access = access_janitor + contains = list(/obj/item/weapon/watertank/janitor) + crate_name = "janitor backpack crate" + crate_type = /obj/structure/closet/crate/secure -/datum/supply_packs/misc/janitor/lightbulbs +/datum/supply_pack/misc/janitor/lightbulbs name = "Replacement Lights" + cost = 10 contains = list(/obj/item/weapon/storage/box/lights/mixed, /obj/item/weapon/storage/box/lights/mixed, /obj/item/weapon/storage/box/lights/mixed) - cost = 10 - containername = "replacement lights" + crate_name = "replacement lights" -/datum/supply_packs/misc/noslipfloor +/datum/supply_pack/misc/noslipfloor name = "High-traction Floor Tiles" - contains = list(/obj/item/stack/tile/noslip) - amount = 20 cost = 20 - containername = "high-traction floor tiles" + contains = list(/obj/item/stack/tile/noslip/thirty) + crate_name = "high-traction floor tiles" -/datum/supply_packs/misc/plasmaman - name = "Plasma-man Supply Kit" +/datum/supply_pack/misc/plasmaman + name = "Plasmaman Supply Kit" + cost = 20 contains = list(/obj/item/clothing/under/plasmaman, /obj/item/clothing/under/plasmaman, /obj/item/weapon/tank/internals/plasmaman/belt/full, /obj/item/weapon/tank/internals/plasmaman/belt/full, /obj/item/clothing/head/helmet/space/plasmaman, /obj/item/clothing/head/helmet/space/plasmaman) - cost = 20 - containername = "plasma-man supply kit" + crate_name = "plasmaman supply kit" -///////////// Costumes - -/datum/supply_packs/misc/costume +/datum/supply_pack/misc/costume name = "Standard Costume Crate" + cost = 10 + access = access_theatre contains = list(/obj/item/weapon/storage/backpack/clown, /obj/item/clothing/shoes/clown_shoes, /obj/item/clothing/mask/gas/clown_hat, @@ -1225,21 +1182,21 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine /obj/item/clothing/suit/suspenders, /obj/item/weapon/reagent_containers/food/drinks/bottle/bottleofnothing, /obj/item/weapon/storage/backpack/mime) - cost = 10 - containertype = /obj/structure/closet/crate/secure - containername = "standard costumes" - access = access_theatre + crate_name = "standard costume crate" + crate_type = /obj/structure/closet/crate/secure -/datum/supply_packs/misc/wizard +/datum/supply_pack/misc/wizard name = "Wizard Costume Crate" + cost = 20 contains = list(/obj/item/weapon/staff, /obj/item/clothing/suit/wizrobe/fake, /obj/item/clothing/shoes/sandal, /obj/item/clothing/head/wizard/fake) - cost = 20 - containername = "wizard costume crate" + crate_name = "wizard costume crate" -/datum/supply_packs/misc/randomised +/datum/supply_pack/misc/randomised + name = "Collectable Hats Crate!" + cost = 200 var/num_contained = 3 //number of items picked to be contained in a randomised crate contains = list(/obj/item/clothing/head/collectable/chef, /obj/item/clothing/head/collectable/paper, @@ -1261,27 +1218,21 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine /obj/item/clothing/head/collectable/slime, /obj/item/clothing/head/collectable/xenom, /obj/item/clothing/head/collectable/petehat) - name = "Collectable hat crate!" - cost = 200 - containername = "collectable hats crate! Brought to you by Bass.inc!" + crate_name = "collectable hats crate" -/datum/supply_packs/misc/randomised/New() - manifest += "Contains any [num_contained] of:" - ..() - - -/datum/supply_packs/misc/randomised/contraband +/datum/supply_pack/misc/randomised/contraband + name = "Contraband Crate" + contraband = TRUE + cost = 30 num_contained = 5 contains = list(/obj/item/weapon/poster/contraband, /obj/item/weapon/storage/fancy/cigarettes/dromedaryco, /obj/item/weapon/storage/fancy/cigarettes/cigpack_shadyjims) - name = "Contraband Crate" - cost = 30 - containername = "crate" //let's keep it subtle, eh? - contraband = 1 + crate_name = "crate" -/datum/supply_packs/misc/randomised/toys +/datum/supply_pack/misc/randomised/toys name = "Toy Crate" + cost = 50 // or play the arcade machines ya lazy bum num_contained = 5 contains = list(/obj/item/toy/spinningtoy, /obj/item/toy/sword, @@ -1296,19 +1247,18 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine /obj/item/stack/tile/fakespace, /obj/item/weapon/gun/projectile/shotgun/toy/crossbow, /obj/item/toy/redbutton) + crate_name = "toy crate" - cost = 50 // or play the arcade machines ya lazy bum - containername ="toy crate" - -/datum/supply_packs/misc/autodrobe +/datum/supply_pack/misc/autodrobe name = "Autodrobe Supply Crate" + cost = 15 contains = list(/obj/item/weapon/vending_refill/autodrobe, /obj/item/weapon/vending_refill/autodrobe) - cost = 15 - containername = "autodrobe supply crate" + crate_name = "autodrobe supply crate" -/datum/supply_packs/misc/formalwear //This is a very classy crate. - name = "Formal-wear Crate" +/datum/supply_pack/misc/formalwear + name = "Formalwear Crate" + cost = 30 //Lots of very expensive items. You gotta pay up to look good! contains = list(/obj/item/clothing/under/blacktango, /obj/item/clothing/under/assistantformal, /obj/item/clothing/under/assistantformal, @@ -1336,11 +1286,11 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine /obj/item/clothing/under/suit_jacket/checkered, /obj/item/clothing/under/suit_jacket/tan, /obj/item/weapon/lipstick/random) - cost = 30 //Lots of very expensive items. You gotta pay up to look good! - containername = "formal-wear crate" + crate_name = "formalwear crate" -/datum/supply_packs/misc/foamforce +/datum/supply_pack/misc/foamforce name = "Foam Force Crate" + cost = 10 contains = list(/obj/item/weapon/gun/projectile/shotgun/toy, /obj/item/weapon/gun/projectile/shotgun/toy, /obj/item/weapon/gun/projectile/shotgun/toy, @@ -1349,16 +1299,14 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine /obj/item/weapon/gun/projectile/shotgun/toy, /obj/item/weapon/gun/projectile/shotgun/toy, /obj/item/weapon/gun/projectile/shotgun/toy) - cost = 10 - containername = "foam force crate" + crate_name = "foam force crate" -/datum/supply_packs/misc/foamforce/bonus +/datum/supply_pack/misc/foamforce/bonus name = "Foam Force Pistols Crate" + contraband = TRUE + cost = 40 contains = list(/obj/item/weapon/gun/projectile/automatic/toy/pistol, /obj/item/weapon/gun/projectile/automatic/toy/pistol, /obj/item/ammo_box/magazine/toy/pistol, /obj/item/ammo_box/magazine/toy/pistol) - cost = 40 - containername = "foam force pistols crate" - contraband = 1 - + crate_name = "foam force pistols crate" diff --git a/code/modules/client/client defines.dm b/code/modules/client/client defines.dm index 72679562098..ca9ced5dc8e 100644 --- a/code/modules/client/client defines.dm +++ b/code/modules/client/client defines.dm @@ -4,7 +4,7 @@ //ADMIN THINGS// //////////////// var/datum/admins/holder = null - var/buildmode = 0 + var/datum/click_intercept = null // Needs to implement ClickOn(user,params,atom) proc var/AI_Interact = 0 var/jobbancache = null //Used to cache this client's jobbans to save on DB queries diff --git a/code/modules/clothing/head/helmet.dm b/code/modules/clothing/head/helmet.dm index 095e86969f8..6727996aea8 100644 --- a/code/modules/clothing/head/helmet.dm +++ b/code/modules/clothing/head/helmet.dm @@ -4,7 +4,7 @@ icon_state = "helmet" flags = HEADBANGPROTECT item_state = "helmet" - armor = list(melee = 25, bullet = 15, laser = 25,energy = 10, bomb = 25, bio = 0, rad = 0) + armor = list(melee = 30, bullet = 25, laser = 25,energy = 10, bomb = 25, bio = 0, rad = 0) flags_inv = HIDEEARS|HIDEEYES cold_protection = HEAD min_cold_protection_temperature = HELMET_MIN_TEMP_PROTECT diff --git a/code/modules/clothing/head/jobs.dm b/code/modules/clothing/head/jobs.dm index a469f0aeff8..662e22539d7 100644 --- a/code/modules/clothing/head/jobs.dm +++ b/code/modules/clothing/head/jobs.dm @@ -101,7 +101,7 @@ name = "security beret" desc = "A robust beret with the security insignia emblazoned on it. Uses reinforced fabric to offer sufficent protection." icon_state = "beret_badge" - armor = list(melee = 25, bullet = 15, laser = 25,energy = 10, bomb = 25, bio = 0, rad = 0) + armor = list(melee = 30, bullet = 25, laser = 25,energy = 10, bomb = 25, bio = 0, rad = 0) strip_delay = 60 /obj/item/clothing/head/beret/sec/navyhos diff --git a/code/modules/clothing/head/soft_caps.dm b/code/modules/clothing/head/soft_caps.dm index e4250170a4d..689bd54862e 100644 --- a/code/modules/clothing/head/soft_caps.dm +++ b/code/modules/clothing/head/soft_caps.dm @@ -109,11 +109,11 @@ desc = "It's a robust baseball hat in tasteful red colour." icon_state = "secsoft" item_color = "sec" - armor = list(melee = 30, bullet = 25, laser = 25, energy = 10, bomb = 0, bio = 0, rad = 0) + armor = list(melee = 30, bullet = 25, laser = 25, energy = 10, bomb = 25, bio = 0, rad = 0) strip_delay = 60 /obj/item/clothing/head/soft/emt name = "EMT cap" desc = "It's a baseball hat with a dark turquoise color and a reflective cross on the top." icon_state = "emtsoft" - item_color = "emt" \ No newline at end of file + item_color = "emt" diff --git a/code/modules/clothing/outfits/standard.dm b/code/modules/clothing/outfits/standard.dm index edf67be4041..e32ca287c73 100644 --- a/code/modules/clothing/outfits/standard.dm +++ b/code/modules/clothing/outfits/standard.dm @@ -8,15 +8,7 @@ back = /obj/item/weapon/tank/jetpack/oxygen mask = /obj/item/clothing/mask/breath -/datum/outfit/space/post_equip(mob/living/carbon/human/H) - var/obj/item/weapon/tank/jetpack/J = H.back - J.toggle() - J.Topic(null, list("stat" = 1)) - - /datum/outfit/tournament - -/datum/outfit/tournament/ name = "tournament standard red" uniform = /obj/item/clothing/under/color/red @@ -27,14 +19,14 @@ l_hand = /obj/item/weapon/kitchen/knife r_pocket = /obj/item/weapon/grenade/smokebomb - -/datum/outfit/tournament/red +/datum/outfit/tournament/green name = "tournament standard green" uniform = /obj/item/clothing/under/color/green /datum/outfit/tournament/gangster name = "tournament gangster" + uniform = /obj/item/clothing/under/rank/det suit = /obj/item/clothing/suit/det_suit glasses = /obj/item/clothing/glasses/thermal/monocle diff --git a/code/modules/clothing/shoes/miscellaneous.dm b/code/modules/clothing/shoes/miscellaneous.dm index a35163ba868..190a09a1643 100644 --- a/code/modules/clothing/shoes/miscellaneous.dm +++ b/code/modules/clothing/shoes/miscellaneous.dm @@ -103,6 +103,9 @@ burn_state = FIRE_PROOF can_hold_items = 1 +/obj/item/clothing/shoes/jackboots/fast + slowdown = -1 + /obj/item/clothing/shoes/winterboots name = "winter boots" desc = "Boots lined with 'synthetic' animal fur." diff --git a/code/modules/clothing/spacesuits/hardsuit.dm b/code/modules/clothing/spacesuits/hardsuit.dm index 93fa41ae868..d3ad0d5344e 100644 --- a/code/modules/clothing/spacesuits/hardsuit.dm +++ b/code/modules/clothing/spacesuits/hardsuit.dm @@ -1,6 +1,4 @@ //Baseline hardsuits - - /obj/item/clothing/head/helmet/space/hardsuit name = "hardsuit helmet" desc = "A special helmet designed for work in a hazardous, low-pressure environment. Has radiation shielding." @@ -70,22 +68,22 @@ icon_state = "hardsuit-engineering" item_state = "eng_hardsuit" armor = list(melee = 10, bullet = 5, laser = 10, energy = 5, bomb = 10, bio = 100, rad = 75) - allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank/internals,/obj/item/device/t_scanner, /obj/item/weapon/rcd) + allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank/internals,/obj/item/device/t_scanner, /obj/item/weapon/rcd, /obj/item/weapon/pipe_dispenser) siemens_coefficient = 0 var/obj/item/clothing/head/helmet/space/hardsuit/helmet action_button_name = "Toggle Helmet" var/helmettype = /obj/item/clothing/head/helmet/space/hardsuit var/obj/item/weapon/tank/jetpack/suit/jetpack = null -/obj/item/clothing/suit/space/hardsuit/verb/Jetpack() - set name = "Toggle Inbuilt Jetpack" - set category = "Object" - jetpack.toggle() +/obj/item/clothing/suit/space/hardsuit/equipped(mob/user, slot) + ..() + if(slot == slot_wear_suit && jetpack) + jetpack.cycle_action.Grant(user) -/obj/item/clothing/suit/space/hardsuit/verb/Jetpack_Rockets() - set name = "Toggle Inbuilt Jetpack Stabilization" - set category = "Object" - jetpack.toggle_rockets() +/obj/item/clothing/suit/space/hardsuit/dropped(mob/user) + ..() + if(jetpack) + jetpack.cycle_action.Remove(user) //Engineering /obj/item/clothing/head/helmet/space/hardsuit/engine @@ -516,6 +514,7 @@ helmettype = /obj/item/clothing/head/helmet/space/hardsuit/shielded/ctf armor = list(melee = 0, bullet = 30, laser = 30, energy = 30, bomb = 50, bio = 100, rad = 100) slowdown = 0 + max_charges = 5 /obj/item/clothing/suit/space/hardsuit/shielded/ctf/red name = "red shielded hardsuit" diff --git a/code/modules/clothing/suits/toggles.dm b/code/modules/clothing/suits/toggles.dm index 1089db21f9d..5283af92d42 100644 --- a/code/modules/clothing/suits/toggles.dm +++ b/code/modules/clothing/suits/toggles.dm @@ -92,10 +92,8 @@ //Hardsuit toggle code /obj/item/clothing/suit/space/hardsuit/New() MakeHelmet() - if(!jetpack) - verbs -= /obj/item/clothing/suit/space/hardsuit/verb/Jetpack - verbs -= /obj/item/clothing/suit/space/hardsuit/verb/Jetpack_Rockets ..() + /obj/item/clothing/suit/space/hardsuit/Destroy() if(helmet) helmet.suit = null diff --git a/code/modules/clothing/under/chameleon.dm b/code/modules/clothing/under/chameleon.dm index bbf5699c396..f38708348bb 100644 --- a/code/modules/clothing/under/chameleon.dm +++ b/code/modules/clothing/under/chameleon.dm @@ -12,6 +12,7 @@ var/list/clothing_choices = list() var/malfunctioning = 0 burn_state = FIRE_PROOF + armor = list(melee = 10, bullet = 10, laser = 10,energy = 0, bomb = 0, bio = 0, rad = 0) /obj/item/clothing/under/chameleon/New() ..() diff --git a/code/modules/crafting/recipes.dm b/code/modules/crafting/recipes.dm index 76e0cead24a..23432c61759 100644 --- a/code/modules/crafting/recipes.dm +++ b/code/modules/crafting/recipes.dm @@ -16,7 +16,7 @@ reqs = list(/obj/item/weapon/gun = 1) parts = list(/obj/item/weapon/gun = 1) tools = list(/obj/item/weapon/gun/energy/plasmacutter, /obj/item/weapon/screwdriver, /obj/item/weapon/wirecutters) - time = 100 + time = 50 category = CAT_WEAPON /datum/table_recipe/IED @@ -27,7 +27,7 @@ /obj/item/device/assembly/igniter = 1, /obj/item/weapon/reagent_containers/food/drinks/soda_cans = 1) parts = list(/obj/item/weapon/reagent_containers/food/drinks/soda_cans = 1) - time = 30 + time = 15 category = CAT_WEAPON /datum/table_recipe/lance @@ -36,7 +36,7 @@ reqs = list(/obj/item/weapon/twohanded/spear = 1, /obj/item/weapon/grenade = 1) parts = list(/obj/item/weapon/grenade = 1) - time = 30 + time = 15 category = CAT_WEAPON /datum/table_recipe/lance2 @@ -45,7 +45,7 @@ reqs = list(/obj/item/weapon/twohanded/spear = 1, /obj/item/weapon/c4 = 1) parts = list(/obj/item/weapon/c4 = 1) - time = 80 + time = 40 category = CAT_WEAPON @@ -55,7 +55,7 @@ reqs = list(/obj/item/weapon/reagent_containers/glass/rag = 1, /obj/item/weapon/reagent_containers/food/drinks/bottle = 1) parts = list(/obj/item/weapon/reagent_containers/food/drinks/bottle = 1) - time = 80 + time = 40 category = CAT_WEAPON /datum/table_recipe/stunprod @@ -65,7 +65,7 @@ /obj/item/stack/rods = 1, /obj/item/device/assembly/igniter = 1, /obj/item/weapon/stock_parts/cell = 1) - time = 80 + time = 40 parts = list(/obj/item/weapon/stock_parts/cell = 1) category = CAT_WEAPON @@ -77,7 +77,7 @@ /obj/item/weapon/wirecutters = 1, /obj/item/weapon/stock_parts/cell = 1, /obj/item/weapon/ore/bluespace_crystal = 1) - time = 80 + time = 40 parts = list(/obj/item/weapon/stock_parts/cell = 1) category = CAT_WEAPON @@ -86,7 +86,7 @@ result = /obj/item/weapon/tailclub reqs = list(/obj/item/organ/severedtail = 1, /obj/item/stack/sheet/metal = 1) - time = 80 + time = 40 category = CAT_WEAPON /datum/table_recipe/tailwhip @@ -94,7 +94,7 @@ result = /obj/item/weapon/melee/chainofcommand/tailwhip reqs = list(/obj/item/organ/severedtail = 1, /obj/item/stack/cable_coil = 1) - time = 80 + time = 40 category = CAT_WEAPON /datum/table_recipe/ed209 @@ -112,7 +112,7 @@ /obj/item/device/assembly/prox_sensor = 1, /obj/item/robot_parts/r_arm = 1) tools = list(/obj/item/weapon/weldingtool, /obj/item/weapon/screwdriver) - time = 120 + time = 60 category = CAT_ROBOT /datum/table_recipe/secbot @@ -124,7 +124,7 @@ /obj/item/device/assembly/prox_sensor = 1, /obj/item/robot_parts/r_arm = 1) tools = list(/obj/item/weapon/weldingtool) - time = 120 + time = 60 category = CAT_ROBOT /datum/table_recipe/cleanbot @@ -133,7 +133,7 @@ reqs = list(/obj/item/weapon/reagent_containers/glass/bucket = 1, /obj/item/device/assembly/prox_sensor = 1, /obj/item/robot_parts/r_arm = 1) - time = 80 + time = 40 category = CAT_ROBOT /datum/table_recipe/floorbot @@ -143,7 +143,7 @@ /obj/item/stack/tile/plasteel = 1, /obj/item/device/assembly/prox_sensor = 1, /obj/item/robot_parts/r_arm = 1) - time = 80 + time = 40 category = CAT_ROBOT /datum/table_recipe/medbot @@ -153,7 +153,7 @@ /obj/item/weapon/storage/firstaid = 1, /obj/item/device/assembly/prox_sensor = 1, /obj/item/robot_parts/r_arm = 1) - time = 80 + time = 40 category = CAT_ROBOT /datum/table_recipe/flamethrower @@ -165,7 +165,7 @@ parts = list(/obj/item/device/assembly/igniter = 1, /obj/item/weapon/weldingtool = 1) tools = list(/obj/item/weapon/screwdriver) - time = 20 + time = 10 category = CAT_WEAPON /datum/table_recipe/meteorshot @@ -256,7 +256,7 @@ /obj/item/weaponcrafting/stock = 1, /obj/item/stack/packageWrap = 5,) tools = list(/obj/item/weapon/screwdriver) - time = 200 + time = 100 category = CAT_WEAPON /datum/table_recipe/chainsaw @@ -266,7 +266,7 @@ /obj/item/stack/cable_coil = 1, /obj/item/stack/sheet/plasteel = 1) tools = list(/obj/item/weapon/weldingtool) - time = 100 + time = 50 category = CAT_WEAPON /datum/table_recipe/spooky_camera @@ -281,13 +281,13 @@ /datum/table_recipe/lizardhat name = "Lizard Cloche Hat" result = /obj/item/clothing/head/lizard - time = 20 + time = 10 reqs = list(/obj/item/organ/severedtail = 1) category = CAT_MISC /datum/table_recipe/lizardhat_alternate name = "Lizard Cloche Hat" result = /obj/item/clothing/head/lizard - time = 20 + time = 10 reqs = list(/obj/item/stack/sheet/animalhide/lizard = 1) category = CAT_MISC diff --git a/code/modules/events/shuttle_loan.dm b/code/modules/events/shuttle_loan.dm index 76ecd4a37fa..6f25e555c12 100644 --- a/code/modules/events/shuttle_loan.dm +++ b/code/modules/events/shuttle_loan.dm @@ -12,12 +12,12 @@ earliest_start = 4000 /datum/round_event/shuttle_loan + announceWhen = 1 endWhen = 500 - var/dispatch_type = 4 + var/dispatched = 0 + var/dispatch_type = 0 var/bonus_points = 100 var/thanks_msg = "The cargo shuttle should return in five minutes. Have some supply points for your trouble." - var/dispatched = 0 - announceWhen = 1 /datum/round_event/shuttle_loan/start() dispatch_type = pick(HIJACK_SYNDIE, RUSKY_PARTY, SPIDER_GIFT, DEPARTMENT_RESUPPLY, ANTIDOTE_NEEDED) @@ -73,8 +73,6 @@ else endWhen = activeFor + 1 -//whomever coded this didn't even bother to follow the supply ordering code as an example. -//So I had to waste time rewriting it. Thanks for that >:[ /datum/round_event/shuttle_loan/end() if(SSshuttle.shuttle_loan && SSshuttle.shuttle_loan.dispatched) //make sure the shuttle was dispatched in time @@ -91,7 +89,9 @@ var/list/shuttle_spawns = list() switch(dispatch_type) if(HIJACK_SYNDIE) - add_crates(list(/datum/supply_packs/emergency/specialops), empty_shuttle_turfs) + var/datum/supply_pack/pack = SSshuttle.supply_packs[/datum/supply_pack/emergency/specialops] + pack.generate(pick_n_take(empty_shuttle_turfs)) + shuttle_spawns.Add(/mob/living/simple_animal/hostile/syndicate) shuttle_spawns.Add(/mob/living/simple_animal/hostile/syndicate) if(prob(75)) @@ -100,7 +100,9 @@ shuttle_spawns.Add(/mob/living/simple_animal/hostile/syndicate) if(RUSKY_PARTY) - add_crates(list(/datum/supply_packs/organic/party), empty_shuttle_turfs) + var/datum/supply_pack/pack = SSshuttle.supply_packs[/datum/supply_pack/organic/party] + pack.generate(pick_n_take(empty_shuttle_turfs)) + shuttle_spawns.Add(/mob/living/simple_animal/hostile/russian) shuttle_spawns.Add(/mob/living/simple_animal/hostile/russian/ranged) //drops a mateba shuttle_spawns.Add(/mob/living/simple_animal/hostile/bear) @@ -110,7 +112,9 @@ shuttle_spawns.Add(/mob/living/simple_animal/hostile/bear) if(SPIDER_GIFT) - add_crates(list(/datum/supply_packs/emergency/specialops), empty_shuttle_turfs) + var/datum/supply_pack/pack = SSshuttle.supply_packs[/datum/supply_pack/emergency/specialops] + pack.generate(pick_n_take(empty_shuttle_turfs)) + shuttle_spawns.Add(/mob/living/simple_animal/hostile/poison/giant_spider) shuttle_spawns.Add(/mob/living/simple_animal/hostile/poison/giant_spider) shuttle_spawns.Add(/mob/living/simple_animal/hostile/poison/giant_spider/nurse) @@ -135,7 +139,6 @@ T = pick(empty_shuttle_turfs) new /obj/effect/spider/stickyweb(T) - if(ANTIDOTE_NEEDED) var/virus_type = pick(/datum/disease/beesease, /datum/disease/brainrot, /datum/disease/fluspanish) var/turf/T @@ -158,22 +161,23 @@ if(DEPARTMENT_RESUPPLY) var/list/crate_types = list( - /datum/supply_packs/emergency/evac, - /datum/supply_packs/security/supplies, - /datum/supply_packs/organic/food, - /datum/supply_packs/emergency/weedcontrol, - /datum/supply_packs/engineering/tools, - /datum/supply_packs/engineering/engiequipment, - /datum/supply_packs/science/robotics, - /datum/supply_packs/science/plasma, - /datum/supply_packs/medical/supplies + /datum/supply_pack/emergency/equipment, + /datum/supply_pack/security/supplies, + /datum/supply_pack/organic/food, + /datum/supply_pack/emergency/weedcontrol, + /datum/supply_pack/engineering/tools, + /datum/supply_pack/engineering/engiequipment, + /datum/supply_pack/science/robotics, + /datum/supply_pack/science/plasma, + /datum/supply_pack/medical/supplies ) - add_crates(crate_types, empty_shuttle_turfs) + for(var/crate in crate_types) + var/datum/supply_pack/pack = SSshuttle.supply_packs[crate] + pack.generate(pick_n_take(empty_shuttle_turfs)) - for(var/i=0,i<5,i++) - var/turf/T = pick(empty_shuttle_turfs) - var/spawn_type = pick(/obj/effect/decal/cleanable/flour, /obj/effect/decal/cleanable/robot_debris, /obj/effect/decal/cleanable/oil) - new spawn_type(T) + for(var/i in 1 to 5) + var/decal = pick(/obj/effect/decal/cleanable/flour, /obj/effect/decal/cleanable/robot_debris, /obj/effect/decal/cleanable/oil) + new decal(pick_n_take(empty_shuttle_turfs)) var/false_positive = 0 while(shuttle_spawns.len && empty_shuttle_turfs.len) @@ -185,18 +189,8 @@ var/spawn_type = pick_n_take(shuttle_spawns) new spawn_type(T) -/datum/round_event/shuttle_loan/proc/add_crates(list/crate_types, list/turfs) - for(var/crate_type in crate_types) - var/turf/T = pick_n_take(turfs) - var/datum/supply_packs/sp_obj = new crate_type() - var/atom/Crate = new sp_obj.containertype(T) - Crate.name = sp_obj.containername - for(var/type_path in sp_obj.contains) - var/atom/A = new type_path(Crate) - if(sp_obj.amount && A.vars.Find("amount") && A:amount) - A:amount = sp_obj.amount - #undef HIJACK_SYNDIE #undef RUSKY_PARTY #undef SPIDER_GIFT #undef DEPARTMENT_RESUPPLY +#undef ANTIDOTE_NEEDED \ No newline at end of file diff --git a/code/modules/food&drinks/drinks/drinks/drinkingglass.dm b/code/modules/food&drinks/drinks/drinks/drinkingglass.dm index d6ce0c0a10a..bd70905ff91 100644 --- a/code/modules/food&drinks/drinks/drinks/drinkingglass.dm +++ b/code/modules/food&drinks/drinks/drinks/drinkingglass.dm @@ -575,6 +575,18 @@ icon_state = "shotglassbrown" name = "shot of cognac" desc = "You get the feeling this would piss off a rich person somewhere." + if ("wine") + icon_state = "shotglassred" + name = "shot of wine" + desc = "What kind of craven oaf would drink wine from a shot glass?" + if ("blood") + icon_state = "shotglassred" + name = "shot of blood" + desc = "If you close your eyes it sort of tastes like wine..." + if ("liquidgibs") + icon_state = "shotglassred" + name = "shot of gibs" + desc = "...Let's not talk about this." else icon_state = "shotglassbrown" name = "shot of... what?" diff --git a/code/modules/hydroponics/grown.dm b/code/modules/hydroponics/grown.dm index 27f97bb5770..fc30cec85e5 100644 --- a/code/modules/hydroponics/grown.dm +++ b/code/modules/hydroponics/grown.dm @@ -1042,7 +1042,8 @@ obj/item/weapon/reagent_containers/food/snacks/grown/shell/eggy/add_juice() user.unEquip(src) user.put_in_hands(Shiv) qdel(src) - + else + return ..() /obj/item/weapon/reagent_containers/food/snacks/grown/mushroom name = "mushroom" diff --git a/code/modules/mining/abandoned_crates.dm b/code/modules/mining/abandoned_crates.dm index 3f6ca87fa8e..e30fdc8ed22 100644 --- a/code/modules/mining/abandoned_crates.dm +++ b/code/modules/mining/abandoned_crates.dm @@ -3,13 +3,11 @@ /obj/structure/closet/crate/secure/loot name = "abandoned crate" desc = "What could be inside?" - icon_crate = "securecrate" icon_state = "securecrate" var/code = null var/lastattempt = null var/attempts = 10 var/codelen = 4 - locked = 1 /obj/structure/closet/crate/secure/loot/New() ..() @@ -38,13 +36,13 @@ if(11 to 15) new /obj/item/weapon/reagent_containers/glass/beaker/bluespace(src) if(16 to 20) - for(var/i = 0, i < 10, i++) + for(var/i in 1 to 10) new /obj/item/weapon/ore/diamond(src) if(21 to 25) - for(var/i = 0, i < 5, i++) + for(var/i in 1 to 5) new /obj/item/weapon/poster/contraband(src) if(26 to 30) - for(var/i = 0, i < 3, i++) + for(var/i in 1 to 3) new /obj/item/weapon/reagent_containers/glass/beaker/noreact(src) if(31 to 35) new /obj/item/seeds/cashseed(src) @@ -55,7 +53,7 @@ new /obj/item/clothing/under/shorts/blue(src) if(46 to 50) new /obj/item/clothing/under/chameleon(src) - for(var/i = 0, i < 7, i++) + for(var/i in 1 to 7) new /obj/item/clothing/tie/horrible(src) if(51 to 52) // 2% chance new /obj/item/weapon/melee/classic_baton(src) @@ -71,24 +69,22 @@ new /obj/item/clothing/suit/space(src) new /obj/item/clothing/head/helmet/space(src) if(61 to 62) - for(var/i = 0, i < 5, ++i) + for(var/i in 1 to 5) new /obj/item/clothing/head/kitty(src) new /obj/item/clothing/tie/petcollar(src) if(63 to 64) - var/t = rand(4,7) - for(var/i = 0, i < t, ++i) + for(var/i in 1 to rand(4, 7)) var/newcoin = pick(/obj/item/weapon/coin/silver, /obj/item/weapon/coin/silver, /obj/item/weapon/coin/silver, /obj/item/weapon/coin/iron, /obj/item/weapon/coin/iron, /obj/item/weapon/coin/iron, /obj/item/weapon/coin/gold, /obj/item/weapon/coin/diamond, /obj/item/weapon/coin/plasma, /obj/item/weapon/coin/uranium) new newcoin(src) if(65 to 66) new /obj/item/clothing/suit/ianshirt(src) new /obj/item/clothing/suit/hooded/ian_costume(src) if(67 to 68) - var/t = rand(4,7) - for(var/i = 0, i < t, ++i) + for(var/i in 1 to rand(4, 7)) var /newitem = pick(subtypesof(/obj/item/weapon/stock_parts) - /obj/item/weapon/stock_parts/subspace) new newitem(src) if(69 to 70) - for(var/i = 0, i < 5, ++i) + for(var/i in 1 to 5) new /obj/item/weapon/ore/bluespace_crystal(src) if(71 to 72) new /obj/item/weapon/pickaxe/drill(src) @@ -163,40 +159,32 @@ user << "The crate unlocks!" locked = 0 overlays.Cut() - overlays += greenlight + overlays += "securecrateg" else if (input == null || length(input) != codelen) user << "You leave the crate alone." else user << "A red light flashes." lastattempt = replacetext(input, 0, "z") attempts-- - if (attempts == 0) - user << "The crate's anti-tamper system activates!" - var/turf/T = get_turf(src.loc) - explosion(T, -1, -1, 1, 1) - qdel(src) - return + if(attempts == 0) + boom(user) else return ..() -/obj/structure/closet/crate/secure/loot/attack_animal() - qdel(src) +/obj/structure/closet/crate/secure/loot/attack_animal(mob/user) + boom(user) /obj/structure/closet/crate/secure/loot/attackby(obj/item/weapon/W, mob/user) if(locked) - if (istype(W, /obj/item/weapon/card/emag)) - user << "The crate's anti-tamper system activates!" - var/turf/T = get_turf(src.loc) - explosion(T, -1, -1, 1, 1) - qdel(src) - return - if (istype(W, /obj/item/device/multitool)) + if(istype(W, /obj/item/weapon/card/emag)) + boom(user) + if(istype(W, /obj/item/device/multitool)) user << "DECA-CODE LOCK REPORT:" - if (attempts == 1) + if(attempts == 1) user << "* Anti-Tamper Bomb will activate on next failed access attempt." else user << "* Anti-Tamper Bomb will activate after [src.attempts] failed access attempts." - if (lastattempt != null) + if(lastattempt != null) var/list/guess = list() var/bulls = 0 var/cows = 0 @@ -213,3 +201,17 @@ user << "Last code attempt had [bulls] correct digits at correct positions and [cows] correct digits at incorrect positions." else ..() else ..() + +/obj/structure/closet/crate/secure/loot/togglelock(mob/user) + if(locked) + boom(user) + else + ..() + +/obj/structure/closet/crate/secure/loot/proc/boom(mob/user) + user << "The crate's anti-tamper system activates!" + for(var/atom/movable/AM in src) + qdel(AM) + var/turf/T = get_turf(src) + explosion(T, -1, -1, 1, 1) + qdel(src) \ No newline at end of file diff --git a/code/modules/mining/mine_items.dm b/code/modules/mining/mine_items.dm index 40c0ea1d568..2bc0f1ca913 100644 --- a/code/modules/mining/mine_items.dm +++ b/code/modules/mining/mine_items.dm @@ -162,8 +162,8 @@ /obj/structure/closet/crate/miningcar desc = "A mining car. This one doesn't work on rails, but has to be dragged." name = "Mining car (not for rails)" - icon_crate = "miningcar" icon_state = "miningcar" + /*****************************Survival Pod********************************/ diff --git a/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm b/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm index 4f01f0ca45d..6f3d4b26df3 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm @@ -262,7 +262,9 @@ Doesn't work on other aliens/AI.*/ for(var/atom/movable/A in user.stomach_contents) user.stomach_contents.Remove(A) A.loc = user.loc - A.update_pipe_vision() + if(isliving(A)) + var/mob/M = A + M.reset_perspective() user.visible_message("[user] hurls out the contents of their stomach!") return diff --git a/code/modules/mob/living/carbon/brain/MMI.dm b/code/modules/mob/living/carbon/brain/MMI.dm index 65a472c8178..416e1789979 100644 --- a/code/modules/mob/living/carbon/brain/MMI.dm +++ b/code/modules/mob/living/carbon/brain/MMI.dm @@ -8,7 +8,7 @@ w_class = 3 origin_tech = "biotech=3" var/braintype = "Cyborg" - + var/obj/item/device/radio/radio = null //Let's give it a radio. var/syndiemmi = 0 //Whether or not this is a Syndicate MMI var/mob/living/carbon/brain/brainmob = null //The current occupant. var/mob/living/silicon/robot = null //Appears unused. @@ -18,13 +18,13 @@ /obj/item/device/mmi/update_icon() if(brain) if(istype(brain,/obj/item/organ/internal/brain/alien)) - if(brain.brainmob && brain.brainmob.stat == DEAD) + if(brainmob && brainmob.stat == DEAD) icon_state = "mmi_alien_dead" else icon_state = "mmi_alien" braintype = "Xenoborg" //HISS....Beep. else - if(brain.brainmob && brain.brainmob.stat == DEAD) + if(brainmob && brainmob.stat == DEAD) icon_state = "mmi_dead" else icon_state = "mmi_full" @@ -32,6 +32,12 @@ else icon_state = "mmi_empty" +/obj/item/device/mmi/New() + ..() + radio = new(src) //Spawns a radio inside the MMI. + radio.broadcasting = 0 //researching radio mmis turned the robofabs into radios because this didnt start as 0. + + /obj/item/device/mmi/attackby(obj/item/O, mob/user, params) user.changeNext_move(CLICK_CD_MELEE) @@ -71,14 +77,15 @@ return - if(brainmob) + else if(brainmob) O.attack(brainmob, user) //Oh noooeeeee return ..() /obj/item/device/mmi/attack_self(mob/user) if(!brain) - user << "You upend the MMI, but there's nothing in it!" + radio.on = !radio.on + user << "You toggle the MMI's radio system [radio.on==1 ? "on" : "off"]." else user << "You unlock and upend the MMI, spilling the brain onto the floor." @@ -118,19 +125,8 @@ update_icon() return -/obj/item/device/mmi/radio_enabled - name = "Radio-enabled Man-Machine Interface" - desc = "The Warrior's bland acronym, MMI, obscures the true horror of this monstrosity, that nevertheless has become standard-issue on Nanotrasen stations. This one comes with a built-in radio." - origin_tech = "biotech=4" - var/obj/item/device/radio/radio = null //Let's give it a radio. - -/obj/item/device/mmi/radio_enabled/New() - ..() - radio = new(src) //Spawns a radio inside the MMI. - radio.broadcasting = 0 //researching radio mmis turned the robofabs into radios because this didnt start as 0. - -/obj/item/device/mmi/radio_enabled/verb/Toggle_Listening() +/obj/item/device/mmi/verb/Toggle_Listening() set name = "Toggle Listening" set desc = "Toggle listening channel on or off." set category = "MMI" @@ -139,6 +135,9 @@ if(brainmob.stat) brainmob << "Can't do that while incapacitated or dead!" + if(!radio.on) + brainmob << "Your radio is disabled!" + return radio.listening = radio.listening==1 ? 0 : 1 brainmob << "Radio is [radio.listening==1 ? "now" : "no longer"] receiving broadcast." @@ -183,4 +182,8 @@ /obj/item/device/mmi/syndie name = "Syndicate Man-Machine Interface" desc = "Syndicate's own brand of MMI. It enforces laws designed to help Syndicate agents achieve their goals upon cyborgs created with it, but doesn't fit in Nanotrasen AI cores." - syndiemmi = 1 \ No newline at end of file + syndiemmi = 1 + +/obj/item/device/mmi/syndie/New() + ..() + radio.on = 0 \ No newline at end of file diff --git a/code/modules/mob/living/carbon/brain/brain.dm b/code/modules/mob/living/carbon/brain/brain.dm index 0e553eeb6b3..b4d911bec6b 100644 --- a/code/modules/mob/living/carbon/brain/brain.dm +++ b/code/modules/mob/living/carbon/brain/brain.dm @@ -37,4 +37,7 @@ return 1 /mob/living/carbon/brain/flash_eyes(intensity = 1, override_blindness_check = 0, affect_silicon = 0) - return // no eyes, no flashing \ No newline at end of file + return // no eyes, no flashing + +/mob/living/carbon/brain/update_damage_hud() + return //no red circles for brain \ No newline at end of file diff --git a/code/modules/mob/living/carbon/brain/death.dm b/code/modules/mob/living/carbon/brain/death.dm index 5931a033626..9e79f8dba52 100644 --- a/code/modules/mob/living/carbon/brain/death.dm +++ b/code/modules/mob/living/carbon/brain/death.dm @@ -1,15 +1,15 @@ /mob/living/carbon/brain/death(gibbed) if(stat == DEAD) return + stat = DEAD + if(!gibbed && container && istype(container, /obj/item/device/mmi))//If not gibbed but in a container. var/obj/item/device/mmi = container mmi.visible_message("[src]'s MMI flatlines!", \ "You hear something flatline.") mmi.update_icon() - stat = DEAD - - return ..(gibbed) + return ..() /mob/living/carbon/brain/gib(animation = 0) if(container && istype(container, /obj/item/device/mmi)) diff --git a/code/modules/mob/living/carbon/brain/life.dm b/code/modules/mob/living/carbon/brain/life.dm index a9363ab8065..866ea1a48d1 100644 --- a/code/modules/mob/living/carbon/brain/life.dm +++ b/code/modules/mob/living/carbon/brain/life.dm @@ -69,6 +69,7 @@ set_blindness(0) + /* //currently unused feature, since brain outside a mmi is always dead. /mob/living/carbon/brain/proc/handle_brain_revival_life() if(stat != DEAD) diff --git a/code/modules/mob/living/carbon/brain/say.dm b/code/modules/mob/living/carbon/brain/say.dm index 1086ba0ef1d..b2f9a4515f5 100644 --- a/code/modules/mob/living/carbon/brain/say.dm +++ b/code/modules/mob/living/carbon/brain/say.dm @@ -10,8 +10,8 @@ ..() /mob/living/carbon/brain/radio(message, message_mode, list/spans) - if(message_mode && istype(container, /obj/item/device/mmi/radio_enabled)) - var/obj/item/device/mmi/radio_enabled/R = container + if(message_mode && istype(container, /obj/item/device/mmi)) + var/obj/item/device/mmi/R = container if(R.radio) R.radio.talk_into(src, message, , spans) return ITALICS | REDUCE_RANGE diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index 3b517ef6473..f4a47adc483 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -808,7 +808,7 @@ var/const/GALOSHES_DONT_HELP = 4 /mob/living/carbon/proc/update_internals_hud_icon(internal_state = 0) if(hud_used && hud_used.internals) - hud_used.internals = "internal[internal_state]" + hud_used.internals.icon_state = "internal[internal_state]" /mob/living/carbon/update_stat() if(status_flags & GODMODE) diff --git a/code/modules/mob/living/death.dm b/code/modules/mob/living/death.dm index a0384413aa9..a62d0de5c43 100644 --- a/code/modules/mob/living/death.dm +++ b/code/modules/mob/living/death.dm @@ -52,6 +52,7 @@ sleeping = 0 update_sight() hide_fullscreens() + update_damage_hud() update_health_hud() update_canmove() diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 6af8dc1364d..8235f9b02a7 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -961,6 +961,7 @@ Sorry Giacom. Please don't be mad :( if(total_health <= config.health_threshold_crit && !stat) src << "You're too exhausted to keep going..." Weaken(5) + setStaminaLoss(health - 2) update_health_hud() /mob/proc/update_sight() diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm index a41f907d439..16a6f2ba8f2 100644 --- a/code/modules/mob/living/living_defense.dm +++ b/code/modules/mob/living/living_defense.dm @@ -184,13 +184,14 @@ add_logs(user, src, "grabbed", addition="passively") - var/obj/item/weapon/grab/G = new /obj/item/weapon/grab(user, src) + if(anchored || !Adjacent(user)) + return 0 if(buckled) user << "You cannot grab [src], \he is buckled in!" return 0 - if(!G) //the grab will delete itself in New if src is anchored - return 0 - user.put_in_active_hand(G) + var/obj/item/weapon/grab/G = new /obj/item/weapon/grab(user, src) + if(!user.put_in_active_hand(G)) //if we can't put the grab in our hand for some reason, we delete it. + qdel(G) G.synch() LAssailant = user diff --git a/code/modules/mob/living/login.dm b/code/modules/mob/living/login.dm index 20c14999aee..24634ca635a 100644 --- a/code/modules/mob/living/login.dm +++ b/code/modules/mob/living/login.dm @@ -10,13 +10,10 @@ if("sandbox") CanBuild() - update_sight() - reload_fullscreen() update_damage_hud() update_health_hud() //Vents if(ventcrawler) src << "You can ventcrawl! Use alt+click on vents to quickly travel about the station." - //Should update regardless of if we can ventcrawl, since we can end up in pipes in other ways. - update_pipe_vision(loc) + diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 110aac2924b..49a01873380 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -112,7 +112,7 @@ //MMI stuff. Held togheter by magic. ~Miauw if(!mmi || !mmi.brainmob) - mmi = new(src) + mmi = new (src) mmi.brain = new /obj/item/organ/internal/brain(mmi) mmi.brain.name = "[real_name]'s brain" mmi.icon_state = "mmi_full" diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm index bcae160d1f0..0f18a75e7c0 100644 --- a/code/modules/mob/living/silicon/silicon.dm +++ b/code/modules/mob/living/silicon/silicon.dm @@ -485,3 +485,34 @@ if(changed) animate(src, transform = ntransform, time = 2,easing = EASE_IN|EASE_OUT) return ..() + + +/mob/living/silicon/Stun(amount) + if(status_flags & CANSTUN) + stunned = max(max(stunned,amount),0) //can't go below 0, getting a low amount of stun doesn't lower your current stun + update_stat() + +/mob/living/silicon/SetStunned(amount) //if you REALLY need to set stun to a set amount without the whole "can't go below current stunned" + if(status_flags & CANSTUN) + stunned = max(amount,0) + update_stat() + +/mob/living/silicon/AdjustStunned(amount) + if(status_flags & CANSTUN) + stunned = max(stunned + amount,0) + update_stat() + +/mob/living/silicon/Weaken(amount, ignore_canweaken = 0) + if(status_flags & CANWEAKEN || ignore_canweaken) + weakened = max(max(weakened,amount),0) + update_stat() + +/mob/living/silicon/SetWeakened(amount) + if(status_flags & CANWEAKEN) + weakened = max(amount,0) + update_stat() + +/mob/living/silicon/AdjustWeakened(amount) + if(status_flags & CANWEAKEN) + weakened = max(weakened + amount,0) + update_stat() diff --git a/code/modules/mob/living/simple_animal/bot/bot.dm b/code/modules/mob/living/simple_animal/bot/bot.dm index aaa61f49a39..0406f09bb77 100644 --- a/code/modules/mob/living/simple_animal/bot/bot.dm +++ b/code/modules/mob/living/simple_animal/bot/bot.dm @@ -18,7 +18,7 @@ speak_emote = list("states") bubble_icon = "machine" - faction = list("neutral, silicon") + faction = list("neutral", "silicon") var/obj/machinery/bot_core/bot_core = null var/bot_core_type = /obj/machinery/bot_core @@ -282,7 +282,7 @@ return var/obj/item/weapon/weldingtool/WT = W if(WT.remove_fuel(0, user)) - health = min(maxHealth, health+10) + adjustHealth(-10) user.visible_message("[user] repairs [src]!","You repair [src].") else user << "The welder must be on for this task!" diff --git a/code/modules/mob/living/simple_animal/bot/mulebot.dm b/code/modules/mob/living/simple_animal/bot/mulebot.dm index 836a0d63579..5fdb5a4d35b 100644 --- a/code/modules/mob/living/simple_animal/bot/mulebot.dm +++ b/code/modules/mob/living/simple_animal/bot/mulebot.dm @@ -17,8 +17,8 @@ var/global/mulebot_count = 0 density = 1 anchored = 1 animate_movement=1 - health = 150 - maxHealth = 150 + health = 50 + maxHealth = 50 damage_coeff = list(BRUTE = 0.5, BURN = 0.7, TOX = 0, CLONE = 0, STAMINA = 0, OXY = 0) a_intent = "harm" //No swapping buckle_lying = 0 @@ -649,9 +649,6 @@ var/global/mulebot_count = 0 // called from mob/living/carbon/human/Crossed() // when mulebot is in the same loc /mob/living/simple_animal/bot/mulebot/proc/RunOver(mob/living/carbon/human/H) - if(client) - return - add_logs(src, H, "run over", null, "(DAMTYPE: [uppertext(BRUTE)])") H.visible_message("[src] drives over [H]!", \ "[src] drives over you!") diff --git a/code/modules/mob/living/simple_animal/bot/secbot.dm b/code/modules/mob/living/simple_animal/bot/secbot.dm index a58cfb0ef85..0ce588cdd87 100644 --- a/code/modules/mob/living/simple_animal/bot/secbot.dm +++ b/code/modules/mob/living/simple_animal/bot/secbot.dm @@ -41,7 +41,7 @@ var/turf/Tsec = get_turf(src) new /obj/item/weapon/stock_parts/cell/potato(Tsec) var/obj/item/weapon/reagent_containers/food/drinks/drinkingglass/shotglass/S = new(Tsec) - S.list_reagents = list("whiskey" = 15) + S.reagents.add_reagent("whiskey", 15) S.on_reagent_change() ..() diff --git a/code/modules/mob/living/simple_animal/friendly/cat.dm b/code/modules/mob/living/simple_animal/friendly/cat.dm index bfb95d5d498..e61bc8e697b 100644 --- a/code/modules/mob/living/simple_animal/friendly/cat.dm +++ b/code/modules/mob/living/simple_animal/friendly/cat.dm @@ -30,6 +30,27 @@ var/mob/living/simple_animal/mouse/movement_target gold_core_spawnable = 2 +/mob/living/simple_animal/pet/cat/space + name = "space cat" + desc = "It's a cat... in space!" + icon_state = "spacecat" + icon_living = "spacecat" + icon_dead = "spacecat_dead" + unsuitable_atmos_damage = 0 + minbodytemp = TCMB + maxbodytemp = T0C + 40 + +/mob/living/simple_animal/pet/cat/kitten + name = "kitten" + desc = "D'aaawwww" + icon_state = "kitten" + icon_living = "kitten" + icon_dead = "kitten_dead" + gender = NEUTER + density = 0 + pass_flags = PASSMOB + mob_size = MOB_SIZE_SMALL + //RUNTIME IS ALIVE! SQUEEEEEEEE~ /mob/living/simple_animal/pet/cat/Runtime name = "Runtime" @@ -40,6 +61,10 @@ gender = FEMALE gold_core_spawnable = 0 +/mob/living/simple_animal/pet/cat/Proc + name = "Proc" + gold_core_spawnable = 0 + /mob/living/simple_animal/pet/cat/Life() //MICE! if((src.loc) && isturf(src.loc)) @@ -79,34 +104,19 @@ stop_automated_movement = 1 walk_to(src,movement_target,0,3) -/mob/living/simple_animal/pet/cat/Proc - name = "Proc" - gold_core_spawnable = 0 - -/mob/living/simple_animal/pet/cat/kitten - name = "kitten" - desc = "D'aaawwww" - icon_state = "kitten" - icon_living = "kitten" - icon_dead = "kitten_dead" - gender = NEUTER - density = 0 - pass_flags = PASSMOB - mob_size = MOB_SIZE_SMALL - /mob/living/simple_animal/pet/cat/attack_hand(mob/living/carbon/human/M) . = ..() switch(M.a_intent) if("help") - wuv(1,M) + wuv(1, M) if("harm") - wuv(-1,M) + wuv(-1, M) /mob/living/simple_animal/pet/cat/proc/wuv(change, mob/M) if(change) if(change > 0) if(M && stat != DEAD) - flick_overlay(image('icons/mob/animal.dmi',src,"heart-ani2",MOB_LAYER+1), list(M.client), 20) + flick_overlay(image('icons/mob/animal.dmi', src, "heart-ani2", MOB_LAYER+1), list(M.client), 20) emote("me", 1, "purrs!") else if(M && stat != DEAD) diff --git a/code/modules/mob/living/simple_animal/friendly/drone/drones_as_items.dm b/code/modules/mob/living/simple_animal/friendly/drone/drones_as_items.dm index 1b611d1da57..f42d394094f 100644 --- a/code/modules/mob/living/simple_animal/friendly/drone/drones_as_items.dm +++ b/code/modules/mob/living/simple_animal/friendly/drone/drones_as_items.dm @@ -1,3 +1,4 @@ +#define DRONE_MINIMUM_AGE 14 /////////////////// //DRONES AS ITEMS// @@ -24,6 +25,12 @@ /obj/item/drone_shell/attack_ghost(mob/user) if(jobban_isbanned(user,"drone")) return + if(config.use_age_restriction_for_jobs) + if(!isnum(user.client.player_age)) //apparently what happens when there's no DB connected. just don't let anybody be a drone without admin intervention + return + if(user.client.player_age < DRONE_MINIMUM_AGE) + user << "You're too new to play as a drone! Please try again in [DRONE_MINIMUM_AGE - user.client.player_age] days." + return if(!ticker.mode) user << "Can't become a drone before the game has started." return @@ -74,4 +81,4 @@ if(!D) return icon_state = "[D.visualAppearence]_hat" - . = icon_state \ No newline at end of file + . = icon_state diff --git a/code/modules/mob/living/simple_animal/friendly/drone/say.dm b/code/modules/mob/living/simple_animal/friendly/drone/say.dm index 5bd5dbb8eb7..d4e5ba43abe 100644 --- a/code/modules/mob/living/simple_animal/friendly/drone/say.dm +++ b/code/modules/mob/living/simple_animal/friendly/drone/say.dm @@ -22,11 +22,9 @@ /mob/living/simple_animal/drone/proc/alert_drones(msg, dead_can_hear = 0) for(var/W in mob_list) - var/mob/M = W - if(istype(M, /mob/living/simple_animal/drone) && M.stat != DEAD) - for(var/F in src.faction) - if(F in M.faction) - M << msg + var/mob/living/simple_animal/drone/M = W + if(istype(M) && M.stat != DEAD && faction_check(M)) //if it's a living drone with matching factions, it gets a message + M << msg if(dead_can_hear && (M in dead_mob_list)) M << "(F) [msg]" diff --git a/code/modules/mob/living/simple_animal/hostile/alien.dm b/code/modules/mob/living/simple_animal/hostile/alien.dm index 8bd71dd3313..c91631ef175 100644 --- a/code/modules/mob/living/simple_animal/hostile/alien.dm +++ b/code/modules/mob/living/simple_animal/hostile/alien.dm @@ -150,3 +150,27 @@ adjustBruteLoss(2) else if(bodytemperature > maxbodytemp) adjustBruteLoss(20) + + +/mob/living/simple_animal/hostile/alien/maid + name = "lusty xenomorph maid" + melee_damage_lower = 0 + melee_damage_upper = 0 + a_intent = "help" + friendly = "caresses" + environment_smash = 0 + gold_core_spawnable = 1 + icon_state = "maid" + icon_living = "maid" + icon_dead = "maid_dead" + +/mob/living/simple_animal/hostile/alien/maid/AttackingTarget() + if(istype(target, /atom/movable)) + if(istype(target, /obj/effect/decal/cleanable)) + visible_message("[src] cleans up \the [target].") + qdel(target) + return + var/atom/movable/M = target + M.clean_blood() + visible_message("[src] polishes \the [target].") + diff --git a/code/modules/mob/living/simple_animal/parrot.dm b/code/modules/mob/living/simple_animal/parrot.dm index 402517cc932..13e81b5e7ed 100644 --- a/code/modules/mob/living/simple_animal/parrot.dm +++ b/code/modules/mob/living/simple_animal/parrot.dm @@ -119,7 +119,7 @@ /mob/living/simple_animal/parrot/examine(mob/user) ..() if(stat) - user << pick("This parrot is no more", " This is a late parrot", "This is an ex-parrot") + user << pick("This parrot is no more", "This is a late parrot", "This is an ex-parrot") /mob/living/simple_animal/parrot/death(gibbed) if(held_item) @@ -882,19 +882,23 @@ ..() /mob/living/simple_animal/parrot/Poly/Life() - if(ticker.current_state == GAME_STATE_FINISHED && !memory_saved) + if(!stat && ticker.current_state == GAME_STATE_FINISHED && !memory_saved) + rounds_survived += 1 + if(rounds_survived > longest_survival) + longest_survival = rounds_survived Write_Memory() ..() /mob/living/simple_animal/parrot/Poly/death(gibbed) + rounds_survived = 0 Write_Memory() ..(gibbed) /mob/living/simple_animal/parrot/Poly/proc/Read_Memory() var/savefile/S = new /savefile("data/npc_saves/Poly.sav") S["phrases"] >> speech_buffer - S["rounds_survived"] >> rounds_survived - S["longest_survival"] >> longest_survival + S["roundssurvived"] >> rounds_survived + S["longestsurvival"] >> longest_survival if(isnull(speech_buffer)) speech_buffer = list() @@ -902,11 +906,6 @@ /mob/living/simple_animal/parrot/Poly/proc/Write_Memory() var/savefile/S = new /savefile("data/npc_saves/Poly.sav") S["phrases"] << speech_buffer - if(health > 0) - S["rounds_survived"] << rounds_survived + 1 - if(rounds_survived == longest_survival) - S["longest_survival"] << longest_survival + 1 - else - S["rounds_survived"] << 0 - + S["roundssurvived"] << rounds_survived + S["longestsurvival"] << longest_survival memory_saved = 1 diff --git a/code/modules/mob/living/ventcrawling.dm b/code/modules/mob/living/ventcrawling.dm index 3178e8fb130..45880e12a07 100644 --- a/code/modules/mob/living/ventcrawling.dm +++ b/code/modules/mob/living/ventcrawling.dm @@ -78,7 +78,7 @@ var/list/ventcrawl_machinery = list(/obj/machinery/atmospherics/components/unary /mob/living/proc/add_ventcrawl(obj/machinery/atmospherics/starting_machine) - if(!istype(starting_machine)) + if(!istype(starting_machine) || !starting_machine.can_see_pipes()) return var/list/totalMembers = list() diff --git a/code/modules/mob/login.dm b/code/modules/mob/login.dm index b0b37ca266b..ed0e6f7dac4 100644 --- a/code/modules/mob/login.dm +++ b/code/modules/mob/login.dm @@ -30,6 +30,7 @@ update_Login_details() world.update_status() client.screen = list() //remove hud items just in case + client.images = list() if(!hud_used) create_mob_hud() diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 5e0485cd005..de75be286f4 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -288,6 +288,7 @@ var/next_mob_id = 0 AT.get_remote_view_fullscreens(src) else clear_fullscreen("remote_view", 0) + update_pipe_vision() /mob/proc/show_inv(mob/user) @@ -608,7 +609,7 @@ var/next_mob_id = 0 else stat("Failsafe Controller:", "ERROR") if(Master) - stat("Subsystems:", "[round(Master.subsystem_cost, 0.001)]ds") + stat("Subsystems:", "[round(Master.subsystem_cost, 0.01)]ds") stat(null) for(var/datum/subsystem/SS in Master.subsystems) SS.stat_entry() diff --git a/code/modules/mob/mob_grab.dm b/code/modules/mob/mob_grab.dm index 6ee0a9adf3d..d8032f467bf 100644 --- a/code/modules/mob/mob_grab.dm +++ b/code/modules/mob/mob_grab.dm @@ -19,14 +19,9 @@ /obj/item/weapon/grab/New(mob/user, mob/victim) ..() - loc = user assailant = user affecting = victim - if(affecting.anchored || !user.Adjacent(victim)) - qdel(src) - return - hud = new /obj/screen/grab(src) hud.icon_state = "reinforce" hud.name = "reinforce grab" diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm index 1e4d87e03cb..2cb2a179cb3 100644 --- a/code/modules/mob/transform_procs.dm +++ b/code/modules/mob/transform_procs.dm @@ -94,8 +94,6 @@ if (tr_flags & TR_DEFAULTMSG) O << "You are now a monkey." - O.update_pipe_vision() - for(var/A in loc.vars) if(loc.vars[A] == src) loc.vars[A] = O @@ -216,8 +214,6 @@ if (tr_flags & TR_DEFAULTMSG) O << "You are now a human." - O.update_pipe_vision() - . = O for(var/A in loc.vars) @@ -263,8 +259,6 @@ else O.key = key - O.update_pipe_vision() - var/obj/loc_landmark for(var/obj/effect/landmark/start/sloc in landmarks_list) if (sloc.name != "AI") @@ -345,8 +339,6 @@ else O.key = key - O.update_pipe_vision() - if (config.rename_cyborg) O.rename_self("cyborg") @@ -385,7 +377,6 @@ new_xeno.key = key new_xeno << "You are now an alien." - new_xeno.update_pipe_vision() . = new_xeno qdel(src) @@ -418,7 +409,6 @@ new_slime.key = key new_slime << "You are now a slime. Skreee!" - new_slime.update_pipe_vision() . = new_slime qdel(src) @@ -467,7 +457,6 @@ new_corgi.key = key new_corgi << "You are now a Corgi. Yap Yap!" - new_corgi.update_pipe_vision() . = new_corgi qdel(src) @@ -501,7 +490,6 @@ new_mob << "You suddenly feel more... animalistic." - new_mob.update_pipe_vision() . = new_mob qdel(src) @@ -519,7 +507,6 @@ new_mob.key = key new_mob.a_intent = "harm" new_mob << "You feel more... animalistic" - new_mob.update_pipe_vision() . = new_mob qdel(src) diff --git a/code/modules/paperwork/paper.dm b/code/modules/paperwork/paper.dm index 32a1777ede3..25c5eb7a6b3 100644 --- a/code/modules/paperwork/paper.dm +++ b/code/modules/paperwork/paper.dm @@ -34,9 +34,8 @@ ..() pixel_y = rand(-8, 8) pixel_x = rand(-9, 9) - spawn(2) - update_icon() - updateinfolinks() + update_icon() + updateinfolinks() /obj/item/weapon/paper/update_icon() diff --git a/code/modules/power/supermatter/supermatter_crate.dm b/code/modules/power/supermatter/supermatter_crate.dm deleted file mode 100644 index dd65e75cfc5..00000000000 --- a/code/modules/power/supermatter/supermatter_crate.dm +++ /dev/null @@ -1,7 +0,0 @@ -/datum/supply_packs/engineering/engine/supermatter_shard - name = "Supermatter Shard Crate" - contains = list(/obj/machinery/power/supermatter_shard) - cost = 100 //So cargo thinks twice before killing themselves with it - containertype = /obj/structure/closet/crate/secure - containername = "supermatter shard crate" - access = access_ce diff --git a/code/modules/power/tesla/coil.dm b/code/modules/power/tesla/coil.dm index bf6f80dfdc3..682e22f5915 100644 --- a/code/modules/power/tesla/coil.dm +++ b/code/modules/power/tesla/coil.dm @@ -47,8 +47,7 @@ flick("coilhit", src) playsound(src.loc, 'sound/magic/LightningShock.ogg', 100, 1, extrarange = 5) tesla_zap(src, 5, power_produced) - spawn(10) - being_shocked = 0 + addtimer(src, "reset_shocked", 10) /obj/machinery/power/grounding_rod name = "Grounding Rod" @@ -81,4 +80,4 @@ default_deconstruction_crowbar(W) /obj/machinery/power/grounding_rod/tesla_act(var/power) - flick("coil_shock_1", src) \ No newline at end of file + flick("coil_shock_1", src) diff --git a/code/modules/power/tesla/energy_ball.dm b/code/modules/power/tesla/energy_ball.dm index d3c983b6077..f34f92ce559 100644 --- a/code/modules/power/tesla/energy_ball.dm +++ b/code/modules/power/tesla/energy_ball.dm @@ -1,5 +1,5 @@ -#define TESLA_DEFAULT_POWER 3476520 -#define TESLA_MINI_POWER 1738260 +#define TESLA_DEFAULT_POWER 1738260 +#define TESLA_MINI_POWER 869130 var/list/blacklisted_tesla_types = list(/obj/machinery/atmospherics, /obj/machinery/power/emitter, @@ -28,30 +28,44 @@ var/list/blacklisted_tesla_types = list(/obj/machinery/atmospherics, grav_pull = 0 contained = 0 density = 1 + var/list/orbiting_balls = list() var/produced_power - var/is_orbiting + var/energy_to_raise = 32 + var/energy_to_lower = -20 /obj/singularity/energy_ball/Destroy() - for(var/obj/singularity/energy_ball/EB in orbiting_balls) + if(orbiting && istype(orbiting, /obj/singularity/energy_ball)) + var/obj/singularity/energy_ball/EB = orbiting + EB.orbiting_balls -= src + orbiting = null + + for(var/ball in orbiting_balls) + var/obj/singularity/energy_ball/EB = ball qdel(EB) + return ..() /obj/singularity/energy_ball/process() - if(!is_orbiting) + if(!orbiting) handle_energy() - var/amount_to_move = 2 + orbiting_balls.len * 2 - var/what_does_the_scouter_say_about_the_balls_power_level = (TESLA_DEFAULT_POWER + (TESLA_MINI_POWER * orbiting_balls.len)) - move_the_basket_ball(amount_to_move) + + move_the_basket_ball(2 + orbiting_balls.len * 2) + + playsound(src.loc, 'sound/magic/lightningbolt.ogg', 100, 1, extrarange = 15) + pixel_x = 0 pixel_y = 0 - playsound(src.loc, 'sound/magic/lightningbolt.ogg', 100, 1, extrarange = 15) - tesla_zap(src, 7, what_does_the_scouter_say_about_the_balls_power_level) + + dir = tesla_zap(src, 7, TESLA_DEFAULT_POWER) + pixel_x = -32 pixel_y = -32 - energy += rand(1,3) // ensure it generates energy without needing to be blasted by the PA too much due to its size, and that a tesla engine will always get bigger over time + for (var/ball in orbiting_balls) + tesla_zap(ball, rand(1, Clamp(orbiting_balls.len, 3, 7)), TESLA_MINI_POWER) else energy = 0 // ensure we dont have miniballs of miniballs + return /obj/singularity/energy_ball/examine(mob/user) @@ -61,29 +75,40 @@ var/list/blacklisted_tesla_types = list(/obj/machinery/atmospherics, /obj/singularity/energy_ball/proc/move_the_basket_ball(var/move_amount) - for(var/i = 0, i < move_amount, i++) - var/move_dir = pick(alldirs) - var/turf/T = get_step(src,move_dir) + //we face the last thing we zapped, so this lets us favor that direction a bit + var/first_move = dir + for(var/i in 0 to move_amount) + var/move_dir = pick(alldirs + first_move) //give the first move direction a bit of favoring. + var/turf/T = get_step(src, move_dir) if(can_move(T)) - loc = get_step(src,move_dir) + loc = T /obj/singularity/energy_ball/proc/handle_energy() - if(energy >= 300) - energy -= 300 + if(energy >= energy_to_raise) + energy_to_lower = energy_to_raise - 20 + energy_to_raise += energy_to_raise + playsound(src.loc, 'sound/magic/lightning_chargeup.ogg', 100, 1, extrarange = 15) spawn(100) var/obj/singularity/energy_ball/EB = new(loc) - orbiting_balls.Add(EB) - poi_list.Remove(EB) - EB.transform *= pick(0.3,0.4,0.5,0.6,0.7) - EB.is_orbiting = 1 + + EB.transform *= pick(0.3, 0.4, 0.5, 0.6, 0.7) var/icon/I = icon(icon,icon_state,dir) - var/orbitsize = (I.Width()+I.Height())*pick(0.5,0.6,0.7) - orbitsize -= (orbitsize/world.icon_size)*(world.icon_size*0.25) - EB.orbit(src,orbitsize, pick(FALSE,TRUE), rand(10,25), pick(3,4,5,6,36)) + var/orbitsize = (I.Width() + I.Height()) * pick(0.4, 0.5, 0.6, 0.7, 0.8) + orbitsize -= (orbitsize / world.icon_size) * (world.icon_size * 0.25) + EB.orbit(src, orbitsize, pick(FALSE, TRUE), rand(10, 25), pick(3, 4, 5, 6, 36)) + else if(energy < energy_to_lower && orbiting_balls.len) + energy_to_raise = energy_to_raise * 0.5 + energy_to_lower = (energy_to_raise * 0.5) - 20 + + var/Orchiectomy_target = pick(orbiting_balls) + qdel(Orchiectomy_target) + + else if(orbiting_balls.len) + energy -= orbiting_balls.len /obj/singularity/energy_ball/Bump(atom/A) dust_mobs(A) @@ -91,120 +116,121 @@ var/list/blacklisted_tesla_types = list(/obj/machinery/atmospherics, /obj/singularity/energy_ball/Bumped(atom/A) dust_mobs(A) +/obj/singularity/energy_ball/orbit(obj/singularity/energy_ball/target) + if (istype(target)) + target.orbiting_balls += src + poi_list -= src + + . = ..() + + if (istype(target)) + target.orbiting_balls -= src + /obj/singularity/energy_ball/proc/dust_mobs(atom/A) if(istype(A, /mob/living/carbon)) var/mob/living/carbon/C = A C.dust() return -/proc/get_closest_atom(type, list, source) - var/closest_atom - var/closest_distance - for(var/A in list) - if(!istype(A, type)) - continue - var/distance = get_dist(source, A) - if(!closest_distance) - closest_distance = distance - closest_atom = A - else - if(closest_distance > distance) - closest_distance = distance - closest_atom = A - return closest_atom - /proc/tesla_zap(var/atom/source, zap_range = 3, power) + . = source.dir if(power < 1000) return - var/list/tesla_coils = list() - var/list/grounding_rods = list() - var/list/potential_machine_zaps = list() - var/list/potential_mob_zaps = list() - var/list/potential_structure_zaps = list() + + var/closest_dist = 0 var/closest_atom - for(var/atom/A in oview(source, zap_range)) + var/obj/machinery/power/tesla_coil/closest_tesla_coil + var/obj/machinery/power/grounding_rod/closest_grounding_rod + var/mob/living/closest_mob + var/obj/machinery/closest_machine + var/obj/structure/closest_structure + + for(var/A in oview(source, zap_range)) if(istype(A, /obj/machinery/power/tesla_coil)) + var/dist = get_dist(source, A) var/obj/machinery/power/tesla_coil/C = A - if(C.being_shocked) - continue - tesla_coils.Add(C) + if((dist < closest_dist || !closest_tesla_coil) && !C.being_shocked) + closest_dist = dist + + //we use both of these to save on istype and typecasting overhead later on + //while still allowing common code to run before hand + closest_tesla_coil = C + closest_atom = C + + + else if(closest_tesla_coil) + continue //no need checking these other things + + else if(istype(A, /obj/machinery/power/grounding_rod)) + var/dist = get_dist(source, A) + if(dist < closest_dist || !closest_grounding_rod) + closest_grounding_rod = A + closest_atom = A + closest_dist = dist + + else if(closest_grounding_rod || is_type_in_list(A, blacklisted_tesla_types)) continue - if(istype(A, /obj/machinery/power/grounding_rod)) - var/obj/machinery/power/grounding_rod/R = A - grounding_rods.Add(R) - continue - if(istype(A, /obj/machinery)) - var/obj/machinery/M = A - if(is_type_in_list(M, blacklisted_tesla_types)) - continue - if(M.being_shocked) - continue - potential_machine_zaps.Add(M) - continue - if(istype(A, /obj/structure)) - var/obj/structure/M = A - if(is_type_in_list(M, blacklisted_tesla_types)) - continue - if(M.being_shocked) - continue - potential_structure_zaps.Add(M) - continue - if(istype(A, /mob/living)) + + else if(istype(A, /mob/living)) + var/dist = get_dist(source, A) var/mob/living/L = A - if(L.stat == DEAD) - continue - if(is_type_in_list(L, blacklisted_tesla_types)) - continue - potential_mob_zaps.Add(L) + if((dist < closest_dist || !closest_mob) && L.stat != DEAD) + closest_mob = L + closest_atom = A + closest_dist = dist + + else if(closest_mob) continue - closest_atom = get_closest_atom(/obj/machinery/power/tesla_coil, tesla_coils, source) - if(closest_atom && istype(closest_atom, /obj/machinery/power/tesla_coil)) - var/obj/machinery/power/tesla_coil/C = closest_atom - source.Beam(C,icon_state="lightning[rand(1,12)]",icon='icons/effects/effects.dmi',time=5) - C.tesla_act(power) - return - if(!closest_atom) - closest_atom = get_closest_atom(/obj/machinery/power/grounding_rod, grounding_rods, source) - if(closest_atom && istype(closest_atom, /obj/machinery/power/grounding_rod)) - var/obj/machinery/power/grounding_rod/R = closest_atom - source.Beam(R,icon_state="lightning[rand(1,12)]",icon='icons/effects/effects.dmi',time=5) - R.tesla_act(power) - return - if(!closest_atom) - closest_atom = get_closest_atom(/mob/living, potential_mob_zaps, source) - if(closest_atom && istype(closest_atom, /mob/living)) - var/mob/living/L = closest_atom - var/shock_damage = Clamp(round(power/400), 10, 90) + rand(-5,5) - source.Beam(L,icon_state="lightning[rand(1,12)]",icon='icons/effects/effects.dmi',time=5) - L.electrocute_act(shock_damage, source, 1, tesla_shock = 1) - if(istype(L, /mob/living/silicon)) - var/mob/living/silicon/S = L - S.emp_act(2) - tesla_zap(S, 7, power / 1.5) // metallic folks bounce it further - else - tesla_zap(L, 5, power / 1.5) - return - if(!closest_atom) - closest_atom = get_closest_atom(/obj/machinery, potential_machine_zaps, source) - if(closest_atom) - var/obj/machinery/M = closest_atom - source.Beam(M,icon_state="lightning[rand(1,12)]",icon='icons/effects/effects.dmi',time=5) - M.tesla_act(power) - if(prob(85)) - M.emp_act(2) - else - if(prob(50)) - M.ex_act(3) - else - if(prob(90)) - M.ex_act(2) - else - M.ex_act(1) - return - if(!closest_atom) - closest_atom = get_closest_atom(/obj/structure, potential_structure_zaps, source) - if(closest_atom) - var/obj/structure/S = closest_atom - source.Beam(S,icon_state="lightning[rand(1,12)]",icon='icons/effects/effects.dmi',time=5) - S.tesla_act(power) - return + + else if(istype(A, /obj/machinery)) + var/obj/machinery/M = A + var/dist = get_dist(source, A) + if((dist < closest_dist || !closest_machine) && !M.being_shocked) + closest_machine = M + closest_atom = A + closest_dist = dist + + else if(closest_mob) + continue + + else if(istype(A, /obj/structure)) + var/obj/structure/S = A + var/dist = get_dist(source, A) + if((dist < closest_dist || !closest_tesla_coil) && !S.being_shocked) + closest_structure = S + closest_atom = A + closest_dist = dist + + + //Alright, we've done our loop, now lets see if was anything interesting in range + if(closest_atom) + //common stuff + source.Beam(closest_atom, icon_state="lightning[rand(1,12)]", icon='icons/effects/effects.dmi', time=5) + var/zapdir = get_dir(source, closest_atom) + if(zapdir) + . = closest_atom + + //per type stuff: + if(closest_tesla_coil) + closest_tesla_coil.tesla_act(power) + + else if(closest_grounding_rod) + closest_grounding_rod.tesla_act(power) + + else if(closest_mob) + var/shock_damage = Clamp(round(power/400), 10, 90) + rand(-5, 5) + closest_mob.electrocute_act(shock_damage, source, 1, tesla_shock = 1) + if(istype(closest_mob, /mob/living/silicon)) + var/mob/living/silicon/S = closest_mob + S.emp_act(2) + tesla_zap(S, 7, power / 1.5) // metallic folks bounce it further + else + tesla_zap(closest_mob, 5, power / 1.5) + + else if(closest_machine) + closest_machine.tesla_act(power) + + else if(closest_structure) + closest_structure.tesla_act(power) + + diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index 229a1cb6181..aa308644e11 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -144,11 +144,13 @@ return if(!can_shoot()) //Just because you can pull the trigger doesn't mean it can't shoot. + shoot_with_empty_chamber(user) return if(flag) - handle_suicide(user, target, params) // - return + if(user.zone_selected == "mouth") + handle_suicide(user, target, params) + return //Exclude lasertag guns from the CLUMSY check. diff --git a/code/modules/projectiles/guns/energy/special.dm b/code/modules/projectiles/guns/energy/special.dm index 636fc7074ba..8cc3b930ddf 100644 --- a/code/modules/projectiles/guns/energy/special.dm +++ b/code/modules/projectiles/guns/energy/special.dm @@ -306,5 +306,5 @@ item_state = "instagibblue" ammo_type = list(/obj/item/ammo_casing/energy/instakill/blue) -/obj/item/weapon/gun/energy/laser/instagib/emp_act() //implying you could stop the instagib +/obj/item/weapon/gun/energy/laser/instakill/emp_act() //implying you could stop the instagib return \ No newline at end of file diff --git a/code/modules/projectiles/guns/medbeam.dm b/code/modules/projectiles/guns/medbeam.dm index 8c6252489f2..25c641108d3 100644 --- a/code/modules/projectiles/guns/medbeam.dm +++ b/code/modules/projectiles/guns/medbeam.dm @@ -12,6 +12,7 @@ var/max_range = 8 var/active = 0 var/datum/beam/current_beam = null + var/mounted = 0 //Denotes if this is a handheld or mounted version heavy_weapon = 1 @@ -31,7 +32,8 @@ current_target = null /obj/item/weapon/gun/medbeam/process_fire(atom/target as mob|obj|turf, mob/living/user as mob|obj, message = 1, params, zone_override) - add_fingerprint(user) + if(isliving(user)) + add_fingerprint(user) if(current_target) LoseTarget() @@ -47,8 +49,9 @@ feedback_add_details("gun_fired","[src.type]") /obj/item/weapon/gun/medbeam/process() - var/mob/living/carbon/human/H = loc - if(!istype(H)) + + var/source = loc + if(!mounted && !ishuman(source)) LoseTarget() return @@ -58,24 +61,29 @@ if(world.time <= last_check+check_delay) return - + last_check = world.time - if(get_dist(H,current_target)>max_range || !los_check(H,current_target)) + if(get_dist(source, current_target)>max_range || !los_check(source, current_target)) LoseTarget() - H << "You lose control of the beam!" + if(ishuman(source)) + source << "You lose control of the beam!" return if(current_target) on_beam_tick(current_target) -/obj/item/weapon/gun/medbeam/proc/los_check(mob/user,mob/target) +/obj/item/weapon/gun/medbeam/proc/los_check(atom/movable/user, mob/target) var/turf/user_turf = user.loc - if(!istype(user_turf)) + if(mounted) + user_turf = get_turf(user) + else if(!istype(user_turf)) return 0 var/obj/dummy = new(user_turf) dummy.pass_flags |= PASSTABLE|PASSGLASS|PASSGRILLE //Grille/Glass so it can be used through common windows for(var/turf/turf in getline(user_turf,target)) + if(mounted && turf == user_turf) + continue //Mechs are dense and thus fail the check if(turf.density) qdel(dummy) return 0 @@ -97,10 +105,18 @@ /obj/item/weapon/gun/medbeam/proc/on_beam_tick(var/mob/living/target) target.adjustBruteLoss(-4) target.adjustFireLoss(-4) - return + return /obj/item/weapon/gun/medbeam/proc/on_beam_release(var/mob/living/target) return /obj/effect/ebeam/medical name = "medical beam" + +//////////////////////////////Mech Version/////////////////////////////// +/obj/item/weapon/gun/medbeam/mech + mounted = 1 + +/obj/item/weapon/gun/medbeam/mech/New() + ..() + SSobj.processing -= src //Mech mediguns do not process until installed, and are controlled by the holder obj diff --git a/code/modules/projectiles/guns/projectile/rechargable_magazine.dm b/code/modules/projectiles/guns/projectile/rechargable_magazine.dm index 06fd9b49731..d24dd02c71b 100644 --- a/code/modules/projectiles/guns/projectile/rechargable_magazine.dm +++ b/code/modules/projectiles/guns/projectile/rechargable_magazine.dm @@ -2,13 +2,14 @@ /obj/item/ammo_box/magazine/recharge name = "power pack" + desc = "A rechargeable, detachable battery that serves as a magazine for laser rifles." icon_state = "oldrifle-20" ammo_type = /obj/item/ammo_casing/caseless/laser caliber = "laser" max_ammo = 20 /obj/item/ammo_box/magazine/recharge/update_icon() - ..() + desc = "[initial(desc)] It has [stored_ammo.len] shots\s left." icon_state = "oldrifle-[round(ammo_count(),4)]" @@ -36,6 +37,7 @@ can_suppress = 0 burst_size = 0 action_button_name = null + fire_sound = 'sound/weapons/Laser.ogg' /obj/item/weapon/gun/projectile/automatic/laser/process_chamber(eject_casing = 0, empty_chamber = 1) ..() diff --git a/code/modules/reagents/chemistry/reagents/blob_reagents.dm b/code/modules/reagents/chemistry/reagents/blob_reagents.dm index e8d918142f7..faeb2da938b 100644 --- a/code/modules/reagents/chemistry/reagents/blob_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/blob_reagents.dm @@ -8,7 +8,7 @@ var/message = "The blob strikes you" //message sent to any mob hit by the blob var/message_living = null //extension to first mob sent to only living mobs i.e. silicons have no skin to be burnt -/datum/reagent/blob/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection) +/datum/reagent/blob/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O) return round(reac_volume * min(1.5 - touch_protection, 1), 0.1) //full touch protection means 50% volume, any prot below 0.5 means 100% volume. /datum/reagent/blob/proc/damage_reaction(obj/effect/blob/B, original_health, damage, damage_type, cause) //when the blob takes damage, do this @@ -29,10 +29,9 @@ blobbernaut_message = "rips" message_living = ", and you feel your skin ripping and tearing off" -/datum/reagent/blob/ripping_tendrils/reaction_mob(mob/living/M, method=TOUCH, reac_volume) +/datum/reagent/blob/ripping_tendrils/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O) reac_volume = ..() - if(M) - M.apply_damage(0.7*reac_volume, BRUTE) + M.apply_damage(0.7*reac_volume, BRUTE) if(M) M.adjustStaminaLoss(0.5*reac_volume) if(iscarbon(M)) @@ -47,13 +46,12 @@ color = "#E88D5D" message_living = ", and you feel sick" -/datum/reagent/blob/sporing_pods/reaction_mob(mob/living/M, method=TOUCH, reac_volume) +/datum/reagent/blob/sporing_pods/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O) reac_volume = ..() - if(M) - M.apply_damage(0.5*reac_volume, TOX) + M.apply_damage(0.5*reac_volume, TOX) /datum/reagent/blob/sporing_pods/damage_reaction(obj/effect/blob/B, original_health, damage, damage_type, cause) - if(!isnull(cause) && damage < 20 && original_health - damage <= 0 && prob(50)) //if the cause isn't fire or a bomb, the damage is less than 20, we're going to die from that damage, 50% chance of a shitty spore. + if(!isnull(cause) && damage <= 20 && original_health - damage <= 0 && prob(50)) //if the cause isn't fire or a bomb, the damage is less than 21, we're going to die from that damage, 50% chance of a shitty spore. B.visible_message("A spore floats free of the blob!") var/mob/living/simple_animal/hostile/blob/blobspore/weak/BS = new/mob/living/simple_animal/hostile/blob/blobspore/weak(B.loc) BS.overmind = B.overmind @@ -76,14 +74,13 @@ shortdesc = "will do medium brute damage." color = "#7B5A57" -/datum/reagent/blob/replicating_foam/reaction_mob(mob/living/M, method=TOUCH, reac_volume) +/datum/reagent/blob/replicating_foam/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O) reac_volume = ..() - if(M) - M.apply_damage(0.6*reac_volume, BRUTE) + M.apply_damage(0.6*reac_volume, BRUTE) /datum/reagent/blob/replicating_foam/damage_reaction(obj/effect/blob/B, original_health, damage, damage_type, cause) if(damage > 0 && original_health - damage > 0) - var/obj/effect/blob/newB = B.expand(null, 0) + var/obj/effect/blob/newB = B.expand() if(newB) newB.health = original_health - damage newB.check_health(cause) @@ -91,7 +88,8 @@ return ..() /datum/reagent/blob/replicating_foam/expand_reaction(obj/effect/blob/B, obj/effect/blob/newB, turf/T) - newB.expand() //do it again! + if(prob(50)) + newB.expand() //do it again! //does low burn and a lot of stamina damage, reacts to stamina damage /datum/reagent/blob/energized_fibers @@ -103,10 +101,9 @@ blobbernaut_message = "shocks" message_living = ", and you feel a strong tingling sensation" -/datum/reagent/blob/energized_fibers/reaction_mob(mob/living/M, method=TOUCH, reac_volume) +/datum/reagent/blob/energized_fibers/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O) reac_volume = ..() - if(M) - M.apply_damage(0.5*reac_volume, BURN) + M.apply_damage(0.5*reac_volume, BURN) if(M) M.adjustStaminaLoss(0.8*reac_volume) @@ -120,13 +117,13 @@ /datum/reagent/blob/boiling_oil name = "Boiling Oil" id = "boiling_oil" - description = "will cause medium burn damage and set targets on fire." + description = "will do medium burn damage and set targets on fire." color = "#B68D00" blobbernaut_message = "splashes" message = "The blob splashes you with burning oil" message_living = ", and you feel your skin char and melt" -/datum/reagent/blob/boiling_oil/reaction_mob(mob/living/M, method=TOUCH, reac_volume) +/datum/reagent/blob/boiling_oil/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O) reac_volume = ..() M.adjust_fire_stacks(round(reac_volume/12)) M.IgniteMob() @@ -135,25 +132,69 @@ if(iscarbon(M)) M.emote("scream") +/datum/reagent/blob/regenerative_materia + name = "Regenerative Materia" + id = "regenerative_materia" + description = "will do low toxin damage and cause targets to believe they are fully healed." + color = "#C8A5DC" + message_living = ", and you feel alive" + +/datum/reagent/blob/regenerative_materia/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O) + reac_volume = ..() + if(M.reagents) + M.reagents.add_reagent("regenerative_materia", 0.2*reac_volume) + M.apply_damage(0.6*reac_volume, TOX) + +/datum/reagent/blob/regenerative_materia/on_mob_life(mob/living/M) + M.adjustToxLoss(1*REM) + if(iscarbon(M)) + var/mob/living/carbon/N = M + N.hal_screwyhud = 5 //fully healed, honest + ..() + +/datum/reagent/blob/regenerative_materia/on_mob_delete(mob/living/M) + if(iscarbon(M)) + var/mob/living/carbon/N = M + N.hal_screwyhud = 0 + ..() + //toxin, hallucination, and some bonus spore toxin /datum/reagent/blob/hallucinogenic_nectar name = "Hallucinogenic Nectar" id = "hallucinogenic_nectar" - description = "will cause low toxin damage, vivid hallucinations, and inject targets with toxins." + description = "will do low toxin damage, vivid hallucinations, and inject targets with toxins." color = "#CD7794" blobbernaut_message = "splashes" message = "The blob splashes you with sticky nectar" message_living = ", and you feel really good" -/datum/reagent/blob/hallucinogenic_nectar/reaction_mob(mob/living/M, method=TOUCH, reac_volume) +/datum/reagent/blob/hallucinogenic_nectar/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O) reac_volume = ..() M.hallucination += 0.8*reac_volume M.adjust_drugginess(0.8*reac_volume) if(M.reagents) M.reagents.add_reagent("spore", 0.2*reac_volume) - if(M) - M.apply_damage(0.6*reac_volume, TOX) + M.apply_damage(0.6*reac_volume, TOX) + +//kills sleeping targets and turns them into blob zombies +/datum/reagent/blob/zombifying_feelers + name = "Zombifying Feelers" + id = "zombifying_feelers" + description = "will cause medium toxin damage and turn sleeping targets into blob zombies." + color = "#828264" + message_living = ", and you feel tired" + +/datum/reagent/blob/zombifying_feelers/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O) + reac_volume = ..() + M.apply_damage(0.6*reac_volume, TOX) + if(O && ishuman(M) && M.stat == UNCONSCIOUS) + M.death() //sleeping in a fight? bad plan. + var/mob/living/simple_animal/hostile/blob/blobspore/BS = new/mob/living/simple_animal/hostile/blob/blobspore/weak(get_turf(M)) + BS.overmind = O + BS.update_icons() + O.blob_mobs.Add(BS) + BS.Zombify(M) //toxin, stamina, and some bonus spore toxin /datum/reagent/blob/envenomed_filaments @@ -163,15 +204,29 @@ color = "#9ACD32" message_living = ", and you feel sick and nauseated" -/datum/reagent/blob/envenomed_filaments/reaction_mob(mob/living/M, method=TOUCH, reac_volume) +/datum/reagent/blob/envenomed_filaments/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O) reac_volume = ..() if(M.reagents) M.reagents.add_reagent("spore", 0.2*reac_volume) - if(M) - M.apply_damage(0.6*reac_volume, TOX) + M.apply_damage(0.6*reac_volume, TOX) if(M) M.adjustStaminaLoss(0.4*reac_volume) +//does oxygen damage, randomly pushes or pulls targets +/datum/reagent/blob/cyclonic_grid + name = "Cyclonic Grid" + id = "cyclonic_grid" + description = "will cause high oxygen damage and randomly throw targets to or from it." + color = "#9BCD9B" + message = "The blob blasts you with a gust of air" + message_living = ", and you can't catch your breath" + +/datum/reagent/blob/cyclonic_grid/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O) + reac_volume = ..() + reagent_vortex(M, rand(0, 1), reac_volume) + M.losebreath += round(0.05*reac_volume) + M.apply_damage(0.6*reac_volume, OXY) + //does tons of oxygen damage and a little brute /datum/reagent/blob/lexorin_jelly name = "Lexorin Jelly" @@ -180,32 +235,62 @@ color = "#00E5B1" message_living = ", and your lungs feel heavy and weak" -/datum/reagent/blob/lexorin_jelly/reaction_mob(mob/living/M, method=TOUCH, reac_volume) +/datum/reagent/blob/lexorin_jelly/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O) reac_volume = ..() M.losebreath += round(0.2*reac_volume) - if(M) - M.apply_damage(0.2*reac_volume, BRUTE) + M.apply_damage(0.2*reac_volume, BRUTE) if(M) M.apply_damage(0.6*reac_volume, OXY) +//does aoe brute damage when hitting targets, is immune to explosions +/datum/reagent/blob/explosive_lattice + name = "Explosive Lattice" + id = "explosive_lattice" + description = "will do brute damage in an area around targets and is resistant to explosions." + shortdesc = "will do brute damage in an area around targets." + color = "#8B2500" + blobbernaut_message = "blasts" + message = "The blob blasts you" + +/datum/reagent/blob/explosive_lattice/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O) + if(reac_volume >= 15) //if it's not a spore cloud, bad time incoming + reac_volume = ..() + var/obj/effect/overlay/temp/explosion/E = PoolOrNew(/obj/effect/overlay/temp/explosion, get_turf(M)) + E.alpha = 150 + for(var/mob/living/L in range(M, 1)) + if("blob" in L.faction) //no friendly fire + continue + L.apply_damage(0.6*reac_volume, BRUTE) + if(M) + M.apply_damage(0.1*reac_volume, BRUTE) + else + reac_volume = ..() + M.apply_damage(0.8*reac_volume, BRUTE) + +/datum/reagent/blob/explosive_lattice/damage_reaction(obj/effect/blob/B, original_health, damage, damage_type, cause) + if(isnull(cause) && damage_type == BRUTE) + return 0 //no-sell the explosion we do not take damage + return ..() + //does semi-random brute damage and reacts to brute damage -/datum/reagent/blob/reactive +/datum/reagent/blob/reactive_gelatin name = "Reactive Gelatin" id = "reactive_gelatin" description = "will do high brute damage and react to brute damage." + shortdesc = "will do high brute damage." color = "#FFA500" blobbernaut_message = "pummels" message = "The blob pummels you" -/datum/reagent/blob/reactive/reaction_mob(mob/living/M, method=TOUCH, reac_volume) +/datum/reagent/blob/reactive_gelatin/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O) reac_volume = ..() - var/damage = rand(10, 25)/25 - if(M) - M.apply_damage(damage*reac_volume, BRUTE) + var/damage = rand(10, 30)/25 + M.apply_damage(damage*reac_volume, BRUTE) -/datum/reagent/blob/reactive/damage_reaction(obj/effect/blob/B, original_health, damage, damage_type, cause) - if(damage && damage_type == BRUTE && original_health - damage > 0 && isliving(cause)) //is there any damage, is it brute, will we be alive, and is the cause a mob? - B.visible_message("The blob retaliates, lashing out!") +/datum/reagent/blob/reactive_gelatin/damage_reaction(obj/effect/blob/B, original_health, damage, damage_type, cause) + if(damage && damage_type == BRUTE && original_health - damage > 0) //is there any damage, is it brute, and will we be alive + if(isliving(cause)) + B.visible_message("The blob retaliates, lashing out!") for(var/atom/A in range(1, B)) A.blob_act() return ..() @@ -220,13 +305,12 @@ message = "The blob splashes you with an icy liquid" message_living = ", and you feel cold and tired" -/datum/reagent/blob/cryogenic_liquid/reaction_mob(mob/living/M, method=TOUCH, reac_volume) +/datum/reagent/blob/cryogenic_liquid/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O) reac_volume = ..() if(M.reagents) M.reagents.add_reagent("frostoil", 0.4*reac_volume) M.reagents.add_reagent("ice", 0.4*reac_volume) - if(M) - M.apply_damage(0.6*reac_volume, BURN) + M.apply_damage(0.6*reac_volume, BURN) if(M) M.adjustStaminaLoss(0.4*reac_volume) @@ -235,12 +319,13 @@ name = "Electromagnetic Web" id = "electromagnetic_web" description = "will do low burn damage and EMP targets, but is somewhat fragile." + shortdesc = "will do low burn damage and EMP targets." color = "#83ECEC" blobbernaut_message = "lashes" message = "The blob lashes you" message_living = ", and you hear a faint buzzing" -/datum/reagent/blob/electromagnetic_web/reaction_mob(mob/living/M, method=TOUCH, reac_volume) +/datum/reagent/blob/electromagnetic_web/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O) reac_volume = ..() M.emp_act(2) if(M) @@ -263,17 +348,16 @@ blobbernaut_message = "synchronously strikes" message = "The blobs strike you" -/datum/reagent/blob/synchronous_mesh/reaction_mob(mob/living/M, method=TOUCH, reac_volume) +/datum/reagent/blob/synchronous_mesh/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O) reac_volume = ..() - if(M) - M.apply_damage(0.1*reac_volume, BRUTE) + M.apply_damage(0.1*reac_volume, BRUTE) if(M) for(var/obj/effect/blob/B in range(1, M)) //if the target is completely surrounded, this is 2.4*reac_volume bonus damage, total of 2.5*reac_volume if(M) - var/obj/effect/overlay/temp/blob/O = PoolOrNew(/obj/effect/overlay/temp/blob, B.loc) + var/obj/effect/overlay/temp/blob/OV = PoolOrNew(/obj/effect/overlay/temp/blob, B.loc) if(B.overmind) - O.color = B.overmind.blob_reagent_datum.color - O.do_attack_animation(M) //show them they're getting a bad time + OV.color = B.overmind.blob_reagent_datum.color + OV.do_attack_animation(M) //show them they're getting a bad time M.apply_damage(0.3*reac_volume, BRUTE) /datum/reagent/blob/synchronous_mesh/damage_reaction(obj/effect/blob/B, original_health, damage, damage_type, cause) @@ -289,6 +373,19 @@ else return damage * 1.25 +//does brute damage through armor(but not though bio resistance) +/datum/reagent/blob/penetrating_spines + name = "Penetrating Spines" + id = "penetrating_spines" + description = "will do medium brute damage through armor." + color = "#408B80" + blobbernaut_message = "stabs" + message = "The blob stabs you" + +/datum/reagent/blob/penetrating_spines/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O) + reac_volume = ..() + M.adjustBruteLoss(0.6*reac_volume) + //does low brute damage, oxygen damage, and stamina damage and wets tiles when damaged /datum/reagent/blob/pressurized_slime name = "Pressurized Slime" @@ -300,13 +397,12 @@ message = "The blob splashes into you" message_living = ", and you gasp for breath" -/datum/reagent/blob/pressurized_slime/reaction_mob(mob/living/M, method=TOUCH, reac_volume) +/datum/reagent/blob/pressurized_slime/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O) reac_volume = ..() var/turf/simulated/T = get_turf(M) if(istype(T, /turf/simulated) && prob(reac_volume)) T.MakeSlippery(TURF_WET_WATER) - if(M) - M.apply_damage(0.4*reac_volume, BRUTE) + M.apply_damage(0.4*reac_volume, BRUTE) if(M) M.apply_damage(0.4*reac_volume, OXY) if(M) @@ -333,11 +429,10 @@ color = "#61407E" message = "You feel a thrum as the blob strikes you, and everything flies at you" -/datum/reagent/blob/dark_matter/reaction_mob(mob/living/M, method=TOUCH, reac_volume) +/datum/reagent/blob/dark_matter/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O) reagent_vortex(M, 0, reac_volume) reac_volume = ..() - if(M) - M.apply_damage(0.4*reac_volume, BRUTE) + M.apply_damage(0.4*reac_volume, BRUTE) //does brute damage and throws or pushes nearby objects away from the target /datum/reagent/blob/b_sorium @@ -347,11 +442,10 @@ color = "#808000" message = "The blob slams into you and sends you flying" -/datum/reagent/blob/b_sorium/reaction_mob(mob/living/M, method=TOUCH, reac_volume) +/datum/reagent/blob/b_sorium/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O) reagent_vortex(M, 1, reac_volume) reac_volume = ..() - if(M) - M.apply_damage(0.5*reac_volume, BRUTE) + M.apply_damage(0.5*reac_volume, BRUTE) /datum/reagent/blob/proc/reagent_vortex(mob/living/M, setting_type, reac_volume) if(M) @@ -360,6 +454,10 @@ for(var/atom/movable/X in range(range_power,pull)) if(istype(X, /obj/effect)) continue + if(isliving(X)) + var/mob/living/L = X + if("blob" in L.faction) //no friendly throwpulling + continue if(!X.anchored) var/distance = get_dist(X, pull) var/moving_power = max(range_power - distance, 1) diff --git a/code/modules/reagents/reagent_dispenser.dm b/code/modules/reagents/reagent_dispenser.dm index 3640c593e44..4f5e2d5c42b 100644 --- a/code/modules/reagents/reagent_dispenser.dm +++ b/code/modules/reagents/reagent_dispenser.dm @@ -88,22 +88,26 @@ if(istype(Proj) && !Proj.nodamage && ((Proj.damage_type == BURN) || (Proj.damage_type == BRUTE))) message_admins("[key_name_admin(Proj.firer)] triggered a fueltank explosion.") log_game("[key_name(Proj.firer)] triggered a fueltank explosion.") - explosion(src.loc,-1,0,2, flame_range = 2) + boom() - -/obj/structure/reagent_dispensers/fueltank/blob_act() +/obj/structure/reagent_dispensers/fueltank/proc/boom() explosion(src.loc,0,1,5,7,10, flame_range = 5) - - -/obj/structure/reagent_dispensers/fueltank/ex_act() - explosion(src.loc,-1,0,2, flame_range = 2) if(src) qdel(src) +/obj/structure/reagent_dispensers/fueltank/blob_act() + boom() + + +/obj/structure/reagent_dispensers/fueltank/ex_act() + boom() /obj/structure/reagent_dispensers/fueltank/fire_act() - blob_act() //saving a few lines of copypasta + boom() +/obj/structure/reagent_dispensers/fueltank/tesla_act() + ..() //extend the zap + boom() /obj/structure/reagent_dispensers/peppertank name = "Pepper Spray Refiller" diff --git a/code/modules/research/designs/mecha_designs.dm b/code/modules/research/designs/mecha_designs.dm index ee0c7d2bc67..87b4d4c8dbd 100644 --- a/code/modules/research/designs/mecha_designs.dm +++ b/code/modules/research/designs/mecha_designs.dm @@ -403,7 +403,7 @@ id = "mech_sleeper" build_type = MECHFAB req_tech = list("biotech" = 2) - build_path = /obj/item/mecha_parts/mecha_equipment/sleeper + build_path = /obj/item/mecha_parts/mecha_equipment/medical/sleeper materials = list(MAT_METAL=5000,MAT_GLASS=10000) construction_time = 100 category = list("Exosuit Equipment") @@ -414,7 +414,18 @@ id = "mech_syringe_gun" build_type = MECHFAB req_tech = list("magnets" = 3,"biotech" = 3) - build_path = /obj/item/mecha_parts/mecha_equipment/syringe_gun + build_path = /obj/item/mecha_parts/mecha_equipment/medical/syringe_gun materials = list(MAT_METAL=3000,MAT_GLASS=2000) construction_time = 200 category = list("Exosuit Equipment") + +/datum/design/mech_medical_beamgun + name = "Exosuit Medical Equipment (Medical Beamgun)" + desc = "Equipment for medical exosuits. A mounted medical nanite projector which will treat patients with a focused beam." + id = "mech_medi_beam" + req_tech = list("combat" = 5, "materials" = 7, "powerstorage" = 7, "biotech" = 6) + build_type = MECHFAB + materials = list(MAT_METAL = 15000, MAT_GLASS = 8000, MAT_PLASMA = 3000, MAT_GOLD = 8000, MAT_DIAMOND = 2000) + construction_time = 250 + build_path = /obj/item/mecha_parts/mecha_equipment/medical/mechmedbeam + category = list("Exosuit Equipment") \ No newline at end of file diff --git a/code/modules/research/designs/medical_designs.dm b/code/modules/research/designs/medical_designs.dm index 1d8d95cae67..aaa5d9df810 100644 --- a/code/modules/research/designs/medical_designs.dm +++ b/code/modules/research/designs/medical_designs.dm @@ -37,18 +37,6 @@ build_path = /obj/item/device/mmi category = list("Misc","Medical Designs") -/datum/design/mmi_radio - name = "Radio-enabled Man-Machine Interface" - desc = "The Warrior's bland acronym, MMI, obscures the true horror of this monstrosity. This one comes with a built-in radio." - id = "mmi_radio" - req_tech = list("programming" = 2, "biotech" = 4) - build_type = PROTOLATHE | MECHFAB - materials = list(MAT_METAL = 1200, MAT_GLASS = 500) - construction_time = 75 - reliability = 74 - build_path = /obj/item/device/mmi/radio_enabled - category = list("Misc","Medical Designs") - /datum/design/posibrain name = "Positronic Brain" desc = "The latest in Artificial Intelligences." diff --git a/code/modules/research/rdconsole.dm b/code/modules/research/rdconsole.dm index b1c29467930..25f4074397e 100644 --- a/code/modules/research/rdconsole.dm +++ b/code/modules/research/rdconsole.dm @@ -232,6 +232,14 @@ proc/CallMaterialName(ID) else if(href_list["copy_design"]) //Copy design data from the research holder to the design disk. for(var/datum/design/D in files.known_designs) if(href_list["copy_design_ID"] == D.id) + var/autolathe_friendly = 1 + for(var/x in D.materials) + if( !(x in list(MAT_METAL, MAT_GLASS))) + autolathe_friendly = 0 + D.category -= "Imported" + if(D.build_type & (AUTOLATHE|PROTOLATHE|CRAFTLATHE)) // Specifically excludes circuit imprinter and mechfab + D.build_type = autolathe_friendly ? (D.build_type | AUTOLATHE) : D.build_type + D.category |= "Imported" d_disk.blueprint = D break screen = 1.4 diff --git a/code/controllers/subsystem/shuttles/assault_pod.dm b/code/modules/shuttle/assault_pod.dm similarity index 100% rename from code/controllers/subsystem/shuttles/assault_pod.dm rename to code/modules/shuttle/assault_pod.dm diff --git a/code/modules/shuttle/emergency.dm b/code/modules/shuttle/emergency.dm index f3da90aae59..0fe221d4f13 100644 --- a/code/modules/shuttle/emergency.dm +++ b/code/modules/shuttle/emergency.dm @@ -73,4 +73,267 @@ log_game("[key_name(user)] has emagged the emergency shuttle in ([x],[y],[z]) [time] seconds before launch.") minor_announce("The emergency shuttle will launch in 10 seconds", "SYSTEM ERROR:",null,1) SSshuttle.emergency.setTimer(100) - emagged = 1 \ No newline at end of file + emagged = 1 + +/obj/docking_port/mobile/emergency + name = "emergency shuttle" + id = "emergency" + + dwidth = 9 + width = 22 + height = 11 + dir = 4 + travelDir = -90 + roundstart_move = "emergency_away" + var/sound_played = 0 //If the launch sound has been sent to all players on the shuttle itself + +/obj/docking_port/mobile/emergency/New() + ..() + SSshuttle.emergency = src + +/obj/docking_port/mobile/emergency/timeLeft(divisor) + if(divisor <= 0) + divisor = 10 + if(!timer) + return round(SSshuttle.emergencyCallTime/divisor, 1) + + var/dtime = world.time - timer + switch(mode) + if(SHUTTLE_ESCAPE) + dtime = max(SSshuttle.emergencyEscapeTime - dtime, 0) + if(SHUTTLE_DOCKED) + dtime = max(SSshuttle.emergencyDockTime - dtime, 0) + else + dtime = max(SSshuttle.emergencyCallTime - dtime, 0) + return round(dtime/divisor, 1) + +/obj/docking_port/mobile/emergency/request(obj/docking_port/stationary/S, coefficient=1, area/signalOrigin, reason, redAlert) + SSshuttle.emergencyCallTime = initial(SSshuttle.emergencyCallTime) * coefficient + switch(mode) + if(SHUTTLE_RECALL) + mode = SHUTTLE_CALL + timer = world.time - timeLeft(1) + if(SHUTTLE_IDLE) + mode = SHUTTLE_CALL + timer = world.time + if(SHUTTLE_CALL) + if(world.time < timer) //this is just failsafe + timer = world.time + else + return + + if(prob(70)) + SSshuttle.emergencyLastCallLoc = signalOrigin + else + SSshuttle.emergencyLastCallLoc = null + + priority_announce("The emergency shuttle has been called. [redAlert ? "Red Alert state confirmed: Dispatching priority shuttle. " : "" ]It will arrive in [timeLeft(600)] minutes.[reason][SSshuttle.emergencyLastCallLoc ? "\n\nCall signal traced. Results can be viewed on any communications console." : "" ]", null, 'sound/AI/shuttlecalled.ogg', "Priority") + +/obj/docking_port/mobile/emergency/cancel(area/signalOrigin) + if(mode != SHUTTLE_CALL) + return + + timer = world.time - timeLeft(1) + mode = SHUTTLE_RECALL + + if(prob(70)) + SSshuttle.emergencyLastCallLoc = signalOrigin + else + SSshuttle.emergencyLastCallLoc = null + priority_announce("The emergency shuttle has been recalled.[SSshuttle.emergencyLastCallLoc ? " Recall signal traced. Results can be viewed on any communications console." : "" ]", null, 'sound/AI/shuttlerecalled.ogg', "Priority") + +/* +/obj/docking_port/mobile/emergency/findTransitDock() + . = SSshuttle.getDock("emergency_transit") + if(.) + return . + return ..() +*/ + + +/obj/docking_port/mobile/emergency/check() + if(!timer) + return + + var/time_left = timeLeft(1) + switch(mode) + if(SHUTTLE_RECALL) + if(time_left <= 0) + mode = SHUTTLE_IDLE + timer = 0 + if(SHUTTLE_CALL) + if(time_left <= 0) + //move emergency shuttle to station + if(dock(SSshuttle.getDock("emergency_home"))) + setTimer(20) + return + mode = SHUTTLE_DOCKED + timer = world.time + send2irc("Server", "The Emergency Shuttle has docked with the station.") + priority_announce("The Emergency Shuttle has docked with the station. You have [timeLeft(600)] minutes to board the Emergency Shuttle.", null, 'sound/AI/shuttledock.ogg', "Priority") + + //Gangs only have one attempt left if the shuttle has docked with the station to prevent suffering from dominator delays + for(var/datum/gang/G in ticker.mode.gangs) + if(isnum(G.dom_timer)) + G.dom_attempts = 0 + else + G.dom_attempts = min(1,G.dom_attempts) + + if(SHUTTLE_DOCKED) + + if(time_left <= 50 && !sound_played) //4 seconds left:REV UP THOSE ENGINES BOYS. - should sync up with the launch + sound_played = 1 //Only rev them up once. + for(var/area/shuttle/escape/E in world) + E << 'sound/effects/hyperspace_begin.ogg' + + if(time_left <= 0 && SSshuttle.emergencyNoEscape) + priority_announce("Hostile environment detected. Departure has been postponed indefinitely pending conflict resolution.", null, 'sound/misc/notice1.ogg', "Priority") + sound_played = 0 //Since we didn't launch, we will need to rev up the engines again next pass. + mode = SHUTTLE_STRANDED + + if(time_left <= 0 && !SSshuttle.emergencyNoEscape) + //move each escape pod (or applicable spaceship) to its corresponding transit dock + for(var/A in SSshuttle.mobile) + var/obj/docking_port/mobile/M = A + if(M.launch_status == UNLAUNCHED) //Pods will not launch from the mine/planet, and other ships won't launch unless we tell them to. + M.launch_status = ENDGAME_LAUNCHED + M.enterTransit() + + //now move the actual emergency shuttle to its transit dock + for(var/area/shuttle/escape/E in world) + E << 'sound/effects/hyperspace_progress.ogg' + enterTransit() + mode = SHUTTLE_ESCAPE + launch_status = ENDGAME_LAUNCHED + timer = world.time + priority_announce("The Emergency Shuttle has left the station. Estimate [timeLeft(600)] minutes until the shuttle docks at Central Command.", null, null, "Priority") + if(SHUTTLE_ESCAPE) + if(time_left <= 0) + //move each escape pod to its corresponding escape dock + for(var/A in SSshuttle.mobile) + var/obj/docking_port/mobile/M = A + if(M.launch_status == ENDGAME_LAUNCHED) + if(istype(M, /obj/docking_port/mobile/pod)) + M.dock(SSshuttle.getDock("[M.id]_away")) //Escape pods dock at centcomm + else + continue //Mapping a new docking point for each ship mappers could potentially want docking with centcomm would take up lots of space, just let them keep flying off into the sunset for their greentext + + //now move the actual emergency shuttle to centcomm + for(var/area/shuttle/escape/E in world) + E << 'sound/effects/hyperspace_end.ogg' + dock(SSshuttle.getDock("emergency_away")) + mode = SHUTTLE_ENDGAME + timer = 0 + open_dock() + +/obj/docking_port/mobile/emergency/proc/open_dock() + for(var/obj/machinery/door/poddoor/shuttledock/D in airlocks) + var/turf/T = get_step(D, D.checkdir) + if(!istype(T,/turf/space)) + spawn(0) + D.open() + +/obj/docking_port/mobile/pod + name = "escape pod" + id = "pod" + dwidth = 1 + width = 3 + height = 4 + launch_status = UNLAUNCHED + +/obj/docking_port/mobile/pod/request() + if((security_level == SEC_LEVEL_RED || security_level == SEC_LEVEL_DELTA) && launch_status == UNLAUNCHED) + launch_status = EARLY_LAUNCHED + return ..() + +/obj/docking_port/mobile/pod/New() + if(id == "pod") + WARNING("[type] id has not been changed from the default. Use the id convention \"pod1\" \"pod2\" etc.") + ..() + +/obj/docking_port/mobile/pod/cancel() + return + +/obj/machinery/computer/shuttle/pod + name = "pod control computer" + admin_controlled = 1 + shuttleId = "pod" + possible_destinations = "pod_asteroid" + icon = 'icons/obj/terminals.dmi' + icon_state = "dorm_available" + density = 0 + +/obj/machinery/computer/shuttle/pod/update_icon() + return + +/obj/docking_port/stationary/random + name = "escape pod" + id = "pod" + dwidth = 1 + width = 3 + height = 4 + var/target_area = /area/mine/unexplored + +/obj/docking_port/stationary/random/initialize() + ..() + var/list/turfs = get_area_turfs(target_area) + var/turf/T = pick(turfs) + src.loc = T + +//Pod suits/pickaxes + + +/obj/item/clothing/head/helmet/space/orange + name = "emergency space helmet" + icon_state = "syndicate-helm-orange" + item_state = "syndicate-helm-orange" + +/obj/item/clothing/suit/space/orange + name = "emergency space suit" + icon_state = "syndicate-orange" + item_state = "syndicate-orange" + slowdown = 3 + +/obj/item/weapon/pickaxe/emergency + name = "emergency disembarkation tool" + desc = "For extracting yourself from rough landings." + +/obj/item/weapon/storage/pod + name = "emergency space suits" + desc = "A wall mounted safe containing space suits. Will only open in emergencies." + anchored = 1 + density = 0 + icon = 'icons/obj/storage.dmi' + icon_state = "safe" + +/obj/item/weapon/storage/pod/New() + ..() + new /obj/item/clothing/head/helmet/space/orange(src) + new /obj/item/clothing/head/helmet/space/orange(src) + new /obj/item/clothing/suit/space/orange(src) + new /obj/item/clothing/suit/space/orange(src) + new /obj/item/clothing/mask/gas(src) + new /obj/item/clothing/mask/gas(src) + new /obj/item/weapon/tank/internals/oxygen/red(src) + new /obj/item/weapon/tank/internals/oxygen/red(src) + new /obj/item/weapon/pickaxe/emergency(src) + new /obj/item/weapon/pickaxe/emergency(src) + new /obj/item/weapon/survivalcapsule(src) + +/obj/item/weapon/storage/pod/attackby(obj/item/weapon/W, mob/user, params) + return + +/obj/item/weapon/storage/pod/MouseDrop(over_object, src_location, over_location) + if(security_level == SEC_LEVEL_RED || security_level == SEC_LEVEL_DELTA) + return ..() + else + usr << "The storage unit will only unlock during a Red or Delta security alert." + +/obj/item/weapon/storage/pod/attack_hand(mob/user) + return + + + +#undef UNLAUNCHED +#undef LAUNCHED +#undef EARLY_LAUNCHED diff --git a/code/controllers/subsystem/shuttles/supply.dm b/code/modules/shuttle/supply.dm similarity index 69% rename from code/controllers/subsystem/shuttles/supply.dm rename to code/modules/shuttle/supply.dm index 8cd24bf8ac8..4b3bc532578 100644 --- a/code/controllers/subsystem/shuttles/supply.dm +++ b/code/modules/shuttle/supply.dm @@ -1,9 +1,3 @@ -/obj/item/weapon/paper/manifest - name = "supply manifest" - var/erroneous = 0 - var/points = 0 - var/ordernumber = 0 - /obj/docking_port/mobile/supply name = "supply shuttle" id = "supply" @@ -65,93 +59,97 @@ if(!SSshuttle.shoppinglist.len) return - var/list/emptyTurfs = list() + var/list/empty_turfs = list() for(var/turf/simulated/floor/T in areaInstance) if(T.density || T.contents.len) continue - emptyTurfs += T + empty_turfs += T + var/value = 0 + var/purchases = 0 for(var/datum/supply_order/SO in SSshuttle.shoppinglist) - if(!SO.object) - continue - if(SO.object.cost > SSshuttle.points) + if(!empty_turfs.len) + break + if(SO.pack.cost > SSshuttle.points) continue - var/errors = 0 - if(prob(5)) - errors |= MANIFEST_ERROR_COUNT - if(prob(5)) - errors |= MANIFEST_ERROR_NAME - if(prob(5)) - errors |= MANIFEST_ERROR_ITEM - - var/turf/T = pick_n_take(emptyTurfs) - SO.createObject(T, errors) - - SSshuttle.points -= SO.object.cost + SSshuttle.points -= SO.pack.cost + value += SO.pack.cost SSshuttle.shoppinglist -= SO + SSshuttle.orderhistory += SO + + SO.generate(pick_n_take(empty_turfs)) + investigate_log("Order #[SO.id] ([SO.pack.name], placed by [key_name(SO.orderer_ckey)]) has shipped.", "cargo") + if(SO.pack.dangerous) + message_admins("\A [SO.pack.name] ordered by [key_name_admin(SO.orderer_ckey)] has shipped.") + purchases++ + + investigate_log("[purchases] orders in this shipment, worth [value] points. [SSshuttle.points] points left.", "cargo") /obj/docking_port/mobile/supply/proc/sell() + var/presale_points = SSshuttle.points + + var/pointsEarned = 0 var/crates = 0 var/plasma = 0 var/intel = 0 var/msg = "" - var/pointsEarned = 0 + var/sold_atoms = "" for(var/atom/movable/AM in areaInstance) if(AM.anchored) continue - SSshuttle.sold_atoms += " [AM.name]" + sold_atoms += " [AM.name]" - if(istype(AM, /obj/structure/closet/crate) || istype(AM, /obj/structure/closet/critter)) + if(istype(AM, /obj/structure/closet/crate)) crates++ - SSshuttle.sold_atoms += ":" + sold_atoms += ":" if(!AM.contents.len) - SSshuttle.sold_atoms += " (empty)" + sold_atoms += " (empty)." else - var/slip_found = FALSE + var/manifest_found = FALSE for(var/atom/movable/thing in AM) - SSshuttle.sold_atoms += " [thing.name]" - if(!slip_found && istype(thing, /obj/item/weapon/paper/manifest)) - var/obj/item/weapon/paper/manifest/slip = thing - if(slip.stamped && slip.stamped.len) - slip_found = TRUE + sold_atoms += " [thing.name]," + if(!manifest_found && istype(thing, /obj/item/weapon/paper/manifest)) + var/obj/item/weapon/paper/manifest/manifest = thing + if(manifest.stamped && manifest.stamped.len) + manifest_found = TRUE var/denied = FALSE - for(var/stamp in slip.stamped) + for(var/stamp in manifest.stamped) if(stamp == /obj/item/weapon/stamp/denied) denied = TRUE break - if(slip.erroneous && denied) // Caught a mistake by Centcom. - pointsEarned = slip.points - SSshuttle.points_per_crate + if(manifest.errors && denied) // Caught a mistake by Centcom. + pointsEarned = manifest.order_cost - SSshuttle.points_per_crate SSshuttle.points += pointsEarned // Give a full refund (minus the crate). - msg += "[pointsEarned]: Station correctly denied package [slip.ordernumber]: " - if(slip.erroneous & MANIFEST_ERROR_NAME) + msg += "+[pointsEarned]: Station correctly denied package #[manifest.order_id]: " + if(manifest.errors & MANIFEST_ERROR_NAME) msg += "Destination station incorrect. " - else if(slip.erroneous & MANIFEST_ERROR_COUNT) - msg += "Packages incorrectly counted. " - else if(slip.erroneous & MANIFEST_ERROR_ITEM) + else if(manifest.errors & MANIFEST_ERROR_CONTENTS) + msg += "Contents incorrectly counted. " + else if(manifest.errors & MANIFEST_ERROR_ITEM) msg += "Package incomplete. " msg += "Points refunded." - else if(!slip.erroneous && !denied) // Approved a slip correctly. - pointsEarned = SSshuttle.points_per_slip + else if(!manifest.errors && !denied) // Approved a manifest correctly. + pointsEarned = SSshuttle.points_per_manifest SSshuttle.points += pointsEarned - msg += "+[pointsEarned]: Package [slip.ordernumber] accorded." - else if(slip.erroneous) // You done goofed. - pointsEarned = -SSshuttle.points_per_slip + msg += "+[pointsEarned]: Package [manifest.order_id] accorded." + else if(manifest.errors) // You done goofed. + pointsEarned = -SSshuttle.points_per_manifest SSshuttle.points += pointsEarned - msg += "[pointsEarned]: Station erroneously approved package [slip.ordernumber]: " - if(slip.erroneous & MANIFEST_ERROR_NAME) + msg += "[pointsEarned]: Station erroneously approved package #[manifest.order_id]: " + if(manifest.errors & MANIFEST_ERROR_NAME) msg += "Destination station incorrect." - else if(slip.erroneous & MANIFEST_ERROR_COUNT) - msg += "Packages incorrectly counted." - else if(slip.erroneous & MANIFEST_ERROR_ITEM) + else if(manifest.errors & MANIFEST_ERROR_CONTENTS) + msg += "Contents incorrectly counted. " + else if(manifest.errors & MANIFEST_ERROR_ITEM) msg += "We found unshipped items on our dock." msg += " Be more vigilant." else - pointsEarned = round(SSshuttle.points_per_crate - slip.points) + pointsEarned = round(SSshuttle.points_per_crate - manifest.order_cost) SSshuttle.points += pointsEarned - msg += "[pointsEarned]: Station erroneously denied package [slip.ordernumber]." + msg += "[pointsEarned]: Station erroneously denied package #[manifest.order_id]." // Sell plasma if(istype(thing, /obj/item/stack/sheet/mineral/plasma)) @@ -209,7 +207,7 @@ SSshuttle.points += S.rarity // That's right, no bonus for potency. Send a crappy sample first to "show improvement" later qdel(thing) qdel(AM) - SSshuttle.sold_atoms += "." + sold_atoms += "." if(plasma > 0) pointsEarned = round(plasma * SSshuttle.points_per_plasma) @@ -227,3 +225,4 @@ SSshuttle.points += pointsEarned SSshuttle.centcom_message = msg + investigate_log("Shuttle contents sold for [SSshuttle.points - presale_points] points. Contents: [sold_atoms || "none."] Message: [SSshuttle.centcom_message || "none."]", "cargo") \ No newline at end of file diff --git a/code/modules/spells/spell_types/shapeshift.dm b/code/modules/spells/spell_types/shapeshift.dm index 68e3a07825a..b24b9c3bbad 100644 --- a/code/modules/spells/spell_types/shapeshift.dm +++ b/code/modules/spells/spell_types/shapeshift.dm @@ -1,6 +1,6 @@ /obj/effect/proc_holder/spell/targeted/shapeshift - name = "Shapeshift" - desc = "Change shapes" + name = "Shapechange" + desc = "Take on the shape of another for a time to use their natural abilities. Once you've made your choice it cannot be changed." clothes_req = 0 human_req = 0 charge_max = 200 @@ -11,12 +11,26 @@ invocation_type = "shout" action_icon_state = "shapeshift" - var/shapeshift_type = /mob/living/simple_animal/hostile/retaliate/goat + var/shapeshift_type var/list/current_shapes = list() var/list/current_casters = list() + var/list/possible_shapes = list(/mob/living/simple_animal/mouse,\ + /mob/living/simple_animal/pet/dog/corgi,\ + /mob/living/simple_animal/hostile/carp/ranged/chaos,\ + /mob/living/simple_animal/bot/ed209,\ + /mob/living/simple_animal/hostile/construct/armored) /obj/effect/proc_holder/spell/targeted/shapeshift/cast(list/targets,mob/user = usr) for(var/mob/living/M in targets) + if(!shapeshift_type) + var/list/animal_list = list() + for(var/path in possible_shapes) + var/mob/living/simple_animal/A = path + animal_list[initial(A.name)] = path + shapeshift_type = input(M, "Choose Your Animal Form!", "It's Morphing Time!", null) as anything in animal_list + if(!shapeshift_type) //If you aren't gonna decide I am! + shapeshift_type = pick(animal_list) + shapeshift_type = animal_list[shapeshift_type] if(M in current_shapes) Restore(M) else @@ -56,17 +70,4 @@ current_shapes.Remove(shape) shape.mind.transfer_to(caster) - qdel(shape) //Gib it maybe ? - -/obj/effect/proc_holder/spell/targeted/shapeshift/wild - name = "Wild Shapeshift" - desc = "Change into a variety of forms. Most of them deadly. Or inconspicious" - - var/list/possible_shapes = list(/mob/living/simple_animal/pet/dog/corgi,\ - /mob/living/simple_animal/hostile/poison/giant_spider/hunter,\ - /mob/living/simple_animal/hostile/carp/megacarp,\ - /mob/living/simple_animal/hostile/construct/armored) - -/obj/effect/proc_holder/spell/targeted/shapeshift/wild/New() - ..() - shapeshift_type = pick(possible_shapes) \ No newline at end of file + qdel(shape) //Gib it maybe ? \ No newline at end of file diff --git a/code/modules/surgery/dental_implant.dm b/code/modules/surgery/dental_implant.dm index 3f6cb539baf..189d37da341 100644 --- a/code/modules/surgery/dental_implant.dm +++ b/code/modules/surgery/dental_implant.dm @@ -28,7 +28,7 @@ return 1 /datum/action/item_action/hands_free/activate_pill - name = "activate pill" + name = "Activate Pill" /datum/action/item_action/hands_free/activate_pill/Trigger() if(!..() || CheckRemoval(owner)) diff --git a/code/modules/uplink/uplink_item.dm b/code/modules/uplink/uplink_item.dm index 1e61cda0a1c..90b3fb4f8b9 100644 --- a/code/modules/uplink/uplink_item.dm +++ b/code/modules/uplink/uplink_item.dm @@ -871,6 +871,12 @@ var/list/uplink_items = list() // Global list so we only initialize this once. item = /obj/item/weapon/c4 cost = 1 +/datum/uplink_item/device_tools/c4bag + name = "Bag of C-4 explosives" + desc = "Because sometimes quantity is quality. Contains 10 C-4 plastic explosives." + item = /obj/item/weapon/storage/backpack/dufflebag/syndie/c4 + cost = 9 //10% discount! + /datum/uplink_item/device_tools/powersink name = "Power Sink" desc = "When screwed to wiring attached to a power grid and activated, this large device places excessive \ diff --git a/html/changelog.html b/html/changelog.html index c7d4e78570a..61522966e02 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -55,6 +55,91 @@ -->
+

10 February 2016

+

Joan updated:

+
    +
  • Blob mobs now heal for 2.5% of their maxhealth when blob_act()ed, basically whenever they're on blobs near a node or the core.
  • +
  • Blob expansion no longer has a chance to fail inversely proportional with the expanding blob's health. Blobs still, however, expand at roughly the same rate as they do currently.
  • +
  • Adds five new blob chemicals.
  • +
  • Adds Penetrating Spines, which is sea green and does brute damage through armor. The damage can still be reduced by bio protection.
  • +
  • Adds Explosive Lattice, which is dark orange and does brute damage to all mobs near the target. Explosive Lattice is very resistant to explosions.
  • +
  • Adds Cyclonic Grid, which is a light blueish green and does oxygen damage, in addition to randomly throwing or pulling nearby objects.
  • +
  • Adds Zombifying Feelers, which is a fleshy zombie color and does toxin damage, in addition to killing and reviving unconscious humans as blob zombies.
  • +
  • Adds Regenerative Materia, which is light pink and does toxin damage, in addition to making the attacked mob think it is at full health.
  • +
  • Tweaks some of the existing blob chemicals slightly.
  • +
  • Sporing Pods can produce spores when killed by damage less than 21, from less than 20. This means lasers can produce spores.
  • +
  • Reactive Gelatin has a slightly higher maximum damage and will attack the nearby area when hit with brute damage projectiles, from just when attacked by brute damage in melee.
  • +
  • Sorium, Dark Matter, and the new Cyclonic Grid will not throw mobs with the 'blob' faction, such as blobbernauts and spores.
  • +
+

Kor updated:

+
    +
  • The chaplain can now transform the null rod into a holy weapon of his choice by using it in hand. Each one has different strengths and drawbacks.
  • +
+

MrStonedOne updated:

+
    +
  • Tesla balance changes
  • +
  • Tesla will now require increasingly more energy to trigger new orbiting balls. First ball comes with 32 energy (down from 300), fourth requires 256 (down from 1200), and so on and on, doubling with each new ball. Balls after 7 are increasingly harder to get than before, whereas balls before 6 are easier to get.
  • +
  • MULTIBOLT IS BACK!
  • +
  • Be warned that in multibolt all but 1 primary bolt now have a random shocking range, meaning they may still target a close human over a far away grounding rod as the rod may be out of range.
  • +
  • Power output of tesla massively dropped, it should no longer put out almost twice the power of a stage 3 singulo with maxed collectors without any balls, you'll need at least 3 balls for that now.
  • +
  • Tesla can now lose power, causing ball count to drop. Tesla will never shrink out of existence, just lose its balls.
  • +
  • Tesla is now more likely to head in the direction of the thing it last zapped.
  • +
+

PKPenguin321 updated:

+
    +
  • Chameleon Jumpsuits now have slight melee, bullet, and laser protection.
  • +
  • The armor values for security helmets, caps, and berets have all been brought in line. Consequently, helmets and berets are a teeny bit better, and caps now have the slight bomb protection that the other two had.
  • +
+

neersighted updated:

+
    +
  • Horizontal (lying) mobs now fit into crates
  • +
  • Mobs may now be stuffed into crates, as with lockers
  • +
  • Stuffing into a locker deals a mild stun (the same as tabling)
  • +
+ +

09 February 2016

+

AnturK updated:

+
    +
  • Syndicate Operatives can now buy bags full of plastic explosives for 9 TC.
  • +
+

Gun Hog updated:

+
    +
  • "Nanotrasen has drafted a design for an exosuit version of the medical nanite projector normally issued to its Emergency Response Personnel. With sufficient research, a prototype may be fabricated for field testing!"
  • +
+

incoming5643 updated:

+
    +
  • The wizard spell wild shapeshift has been made less terrible.
  • +
+

neersighted updated:

+
    +
  • Internals tanks now provide an action button
  • +
  • Jetpacks now emit the gas consumed for propulsion onto their turf
  • +
  • Jetpacks no longer have object verbs
  • +
  • tgui no longer has internals buttons
  • +
  • Malf AI's flood ability now correctly sets vent pressure bounds -- the results are devastating... Try it!
  • +
+ +

08 February 2016

+

Incoming5643 updated:

+
    +
  • Poly will now speak a line or emote when pet.
  • +
  • Poly now responds to getting fed crackers by becoming more annoying for the round.
  • +
  • Every day he is growing stronger
  • +
+

Kor updated:

+
    +
  • A certain hygiene obsessed alien is now obtainable via xenobiology gold cores.
  • +
  • Add laserguns with swappable, rechargeable magazines. They are adminspawn only.
  • +
  • Operatives now get their pinpointers in their pocket when they spawn, meaning reinforcements automatically come with them (and hopefully people stop forgetting them in general).
  • +
  • Capture the flag now features a high speed instagib mode, with guns courtesy of MMMiracles.
  • +
+

phil235 updated:

+
    +
  • The vision updates for mobs are now instantaneous (e.g. you don't have to wait one second to see again when removing your welding helmet)
  • +
  • Your vision is now affected when you're inside something or viewing through a camera. You can no longer see mobs or objects when ventcrawling (unless you have xray for example), an xray user viewing through a camera do not see through walls around the camera. On the other hand, cameras with an xray upgrade let you see through walls. Unfocused camera now give you the same effect as when you are nearsighted. Being inside closets, morgue container and disposal bins give you some vision impairments.
  • +
  • The ability to toggle your hud on and off (with f12) is now available to all mobs not just humans.
  • +
+

06 February 2016

LordPidey updated:

    diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml index 5f6816a3461..5d691cab719 100644 --- a/html/changelogs/.all_changelog.yml +++ b/html/changelogs/.all_changelog.yml @@ -3433,3 +3433,104 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py. useful to someone. - rscadd: Cargo consoles have been redesigned and now feature search and a shopping cart! +2016-02-08: + Incoming5643: + - rscadd: Poly will now speak a line or emote when pet. + - rscadd: Poly now responds to getting fed crackers by becoming more annoying for + the round. + - experiment: Every day he is growing stronger + Kor: + - rscadd: A certain hygiene obsessed alien is now obtainable via xenobiology gold + cores. + - rscadd: Add laserguns with swappable, rechargeable magazines. They are adminspawn + only. + - rscadd: Operatives now get their pinpointers in their pocket when they spawn, + meaning reinforcements automatically come with them (and hopefully people stop + forgetting them in general). + - rscadd: Capture the flag now features a high speed instagib mode, with guns courtesy + of MMMiracles. + phil235: + - tweak: The vision updates for mobs are now instantaneous (e.g. you don't have + to wait one second to see again when removing your welding helmet) + - tweak: Your vision is now affected when you're inside something or viewing through + a camera. You can no longer see mobs or objects when ventcrawling (unless you + have xray for example), an xray user viewing through a camera do not see through + walls around the camera. On the other hand, cameras with an xray upgrade let + you see through walls. Unfocused camera now give you the same effect as when + you are nearsighted. Being inside closets, morgue container and disposal bins + give you some vision impairments. + - rscadd: The ability to toggle your hud on and off (with f12) is now available + to all mobs not just humans. +2016-02-09: + AnturK: + - rscadd: Syndicate Operatives can now buy bags full of plastic explosives for 9 + TC. + Gun Hog: + - rscadd: '"Nanotrasen has drafted a design for an exosuit version of the medical + nanite projector normally issued to its Emergency Response Personnel. With sufficient + research, a prototype may be fabricated for field testing!"' + incoming5643: + - rscadd: The wizard spell wild shapeshift has been made less terrible. + neersighted: + - rscadd: Internals tanks now provide an action button + - rscadd: Jetpacks now emit the gas consumed for propulsion onto their turf + - rscdel: Jetpacks no longer have object verbs + - rscdel: tgui no longer has internals buttons + - bugfix: Malf AI's flood ability now correctly sets vent pressure bounds -- the + results are devastating... Try it! +2016-02-10: + Joan: + - rscadd: Blob mobs now heal for 2.5% of their maxhealth when blob_act()ed, basically + whenever they're on blobs near a node or the core. + - tweak: Blob expansion no longer has a chance to fail inversely proportional with + the expanding blob's health. Blobs still, however, expand at roughly the same + rate as they do currently. + - experiment: Adds five new blob chemicals. + - rscadd: Adds Penetrating Spines, which is sea green and does brute damage through + armor. The damage can still be reduced by bio protection. + - rscadd: Adds Explosive Lattice, which is dark orange and does brute damage to + all mobs near the target. Explosive Lattice is very resistant to explosions. + - rscadd: Adds Cyclonic Grid, which is a light blueish green and does oxygen damage, + in addition to randomly throwing or pulling nearby objects. + - rscadd: Adds Zombifying Feelers, which is a fleshy zombie color and does toxin + damage, in addition to killing and reviving unconscious humans as blob zombies. + - rscadd: Adds Regenerative Materia, which is light pink and does toxin damage, + in addition to making the attacked mob think it is at full health. + - wip: Tweaks some of the existing blob chemicals slightly. + - rscadd: Sporing Pods can produce spores when killed by damage less than 21, from + less than 20. This means lasers can produce spores. + - rscadd: Reactive Gelatin has a slightly higher maximum damage and will attack + the nearby area when hit with brute damage projectiles, from just when attacked + by brute damage in melee. + - tweak: Sorium, Dark Matter, and the new Cyclonic Grid will not throw mobs with + the 'blob' faction, such as blobbernauts and spores. + Kor: + - rscadd: The chaplain can now transform the null rod into a holy weapon of his + choice by using it in hand. Each one has different strengths and drawbacks. + MrStonedOne: + - tweak: Tesla balance changes + - tweak: Tesla will now require increasingly more energy to trigger new orbiting + balls. First ball comes with 32 energy (down from 300), fourth requires 256 + (down from 1200), and so on and on, doubling with each new ball. Balls after + 7 are increasingly harder to get than before, whereas balls before 6 are easier + to get. + - rscadd: MULTIBOLT IS BACK! + - tweak: Be warned that in multibolt all but 1 primary bolt now have a random shocking + range, meaning they may still target a close human over a far away grounding + rod as the rod may be out of range. + - tweak: Power output of tesla massively dropped, it should no longer put out almost + twice the power of a stage 3 singulo with maxed collectors without any balls, + you'll need at least 3 balls for that now. + - tweak: Tesla can now lose power, causing ball count to drop. Tesla will never + shrink out of existence, just lose its balls. + - tweak: Tesla is now more likely to head in the direction of the thing it last + zapped. + PKPenguin321: + - rscadd: Chameleon Jumpsuits now have slight melee, bullet, and laser protection. + - tweak: The armor values for security helmets, caps, and berets have all been brought + in line. Consequently, helmets and berets are a teeny bit better, and caps now + have the slight bomb protection that the other two had. + neersighted: + - rscadd: Horizontal (lying) mobs now fit into crates + - rscadd: Mobs may now be stuffed into crates, as with lockers + - rscadd: Stuffing into a locker deals a mild stun (the same as tabling) diff --git a/html/changelogs/AutoChangeLog-pr-14992.yml b/html/changelogs/AutoChangeLog-pr-14992.yml deleted file mode 100644 index 7adeb9e3d07..00000000000 --- a/html/changelogs/AutoChangeLog-pr-14992.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: Kor -delete-after: True -changes: - - rscadd: "Add laserguns with swappable, rechargeable magazines. They are adminspawn only." diff --git a/html/changelogs/AutoChangeLog-pr-15177.yml b/html/changelogs/AutoChangeLog-pr-15177.yml deleted file mode 100644 index 2c35b9472b0..00000000000 --- a/html/changelogs/AutoChangeLog-pr-15177.yml +++ /dev/null @@ -1,6 +0,0 @@ -author: phil235 -delete-after: True -changes: - - tweak: "The vision updates for mobs are now instantaneous (e.g. you don't have to wait one second to see again when removing your welding helmet)" - - tweak: "Your vision is now affected when you're inside something or viewing through a camera. You can no longer see mobs or objects when ventcrawling (unless you have xray for example), an xray user viewing through a camera do not see through walls around the camera. On the other hand, cameras with an xray upgrade let you see through walls. Unfocused camera now give you the same effect as when you are nearsighted. Being inside closets, morgue container and disposal bins give you some vision impairments." - - rscadd: "The ability to toggle your hud on and off (with f12) is now available to all mobs not just humans." diff --git a/html/changelogs/AutoChangeLog-pr-15183.yml b/html/changelogs/AutoChangeLog-pr-15183.yml deleted file mode 100644 index a2116a8a37e..00000000000 --- a/html/changelogs/AutoChangeLog-pr-15183.yml +++ /dev/null @@ -1,6 +0,0 @@ -author: Incoming5643 -delete-after: True -changes: - - rscadd: "Poly will now speak a line or emote when pet." - - rscadd: "Poly now responds to getting fed crackers by becoming more annoying for the round." - - experiment: "Every day he is growing stronger" diff --git a/html/changelogs/AutoChangeLog-pr-15208.yml b/html/changelogs/AutoChangeLog-pr-15208.yml deleted file mode 100644 index 2ee2d97157b..00000000000 --- a/html/changelogs/AutoChangeLog-pr-15208.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: Kor -delete-after: True -changes: - - rscadd: "Operatives now get their pinpointers in their pocket when they spawn, meaning reinforcements automatically come with them (and hopefully people stop forgetting them in general)." diff --git a/html/changelogs/AutoChangeLog-pr-15254.yml b/html/changelogs/AutoChangeLog-pr-15254.yml new file mode 100644 index 00000000000..f782010a9bb --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-15254.yml @@ -0,0 +1,4 @@ +author: PKPenguin321 +delete-after: True +changes: + - experiment: "The time needed to complete most tablecrafting recipes has been cut in half to make tablecrafting less annoying to use." diff --git a/html/changelogs/AutoChangeLog-pr-15344.yml b/html/changelogs/AutoChangeLog-pr-15344.yml new file mode 100644 index 00000000000..b08c8d78458 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-15344.yml @@ -0,0 +1,5 @@ +author: Shadowlight213 +delete-after: True +changes: + - rscadd: "pAI controlled mulebots can now run people over." + - tweak: "Mulebot health has been greatly decreased." diff --git a/html/changelogs/AutoChangeLog-pr-15349.yml b/html/changelogs/AutoChangeLog-pr-15349.yml new file mode 100644 index 00000000000..69c4f25385b --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-15349.yml @@ -0,0 +1,4 @@ +author: octareenroon91 +delete-after: True +changes: + - rscadd: "New designs can now be added to Autolathes via a design disk. Simply use a disk containing a suitable design on your autolathe." diff --git a/icons/effects/beam.dmi b/icons/effects/beam.dmi index 2d880961426..39df6013a71 100644 Binary files a/icons/effects/beam.dmi and b/icons/effects/beam.dmi differ diff --git a/icons/mecha/mecha_equipment.dmi b/icons/mecha/mecha_equipment.dmi index 930d0685de4..525f80e2caf 100644 Binary files a/icons/mecha/mecha_equipment.dmi and b/icons/mecha/mecha_equipment.dmi differ diff --git a/icons/misc/buildmode.dmi b/icons/misc/buildmode.dmi index 089427111f2..649a7726569 100644 Binary files a/icons/misc/buildmode.dmi and b/icons/misc/buildmode.dmi differ diff --git a/icons/mob/alien.dmi b/icons/mob/alien.dmi index b082eb15418..b1433434c03 100644 Binary files a/icons/mob/alien.dmi and b/icons/mob/alien.dmi differ diff --git a/icons/mob/blob.dmi b/icons/mob/blob.dmi index 184337131ad..d2573aa3079 100644 Binary files a/icons/mob/blob.dmi and b/icons/mob/blob.dmi differ diff --git a/icons/mob/head.dmi b/icons/mob/head.dmi index e98422ae586..0af621dcc7c 100644 Binary files a/icons/mob/head.dmi and b/icons/mob/head.dmi differ diff --git a/icons/mob/hud.dmi b/icons/mob/hud.dmi index 50e9757cf3a..8e7724e96e1 100644 Binary files a/icons/mob/hud.dmi and b/icons/mob/hud.dmi differ diff --git a/icons/mob/inhands/items_lefthand.dmi b/icons/mob/inhands/items_lefthand.dmi index 92c0bf9069a..cc5d4e85bcc 100644 Binary files a/icons/mob/inhands/items_lefthand.dmi and b/icons/mob/inhands/items_lefthand.dmi differ diff --git a/icons/mob/inhands/items_righthand.dmi b/icons/mob/inhands/items_righthand.dmi index 1aea3038d1d..02e9868c180 100644 Binary files a/icons/mob/inhands/items_righthand.dmi and b/icons/mob/inhands/items_righthand.dmi differ diff --git a/icons/mob/pets.dmi b/icons/mob/pets.dmi index cc6355a0e84..aa3f457791a 100644 Binary files a/icons/mob/pets.dmi and b/icons/mob/pets.dmi differ diff --git a/icons/mob/suit.dmi b/icons/mob/suit.dmi index 5234f3ea193..792ce0544b0 100644 Binary files a/icons/mob/suit.dmi and b/icons/mob/suit.dmi differ diff --git a/icons/obj/closet.dmi b/icons/obj/closet.dmi index aa5a2366d17..58430a3543a 100644 Binary files a/icons/obj/closet.dmi and b/icons/obj/closet.dmi differ diff --git a/icons/obj/clothing/hats.dmi b/icons/obj/clothing/hats.dmi index cfc9ae1730c..6409d9fee56 100644 Binary files a/icons/obj/clothing/hats.dmi and b/icons/obj/clothing/hats.dmi differ diff --git a/icons/obj/clothing/suits.dmi b/icons/obj/clothing/suits.dmi index a15ca0d9c3b..328994d68b9 100644 Binary files a/icons/obj/clothing/suits.dmi and b/icons/obj/clothing/suits.dmi differ diff --git a/icons/obj/crates.dmi b/icons/obj/crates.dmi index 40b9e739d62..2f2180402a4 100644 Binary files a/icons/obj/crates.dmi and b/icons/obj/crates.dmi differ diff --git a/icons/obj/drinks.dmi b/icons/obj/drinks.dmi index fa7503791a9..5d3d7b77d88 100644 Binary files a/icons/obj/drinks.dmi and b/icons/obj/drinks.dmi differ diff --git a/icons/obj/machines/particle_accelerator.dmi b/icons/obj/machines/particle_accelerator.dmi index f092bd5a97b..e7636ad6a95 100644 Binary files a/icons/obj/machines/particle_accelerator.dmi and b/icons/obj/machines/particle_accelerator.dmi differ diff --git a/icons/obj/weapons.dmi b/icons/obj/weapons.dmi index 675da21434a..2f5140019b4 100644 Binary files a/icons/obj/weapons.dmi and b/icons/obj/weapons.dmi differ diff --git a/tgstation.dme b/tgstation.dme index 0d5e9e52b74..2fb7c791662 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -141,9 +141,6 @@ #include "code\controllers\subsystem\ticker.dm" #include "code\controllers\subsystem\timer.dm" #include "code\controllers\subsystem\voting.dm" -#include "code\controllers\subsystem\shuttles\assault_pod.dm" -#include "code\controllers\subsystem\shuttles\emergency.dm" -#include "code\controllers\subsystem\shuttles\supply.dm" #include "code\datums\ai_laws.dm" #include "code\datums\beam.dm" #include "code\datums\browser.dm" @@ -157,7 +154,6 @@ #include "code\datums\outfit.dm" #include "code\datums\progressbar.dm" #include "code\datums\recipe.dm" -#include "code\datums\supplypacks.dm" #include "code\datums\votablemap.dm" #include "code\datums\diseases\_disease.dm" #include "code\datums\diseases\_MobProcs.dm" @@ -601,6 +597,7 @@ #include "code\game\objects\items\weapons\flamethrower.dm" #include "code\game\objects\items\weapons\gift_wrappaper.dm" #include "code\game\objects\items\weapons\handcuffs.dm" +#include "code\game\objects\items\weapons\holy_weapons.dm" #include "code\game\objects\items\weapons\janisigns.dm" #include "code\game\objects\items\weapons\kitchen.dm" #include "code\game\objects\items\weapons\manuals.dm" @@ -708,12 +705,9 @@ #include "code\game\objects\structures\beds_chairs\alien_nest.dm" #include "code\game\objects\structures\beds_chairs\bed.dm" #include "code\game\objects\structures\beds_chairs\chair.dm" -#include "code\game\objects\structures\crates_lockers\bins.dm" #include "code\game\objects\structures\crates_lockers\closets.dm" #include "code\game\objects\structures\crates_lockers\crates.dm" -#include "code\game\objects\structures\crates_lockers\largecrate.dm" #include "code\game\objects\structures\crates_lockers\closets\cardboardbox.dm" -#include "code\game\objects\structures\crates_lockers\closets\crittercrate.dm" #include "code\game\objects\structures\crates_lockers\closets\fitness.dm" #include "code\game\objects\structures\crates_lockers\closets\gimmick.dm" #include "code\game\objects\structures\crates_lockers\closets\job_closets.dm" @@ -733,6 +727,10 @@ #include "code\game\objects\structures\crates_lockers\closets\secure\scientist.dm" #include "code\game\objects\structures\crates_lockers\closets\secure\secure_closets.dm" #include "code\game\objects\structures\crates_lockers\closets\secure\security.dm" +#include "code\game\objects\structures\crates_lockers\crates\bins.dm" +#include "code\game\objects\structures\crates_lockers\crates\critter.dm" +#include "code\game\objects\structures\crates_lockers\crates\large.dm" +#include "code\game\objects\structures\crates_lockers\crates\secure.dm" #include "code\game\objects\structures\transit_tubes\station.dm" #include "code\game\objects\structures\transit_tubes\transit_tube.dm" #include "code\game\objects\structures\transit_tubes\transit_tube_construction.dm" @@ -896,6 +894,7 @@ #include "code\modules\awaymissions\mission_code\wildwest.dm" #include "code\modules\cargo\console.dm" #include "code\modules\cargo\order.dm" +#include "code\modules\cargo\packs.dm" #include "code\modules\client\asset_cache.dm" #include "code\modules\client\client defines.dm" #include "code\modules\client\client procs.dm" @@ -1411,7 +1410,6 @@ #include "code\modules\power\singularity\particle_accelerator\particle_emitter.dm" #include "code\modules\power\singularity\particle_accelerator\particle_power.dm" #include "code\modules\power\supermatter\supermatter.dm" -#include "code\modules\power\supermatter\supermatter_crate.dm" #include "code\modules\power\tesla\coil.dm" #include "code\modules\power\tesla\energy_ball.dm" #include "code\modules\power\tesla\generator.dm" @@ -1535,10 +1533,12 @@ #include "code\modules\ruins\ruin_areas.dm" #include "code\modules\security levels\keycard authentication.dm" #include "code\modules\security levels\security levels.dm" +#include "code\modules\shuttle\assault_pod.dm" #include "code\modules\shuttle\computer.dm" #include "code\modules\shuttle\emergency.dm" #include "code\modules\shuttle\ferry.dm" #include "code\modules\shuttle\shuttle.dm" +#include "code\modules\shuttle\supply.dm" #include "code\modules\shuttle\syndicate.dm" #include "code\modules\shuttle\white_ship.dm" #include "code\modules\space transition\space_transition.dm" diff --git a/tgui/README.md b/tgui/README.md new file mode 100644 index 00000000000..109a1c45fc6 --- /dev/null +++ b/tgui/README.md @@ -0,0 +1,139 @@ + + +- [tgui](#tgui) + - [Concepts](#concepts) + - [Using It](#using-it) + - [Copypasta](#copypasta) + + + +# tgui +tgui is the user interface library of /tg/station. It is rendered clientside, based on JSON data sent from the server. Clicks are processed on the server, in a similar method to native BYOND `Topic()`. + +Basic tgui consists of defining a few procs. In these procs you will handle a request to open or update a UI (typically by updating a UI if it exists or setting up and opening it if it does not), a request for data, in which you build a list to be passed as JSON to the UI, and an action handler, which handles any user input. In addition, you will write a HTML template file which renders your data and provides actionable inputs. + +tgui is very different from most UIs you will encounter in BYOND programming, and is heavily reliant of Javascript and web technologies as opposed to DM. However, if you are familiar with NanoUI (a library which can be found on almost every other SS13 codebase), tgui should be fairly easy to pick up. + +tgui is a fork of NanoUI. The server-side code (DM) is similar and derived from NanoUI, while the clientside is a wholly new project with no code in common. + +## Concepts +tgui is loosely based a MVVM architecture. MVVM stands for model, view, view model. +- A model is the object that a UI represents. This is the atom a UI corresponds to in the game world in most cases, and is known as the `src_object` in tgui. +- The view model is how data is represented in terms of the view. In tgui, this is the `ui_data` proc which munges whatever complex data your `src_object` has into a list. +- The view is how the data is rendered. This is the template, a HTML (plus mustaches and other goodies) file which is compiled into the tgui blob that the browser executes. + +Not included in the MVVM model are other important concepts: +- The action/topic handler, `ui_act`, is what recieves input from the user and acts on it. +- The request/update proc, `ui_interact` is where you open your UI and set options like title, size, autoupdate, theme, and more. +- Finally, `ui_state`s (set in `ui_interact`) dictate under what conditions a UI may be interacted with. This may be the standard checks that check if you are in range and conscious, or more. + +States are easy to write and extend, and what make tgui interactions so powerful. Because states can over overridden from other procs, you can build powerful interactions for embedded objects or remote access. + +## Using It +All these examples and abstracts sound great, you might say. But you also might say, "How do I use it?" + +Examples can be as simple or as complex as you would like. Let's start with a very basic hello world. + +```DM +/obj/machinery/my_machine/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, datum/tgui/master_ui = null, datum/ui_state/state = default_state) + ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) + if(!ui) + ui = new(user, src, ui_key, "my_machine", name, 300, 300, master_ui, state) + ui.open() +``` + +This is the proc that defines our interface. There's a bit going on here, so let's break it down. First, we override the ui_interact proc on our object. This will be called by `interact` for you, which is in turn called by `attack_hand` (or `attack_self` for items). `ui_interact` is also called to update a UI (hence the `try_update_ui`), so we accept an existing UI to update. The `state` is a default argument so that a caller can overload it with named arguments (`ui_interact(state = overloaded_state)`) if needed. + +Inside the `if(!ui)` block (which means we are creating a new UI), we choose our template, title, and size; we can also set various options like `style` (for themes), or autoupdate. These options will be elaborated on later (as will `ui_state`s). + +After `ui_interact`, we need to define `ui_data`. This just returns a list of data for our object to use. Let's imagine our object has a few vars: + +```DM +/obj/machinery/my_machine/ui_data(mob/user) + var/list/data = list() + data["health"] = health + data["color"] = color + + return data +``` + +The `ui_data` proc is what people often find the hardest about tgui, but its really quite simple! You just need to represent your object as numbers, strings, and lists, instead of atoms and datums. + +Finally, the `ui_act` proc is called by the interface whenever the user used an input. The input's `action` and `params` are passed to the proc. + +```DM +/obj/machinery/my_machine/ui_act(action, params) + if(..()) + return + switch(action) + if("change_color") + var/new_color = params["color"] + if(!(color in allowed_coors)) + return + color = new_color + . = TRUE + update_icon() +``` + +The `..()` (parent call) is very important here, as it is how we check that the user is allowed to use this interface (to avoid so-called href exploits). It is also very important to clamp and sanitize all input here. Always assume the user is attempting to exploit the game. + +Also note the use of `. = TRUE` (or `FALSE`), which is used to notify the UI that this input caused an update. This is especially important for UIs that do not auto-update, as otherwise the user will never see their change. + +Finally, you have a template. This is also a source of confusion for many new users. Some basic HTML knowledge will get you a long way, however. + +A template is regular HTML, with mustache for logic and built-in components to quickly build UIs. Here's how we might show some data (components will be elaborated on later). + +In a template there are a few special values. `config` is always the same and is part of core tgui (it will be explained later), `data` is the data returned from `ui_data`, and `adata` is the same, but with certain values (numbers at this time) interpolated in order to allow animation. + +```html + + + {{data.health}} + + + {{data.color}} + + +``` + +Templates can be very confusing at first, as ternary operators, computed properties, and iterators are used quite a bit in more complex interfaces. Start with the basics, and work your way up. Much of the complexity stems from performance concerns. If in doubt, take the simpler approach and refactor if performance becomes an issue. + +## Copypasta +We all do it, even the best of us. If you just want to make a tgui **fast**, here's what you need (note that you'll probably be forced to clean your shit up upon code review): + +```DM +/obj/copypasta/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, datum/tgui/master_ui = null, datum/ui_state/state = default_state) // Remember to use the appropriate state. + ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) + if(!ui) + ui = new(user, src, ui_key, "copypasta", name, 300, 300, master_ui, state) + ui.open() + +/obj/copypasta/ui_data(mob/user) + var/list/data = list() + data["var"] = var + + return data + +/obj/copypasta/ui_act(action, params) + if(..()) + return + switch(action) + if("copypasta") + var/newvar = params["var"] + var = Clamp(newvar, min_val, max_val) // Just a demo of proper input sanitation. + . = TRUE + update_icon() // Not applicable to all objects. +``` + +And the template: + +```html + + + {{data.var}} + + + {{adata.var}} + + +``` diff --git a/tgui/assets/tgui.css b/tgui/assets/tgui.css index 89012c18514..ce30e93bf84 100644 --- a/tgui/assets/tgui.css +++ b/tgui/assets/tgui.css @@ -1 +1 @@ -body,html{box-sizing:border-box;height:100%;margin:0}html{overflow:hidden;cursor:default}body{overflow:auto;font-family:Verdana,Geneva,sans-serif;font-size:12px;color:#fff;background-color:#2a2a2a;background-image:linear-gradient(180deg,#2a2a2a 0,#202020);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff2a2a2a',endColorstr='#ff202020',GradientType=0)}*,:after,:before{box-sizing:inherit}h1,h2,h3,h4{display:inline-block;margin:0;padding:6px 0}h1{font-size:18px}h2{font-size:16px}h3{font-size:14px}h4{font-size:12px}.wf-inactive .titlebar .minimize:after{content:"-"}.wf-inactive .titlebar .close:after{content:"X"}body.nanotrasen{background:url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+DQo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmVyc2lvbj0iMS4wIiB2aWV3Qm94PSIwIDAgNDI1IDIwMCIgb3BhY2l0eT0iLjMzIj4NCiAgPHBhdGggZD0ibSAxNzguMDAzOTksMC4wMzg2OSAtNzEuMjAzOTMsMCBhIDYuNzYxMzQyMiw2LjAyNTU0OTUgMCAwIDAgLTYuNzYxMzQsNi4wMjU1NSBsIDAsMTg3Ljg3MTQ3IGEgNi43NjEzNDIyLDYuMDI1NTQ5NSAwIDAgMCA2Ljc2MTM0LDYuMDI1NTQgbCA1My4xMDcyLDAgYSA2Ljc2MTM0MjIsNi4wMjU1NDk1IDAgMCAwIDYuNzYxMzUsLTYuMDI1NTQgbCAwLC0xMDEuNTQ0MDE4IDcyLjIxNjI4LDEwNC42OTkzOTggYSA2Ljc2MTM0MjIsNi4wMjU1NDk1IDAgMCAwIDUuNzYwMTUsMi44NzAxNiBsIDczLjU1NDg3LDAgYSA2Ljc2MTM0MjIsNi4wMjU1NDk1IDAgMCAwIDYuNzYxMzUsLTYuMDI1NTQgbCAwLC0xODcuODcxNDcgYSA2Ljc2MTM0MjIsNi4wMjU1NDk1IDAgMCAwIC02Ljc2MTM1LC02LjAyNTU1IGwgLTU0LjcxNjQ0LDAgYSA2Ljc2MTM0MjIsNi4wMjU1NDk1IDAgMCAwIC02Ljc2MTMzLDYuMDI1NTUgbCAwLDEwMi42MTkzNSBMIDE4My43NjQxMywyLjkwODg2IGEgNi43NjEzNDIyLDYuMDI1NTQ5NSAwIDAgMCAtNS43NjAxNCwtMi44NzAxNyB6IiAvPg0KICA8cGF0aCBkPSJNIDQuODQ0NjMzMywyMi4xMDg3NSBBIDEzLjQxMjAzOSwxMi41MDE4NDIgMCAwIDEgMTMuNDc3NTg4LDAuMDM5MjQgbCA2Ni4xMTgzMTUsMCBhIDUuMzY0ODE1OCw1LjAwMDczNyAwIDAgMSA1LjM2NDgyMyw1LjAwMDczIGwgMCw3OS44NzkzMSB6IiAvPg0KICA8cGF0aCBkPSJtIDQyMC4xNTUzNSwxNzcuODkxMTkgYSAxMy40MTIwMzgsMTIuNTAxODQyIDAgMCAxIC04LjYzMjk1LDIyLjA2OTUxIGwgLTY2LjExODMyLDAgYSA1LjM2NDgxNTIsNS4wMDA3MzcgMCAwIDEgLTUuMzY0ODIsLTUuMDAwNzQgbCAwLC03OS44NzkzMSB6IiAvPg0KPC9zdmc+DQo8IS0tIFRoaXMgd29yayBpcyBsaWNlbnNlZCB1bmRlciBhIENyZWF0aXZlIENvbW1vbnMgQXR0cmlidXRpb24tU2hhcmVBbGlrZSA0LjAgSW50ZXJuYXRpb25hbCBMaWNlbnNlLiAtLT4NCjwhLS0gaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbGljZW5zZXMvYnktc2EvNC4wLyAtLT4NCg==") no-repeat fixed center/70% 70%,linear-gradient(180deg,#2a2a2a 0,#202020);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff2a2a2a',endColorstr='#ff202020',GradientType=0)}body.nanotrasen .normal{color:#40628a}body.nanotrasen .good{color:#537d29}body.nanotrasen .average{color:#be6209}body.nanotrasen .bad{color:#b00e0e}body.nanotrasen .highlight{color:#8ba5c4}body.nanotrasen main{display:block;margin-top:32px;padding:2px 6px 0}body.nanotrasen hr{height:2px;background-color:#40628a;border:none}body.nanotrasen .hidden{display:none}body.nanotrasen .bar .barText,body.nanotrasen span.button{color:#fff;font-size:12px;font-weight:400;font-style:normal;text-decoration:none}body.nanotrasen .bold{font-weight:700}body.nanotrasen .italic{font-style:italic}body.nanotrasen [unselectable=on]{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}body.nanotrasen div[data-tooltip],body.nanotrasen span[data-tooltip]{position:relative}body.nanotrasen div[data-tooltip]:after,body.nanotrasen span[data-tooltip]:after{position:absolute;display:block;z-index:2;width:250px;padding:10px;-webkit-transform:translateX(-50%);-ms-transform:translateX(-50%);transform:translateX(-50%);visibility:hidden;opacity:0;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";white-space:normal;text-align:left;content:attr(data-tooltip);transition:all .5s;border:1px solid #272727;background-color:#363636}body.nanotrasen div[data-tooltip]:hover:after,body.nanotrasen span[data-tooltip]:hover:after{visibility:visible;opacity:1;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"}body.nanotrasen div[data-tooltip].tooltip-top:after,body.nanotrasen span[data-tooltip].tooltip-top:after{bottom:100%;left:50%;-webkit-transform:translateX(-50%) translateY(8px);-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.nanotrasen div[data-tooltip].tooltip-bottom:after,body.nanotrasen div[data-tooltip].tooltip-top:hover:after,body.nanotrasen span[data-tooltip].tooltip-bottom:after,body.nanotrasen span[data-tooltip].tooltip-top:hover:after{-webkit-transform:translateX(-50%) translateY(-8px);-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.nanotrasen div[data-tooltip].tooltip-bottom:after,body.nanotrasen span[data-tooltip].tooltip-bottom:after{top:100%;left:50%}body.nanotrasen div[data-tooltip].tooltip-bottom:hover:after,body.nanotrasen span[data-tooltip].tooltip-bottom:hover:after{-webkit-transform:translateX(-50%) translateY(8px);-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.nanotrasen div[data-tooltip].tooltip-left:after,body.nanotrasen span[data-tooltip].tooltip-left:after{top:50%;right:100%;-webkit-transform:translateX(8px) translateY(-50%);-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.nanotrasen div[data-tooltip].tooltip-left:hover:after,body.nanotrasen div[data-tooltip].tooltip-right:after,body.nanotrasen span[data-tooltip].tooltip-left:hover:after,body.nanotrasen span[data-tooltip].tooltip-right:after{-webkit-transform:translateX(-8px) translateY(-50%);-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.nanotrasen div[data-tooltip].tooltip-right:after,body.nanotrasen span[data-tooltip].tooltip-right:after{top:50%;left:100%}body.nanotrasen div[data-tooltip].tooltip-right:hover:after,body.nanotrasen span[data-tooltip].tooltip-right:hover:after{-webkit-transform:translateX(8px) translateY(-50%);-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.nanotrasen .bar{display:inline-block;position:relative;vertical-align:middle;width:100%;height:20px;line-height:17px;padding:1px;border:1px solid #40628a;background:#272727}body.nanotrasen .bar .barText{position:absolute;top:0;right:3px}body.nanotrasen .bar .barFill{display:block;height:100%;transition:background-color 1s;background-color:#40628a}body.nanotrasen .bar .barFill.good{background-color:#537d29}body.nanotrasen .bar .barFill.average{background-color:#be6209}body.nanotrasen .bar .barFill.bad{background-color:#b00e0e}body.nanotrasen span.button{display:inline-block;vertical-align:middle;height:20px;line-height:17px;padding:0 5px;white-space:nowrap;border:1px solid #272727}body.nanotrasen span.button .fa{padding-right:2px}body.nanotrasen span.button.normal{transition:background-color .5s;background-color:#40628a}body.nanotrasen span.button.normal.active:focus,body.nanotrasen span.button.normal.active:hover{transition:background-color .25s;background-color:#4f78aa;outline:0}body.nanotrasen span.button.disabled{transition:background-color .5s;background-color:#999}body.nanotrasen span.button.disabled.active:focus,body.nanotrasen span.button.disabled.active:hover{transition:background-color .25s;background-color:#a8a8a8;outline:0}body.nanotrasen span.button.selected{transition:background-color .5s;background-color:#2f943c}body.nanotrasen span.button.selected.active:focus,body.nanotrasen span.button.selected.active:hover{transition:background-color .25s;background-color:#3ab84b;outline:0}body.nanotrasen span.button.caution{transition:background-color .5s;background-color:#9a9d00}body.nanotrasen span.button.caution.active:focus,body.nanotrasen span.button.caution.active:hover{transition:background-color .25s;background-color:#ced200;outline:0}body.nanotrasen span.button.danger{transition:background-color .5s;background-color:#9d0808}body.nanotrasen span.button.danger.active:focus,body.nanotrasen span.button.danger.active:hover{transition:background-color .25s;background-color:#ce0b0b;outline:0}body.nanotrasen span.button.gridable{width:125px;margin:2px 0}body.nanotrasen span.button+span:not(.button),body.nanotrasen span:not(.button)+span.button{margin-left:5px}body.nanotrasen div.display{width:100%;padding:4px;margin:6px 0;background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#54000000,endColorStr=#54000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#54000000,endColorStr=#54000000);background-color:rgba(0,0,0,.33);box-shadow:inset 0 0 5px rgba(0,0,0,.5)}body.nanotrasen div.display header,body.nanotrasen div.subdisplay header{display:block;position:relative;width:100%;padding:0 4px;margin-bottom:6px;color:#fff;border-bottom:2px solid #40628a}body.nanotrasen div.display header .buttonRight,body.nanotrasen div.subdisplay header .buttonRight{position:absolute;bottom:6px;right:4px}body.nanotrasen div.display article,body.nanotrasen div.subdisplay article{display:table;width:100%;border-collapse:collapse}body.nanotrasen input{display:inline-block;vertical-align:middle;height:20px;line-height:17px;padding:0 5px;white-space:nowrap;color:#000;background-color:#fff;border:1px solid #272727}body.nanotrasen input::-webkit-input-placeholder{color:#999}body.nanotrasen input::-moz-placeholder{color:#999}body.nanotrasen input:-ms-input-placeholder{color:#999}body.nanotrasen input::placeholder{color:#999}body.nanotrasen input::-ms-clear{display:none}body.nanotrasen svg.linegraph{overflow:hidden}body.nanotrasen div.notice{margin:8px 0;padding:4px;box-shadow:none;color:#000;font-weight:700;font-style:italic;background-color:#bb9b68;background-image:repeating-linear-gradient(-45deg,#bb9b68,#bb9b68 10px,#b1905d 0,#b1905d 20px)}body.nanotrasen div.notice .label{color:#000}body.nanotrasen div.notice .content:only-of-type{padding:0}body.nanotrasen div.notice hr{background-color:#272727}body.nanotrasen div.resize{position:fixed;bottom:0;right:0;width:0;height:0;border-style:solid;border-width:0 0 45px 45px;border-color:transparent transparent #363636;-webkit-transform:rotate(1turn);-ms-transform:rotate(1turn);transform:rotate(1turn)}body.nanotrasen section .content,body.nanotrasen section .label,body.nanotrasen section .line,body.syndicate section .content,body.syndicate section .label,body.syndicate section .line{display:table-cell;margin:0;text-align:left;vertical-align:middle;padding:3px 2px}body.nanotrasen section{display:table-row;width:100%}body.nanotrasen section:not(:first-child){padding-top:4px}body.nanotrasen section.candystripe:nth-child(even){background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000);background-color:rgba(0,0,0,.2)}body.nanotrasen section .label{width:1%;padding-right:32px;white-space:nowrap;color:#8ba5c4}body.nanotrasen section .content:not(:last-child){padding-right:16px}body.nanotrasen section .line{width:100%}body.nanotrasen div.subdisplay{width:100%;margin:0}body.nanotrasen header.titlebar .close,body.nanotrasen header.titlebar .minimize{display:inline-block;position:relative;padding:7px;margin:-7px;color:#8ba5c4}body.nanotrasen header.titlebar .close:hover,body.nanotrasen header.titlebar .minimize:hover{color:#9cb2cd}body.nanotrasen header.titlebar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px;background-color:#363636;border-bottom:1px solid #161616;box-shadow:0 3px 3px rgba(0,0,0,.1)}body.nanotrasen header.titlebar .statusicon{position:absolute;top:4px;left:12px;transition:color .5s}body.nanotrasen header.titlebar .title{position:absolute;top:6px;left:46px;color:#8ba5c4;font-size:16px;white-space:nowrap}body.nanotrasen header.titlebar .minimize{position:absolute;top:6px;right:46px}body.nanotrasen header.titlebar .close{position:absolute;top:4px;right:12px}body.syndicate{background:url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+DQo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmVyc2lvbj0iMS4wIiB2aWV3Qm94PSIwIDAgMjAwIDI4OS43NDIiIG9wYWNpdHk9Ii4zMyI+DQogIDxwYXRoIGQ9Im0gOTMuNTM3Njc3LDAgYyAtMTguMTEzMTI1LDAgLTM0LjIyMDEzMywzLjExMTY0IC00OC4zMjM0ODQsOS4zMzQzNyAtMTMuOTY1MDkyLDYuMjIxNjcgLTI0LjYxMjQ0MiwxNS4wNzExNCAtMzEuOTQwNjUxLDI2LjU0NzEgLTcuMTg5OTM5OCwxMS4zMzc4OSAtMTAuMzAxMjI2NiwyNC43NDkxMSAtMTAuMzAxMjI2Niw0MC4yMzQ3OCAwLDEwLjY0NjYyIDIuNzI1MDAyNiwyMC40NjQ2NSA4LjE3NTExMTYsMjkuNDUyNTggNS42MTUyNzcsOC45ODY4NiAxNC4wMzgyNzcsMTcuMzUyMDQgMjUuMjY4ODIxLDI1LjA5NDM2IDExLjIzMDU0NCw3LjYwNTMxIDI2LjUwNzQyMSwxNS40MTgzNSA0NS44MzA1MTQsMjMuNDM3ODIgMTkuOTgzNzQ4LDguMjk1NTcgMzQuODQ4ODQ4LDE1LjU1NDcxIDQ0LjU5Mjk5OCwyMS43NzYzOCA5Ljc0NDE0LDYuMjIyNzMgMTYuNzYxNywxMi44NTg1IDIxLjA1NTcyLDE5LjkwOTUxIDQuMjk0MDQsNy4wNTIwOCA2LjQ0MTkzLDE1Ljc2NDA4IDYuNDQxOTMsMjYuMTM0NTkgMCwxNi4xNzcwMiAtNS4yMDE5NiwyOC40ODIyMiAtMTUuNjA2NzMsMzYuOTE2ODIgLTEwLjIzOTYsOC40MzQ3IC0yNS4wMjIwMywxMi42NTIzIC00NC4zNDUxNjksMTIuNjUyMyAtMTQuMDM4MTcxLDAgLTI1LjUxNTI0NywtMS42NTk0IC0zNC40MzM2MTgsLTQuOTc3NyAtOC45MTgzNywtMy40NTY2IC0xNi4xODU1NzIsLTguNzExMyAtMjEuODAwODM5LC0xNS43NjMzIC01LjYxNTI3NywtNy4wNTIxIC0xMC4wNzQ3OTUsLTE2LjY2MDg4IC0xMy4zNzc4OTksLTI4LjgyODEyIGwgLTI0Ljc3MzE2MjYyOTM5NDUsMCAwLDU2LjgyNjMyIEMgMzMuODU2NzY5LDI4Ni4wNzYwMSA2My43NDkwNCwyODkuNzQyMDEgODkuNjc4MzgzLDI4OS43NDIwMSBjIDE2LjAyMDAyNywwIDMwLjcxOTc4NywtMS4zODI3IDQ0LjA5NzMzNywtNC4xNDc5IDEzLjU0MjcyLC0yLjkwNDMgMjUuMTA0MSwtNy40Njc2IDM0LjY4MzA5LC0xMy42ODkzIDkuNzQ0MTMsLTYuMzU5NyAxNy4zNDA0MiwtMTQuNTE5NSAyMi43OTA1MiwtMjQuNDc0OCA1LjQ1MDEsLTEwLjA5MzMyIDguMTc1MTEsLTIyLjM5OTU5IDguMTc1MTEsLTM2LjkxNjgyIDAsLTEyLjk5NzY0IC0zLjMwMjEsLTI0LjMzNTM5IC05LjkwODI5LC0zNC4wMTQ2IC02LjQ0MTA1LC05LjgxNzI1IC0xNS41MjU0NSwtMTguNTI3MDcgLTI3LjI1MTQ2LC0yNi4xMzEzMyAtMTEuNTYwODUsLTcuNjA0MjcgLTI3LjkxMDgzLC0xNS44MzE0MiAtNDkuMDUwNjYsLTI0LjY4MDIyIC0xNy41MDY0NCwtNy4xOTAxMiAtMzAuNzE5NjY4LC0xMy42ODk0OCAtMzkuNjM4MDM4LC0xOS40OTcwMSAtOC45MTgzNzEsLTUuODA3NTIgLTE4LjYwNzQ3NCwtMTIuNDM0MDkgLTI0LjA5NjUyNCwtMTguODc0MTcgLTUuNDI2MDQzLC02LjM2NjE2IC05LjY1ODgyNiwtMTUuMDcwMDMgLTkuNjU4ODI2LC0yNC44ODcyOSAwLC05LjI2NDAxIDIuMDc1NDE0LC0xNy4yMTM0NSA2LjIyMzQ1NCwtMjMuODUwMzMgMTEuMDk4Mjk4LC0xNC4zOTc0OCA0MS4yODY2MzgsLTEuNzk1MDcgNDUuMDc1NjA5LDI0LjM0NzYyIDQuODM5MzkyLDYuNzc0OTEgOC44NDkzNSwxNi4yNDcyOSAxMi4wMjk1MTUsMjguNDE1NiBsIDIwLjUzMjM0LDAgMCwtNTUuOTk5NjcgYyAtNC40NzgyNSwtNS45MjQ0OCAtOS45NTQ4OCwtMTAuNjMyMjIgLTE1LjkwODM3LC0xNC4zNzQxMSAxLjY0MDU1LDAuNDc5MDUgMy4xOTAzOSwxLjAyMzc2IDQuNjM4NjUsMS42NDAyNCA2LjQ5ODYxLDIuNjI2MDcgMTIuMTY3OTMsNy4zMjc0NyAxNy4wMDczLDE0LjEwMzQ1IDQuODM5MzksNi43NzQ5MSA4Ljg0OTM1LDE2LjI0NTY3IDEyLjAyOTUyLDI4LjQxMzk3IDAsMCA4LjQ4MTI4LC0wLjEyODk0IDguNDg5NzgsLTAuMDAyIDAuNDE3NzYsNi40MTQ5NCAtMS43NTMzOSw5LjQ1Mjg2IC00LjEyMzQyLDEyLjU2MTA0IC0yLjQxNzQsMy4xNjk3OCAtNS4xNDQ4Niw2Ljc4OTczIC00LjAwMjc4LDEzLjAwMjkgMS41MDc4Niw4LjIwMzE4IDEwLjE4MzU0LDEwLjU5NjQyIDE0LjYyMTk0LDkuMzExNTQgLTMuMzE4NDIsLTAuNDk5MTEgLTUuMzE4NTUsLTEuNzQ5NDggLTUuMzE4NTUsLTEuNzQ5NDggMCwwIDEuODc2NDYsMC45OTg2OCA1LjY1MTE3LC0xLjM1OTgxIC0zLjI3Njk1LDAuOTU1NzEgLTEwLjcwNTI5LC0wLjc5NzM4IC0xMS44MDEyNSwtNi43NjMxMyAtMC45NTc1MiwtNS4yMDg2MSAwLjk0NjU0LC03LjI5NTE0IDMuNDAxMTMsLTEwLjUxNDgyIDIuNDU0NjIsLTMuMjE5NjggNS4yODQyNiwtNi45NTgzMSA0LjY4NDMsLTE0LjQ4ODI0IGwgMC4wMDMsMC4wMDIgOC45MjY3NiwwIDAsLTU1Ljk5OTY3IGMgLTE1LjA3MTI1LC0zLjg3MTY4IC0yNy42NTMxNCwtNi4zNjA0MiAtMzcuNzQ2NzEsLTcuNDY1ODYgLTkuOTU1MzEsLTEuMTA3NTUgLTIwLjE4ODIzLC0xLjY1OTgxIC0zMC42OTY2MTMsLTEuNjU5ODEgeiBtIDcwLjMyMTYwMywxNy4zMDg5MyAwLjIzODA1LDQwLjMwNDkgYyAxLjMxODA4LDEuMjI2NjYgMi40Mzk2NSwyLjI3ODE1IDMuMzQwODEsMy4xMDYwMiA0LjgzOTM5LDYuNzc0OTEgOC44NDkzNCwxNi4yNDU2NiAxMi4wMjk1MSwyOC40MTM5NyBsIDIwLjUzMjM0LDAgMCwtNTUuOTk5NjcgYyAtNi42NzczMSwtNC41OTM4MSAtMTkuODM2NDMsLTEwLjQ3MzA5IC0zNi4xNDA3MSwtMTUuODI1MjIgeiBtIC0yOC4xMjA0OSw1LjYwNTUxIDguNTY0NzksMTcuNzE2NTUgYyAtMTEuOTcwMzcsLTYuNDY2OTcgLTEzLjg0Njc4LC05LjcxNzI2IC04LjU2NDc5LC0xNy43MTY1NSB6IG0gMjIuNzk3MDUsMCBjIDIuNzcxNSw3Ljk5OTI5IDEuNzg3NDEsMTEuMjQ5NTggLTQuNDkzNTQsMTcuNzE2NTUgbCA0LjQ5MzU0LC0xNy43MTY1NSB6IG0gMTUuMjIxOTUsMjQuMDA4NDggOC41NjQ3OSwxNy43MTY1NSBjIC0xMS45NzAzOCwtNi40NjY5NyAtMTMuODQ2NzksLTkuNzE3MjYgLTguNTY0NzksLTE3LjcxNjU1IHogbSAyMi43OTcwNCwwIGMgMi43NzE1LDcuOTk5MjkgMS43ODc0MSwxMS4yNDk1OCAtNC40OTM1NCwxNy43MTY1NSBsIDQuNDkzNTQsLTE3LjcxNjU1IHogbSAtOTkuMTEzODQsMi4yMDc2NCA4LjU2NDc5LDE3LjcxNjU1IGMgLTExLjk3MDM4MiwtNi40NjY5NyAtMTMuODQ2NzgyLC05LjcxNzI2IC04LjU2NDc5LC0xNy43MTY1NSB6IG0gMjIuNzk1NDIsMCBjIDIuNzcxNSw3Ljk5OTI5IDEuNzg3NDEsMTEuMjQ5NTggLTQuNDkzNTQsMTcuNzE2NTUgbCA0LjQ5MzU0LC0xNy43MTY1NSB6IiAvPg0KPC9zdmc+DQo8IS0tIFRoaXMgd29yayBpcyBsaWNlbnNlZCB1bmRlciBhIENyZWF0aXZlIENvbW1vbnMgQXR0cmlidXRpb24tU2hhcmVBbGlrZSA0LjAgSW50ZXJuYXRpb25hbCBMaWNlbnNlLiAtLT4NCjwhLS0gaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbGljZW5zZXMvYnktc2EvNC4wLyAtLT4NCg==") no-repeat fixed center/70% 70%,linear-gradient(180deg,#750000 0,#340404);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff750000',endColorstr='#ff340404',GradientType=0)}body.syndicate .normal{color:#40628a}body.syndicate .good{color:#73e573}body.syndicate .average{color:#be6209}body.syndicate .bad{color:#b00e0e}body.syndicate .highlight{color:#000}body.syndicate main{display:block;margin-top:32px;padding:2px 6px 0}body.syndicate hr{height:2px;background-color:#272727;border:none}body.syndicate .hidden{display:none}body.syndicate .bar .barText,body.syndicate span.button{color:#fff;font-size:12px;font-weight:400;font-style:normal;text-decoration:none}body.syndicate .bold{font-weight:700}body.syndicate .italic{font-style:italic}body.syndicate [unselectable=on]{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}body.syndicate div[data-tooltip],body.syndicate span[data-tooltip]{position:relative}body.syndicate div[data-tooltip]:after,body.syndicate span[data-tooltip]:after{position:absolute;display:block;z-index:2;width:250px;padding:10px;-webkit-transform:translateX(-50%);-ms-transform:translateX(-50%);transform:translateX(-50%);visibility:hidden;opacity:0;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";white-space:normal;text-align:left;content:attr(data-tooltip);transition:all .5s;border:1px solid #272727;background-color:#363636}body.syndicate div[data-tooltip]:hover:after,body.syndicate span[data-tooltip]:hover:after{visibility:visible;opacity:1;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"}body.syndicate div[data-tooltip].tooltip-top:after,body.syndicate span[data-tooltip].tooltip-top:after{bottom:100%;left:50%;-webkit-transform:translateX(-50%) translateY(8px);-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.syndicate div[data-tooltip].tooltip-bottom:after,body.syndicate div[data-tooltip].tooltip-top:hover:after,body.syndicate span[data-tooltip].tooltip-bottom:after,body.syndicate span[data-tooltip].tooltip-top:hover:after{-webkit-transform:translateX(-50%) translateY(-8px);-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.syndicate div[data-tooltip].tooltip-bottom:after,body.syndicate span[data-tooltip].tooltip-bottom:after{top:100%;left:50%}body.syndicate div[data-tooltip].tooltip-bottom:hover:after,body.syndicate span[data-tooltip].tooltip-bottom:hover:after{-webkit-transform:translateX(-50%) translateY(8px);-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.syndicate div[data-tooltip].tooltip-left:after,body.syndicate span[data-tooltip].tooltip-left:after{top:50%;right:100%;-webkit-transform:translateX(8px) translateY(-50%);-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.syndicate div[data-tooltip].tooltip-left:hover:after,body.syndicate div[data-tooltip].tooltip-right:after,body.syndicate span[data-tooltip].tooltip-left:hover:after,body.syndicate span[data-tooltip].tooltip-right:after{-webkit-transform:translateX(-8px) translateY(-50%);-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.syndicate div[data-tooltip].tooltip-right:after,body.syndicate span[data-tooltip].tooltip-right:after{top:50%;left:100%}body.syndicate div[data-tooltip].tooltip-right:hover:after,body.syndicate span[data-tooltip].tooltip-right:hover:after{-webkit-transform:translateX(8px) translateY(-50%);-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.syndicate .bar{display:inline-block;position:relative;vertical-align:middle;width:100%;height:20px;line-height:17px;padding:1px;border:1px solid #000;background:#272727}body.syndicate .bar .barText{position:absolute;top:0;right:3px}body.syndicate .bar .barFill{display:block;height:100%;transition:background-color 1s;background-color:#000}body.syndicate .bar .barFill.good{background-color:#73e573}body.syndicate .bar .barFill.average{background-color:#be6209}body.syndicate .bar .barFill.bad{background-color:#b00e0e}body.syndicate span.button{display:inline-block;vertical-align:middle;height:20px;line-height:17px;padding:0 5px;white-space:nowrap;border:1px solid #272727}body.syndicate span.button .fa{padding-right:2px}body.syndicate span.button.normal{transition:background-color .5s;background-color:#397439}body.syndicate span.button.normal.active:focus,body.syndicate span.button.normal.active:hover{transition:background-color .25s;background-color:#4a964a;outline:0}body.syndicate span.button.disabled{transition:background-color .5s;background-color:#363636}body.syndicate span.button.disabled.active:focus,body.syndicate span.button.disabled.active:hover{transition:background-color .25s;background-color:#545454;outline:0}body.syndicate span.button.selected{transition:background-color .5s;background-color:#9d0808}body.syndicate span.button.selected.active:focus,body.syndicate span.button.selected.active:hover{transition:background-color .25s;background-color:#ce0b0b;outline:0}body.syndicate span.button.caution{transition:background-color .5s;background-color:#be6209}body.syndicate span.button.caution.active:focus,body.syndicate span.button.caution.active:hover{transition:background-color .25s;background-color:#eb790b;outline:0}body.syndicate span.button.danger{transition:background-color .5s;background-color:#9a9d00}body.syndicate span.button.danger.active:focus,body.syndicate span.button.danger.active:hover{transition:background-color .25s;background-color:#ced200;outline:0}body.syndicate span.button.gridable{width:125px;margin:2px 0}body.syndicate span.button+span:not(.button),body.syndicate span:not(.button)+span.button{margin-left:5px}body.syndicate div.display{width:100%;padding:4px;margin:6px 0;background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#80000000,endColorStr=#80000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#80000000,endColorStr=#80000000);background-color:rgba(0,0,0,.5);box-shadow:inset 0 0 5px rgba(0,0,0,.75)}body.syndicate div.display header,body.syndicate div.subdisplay header{display:block;position:relative;width:100%;padding:0 4px;margin-bottom:6px;color:#fff;border-bottom:2px solid #272727}body.syndicate div.display header .buttonRight,body.syndicate div.subdisplay header .buttonRight{position:absolute;bottom:6px;right:4px}body.syndicate div.display article,body.syndicate div.subdisplay article{display:table;width:100%;border-collapse:collapse}body.syndicate input{display:inline-block;vertical-align:middle;height:20px;line-height:17px;padding:0 5px;white-space:nowrap;color:#fff;background-color:#9d0808;border:1px solid #272727}body.syndicate input::-webkit-input-placeholder{color:#999}body.syndicate input::-moz-placeholder{color:#999}body.syndicate input:-ms-input-placeholder{color:#999}body.syndicate input::placeholder{color:#999}body.syndicate input::-ms-clear{display:none}body.syndicate svg.linegraph{overflow:hidden}body.syndicate div.notice{margin:8px 0;padding:4px;box-shadow:none;color:#000;font-weight:700;font-style:italic;background-color:#750000;background-image:repeating-linear-gradient(-45deg,#750000,#750000 10px,#910101 0,#910101 20px)}body.syndicate div.notice .label{color:#000}body.syndicate div.notice .content:only-of-type{padding:0}body.syndicate div.notice hr{background-color:#272727}body.syndicate div.resize{position:fixed;bottom:0;right:0;width:0;height:0;border-style:solid;border-width:0 0 45px 45px;border-color:transparent transparent #363636;-webkit-transform:rotate(1turn);-ms-transform:rotate(1turn);transform:rotate(1turn)}body.syndicate section .content,body.syndicate section .label,body.syndicate section .line{display:table-cell;margin:0;text-align:left;vertical-align:middle;padding:3px 2px}body.syndicate section{display:table-row;width:100%}body.syndicate section:not(:first-child){padding-top:4px}body.syndicate section.candystripe:nth-child(even){background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000);background-color:rgba(0,0,0,.2)}body.syndicate section .label{width:1%;padding-right:32px;white-space:nowrap;color:#fff}body.syndicate section .content:not(:last-child){padding-right:16px}body.syndicate section .line{width:100%}body.syndicate div.subdisplay{width:100%;margin:0}body.syndicate header.titlebar .close,body.syndicate header.titlebar .minimize{display:inline-block;position:relative;padding:7px;margin:-7px;color:#e74242}body.syndicate header.titlebar .close:hover,body.syndicate header.titlebar .minimize:hover{color:#eb5e5e}body.syndicate header.titlebar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px;background-color:#363636;border-bottom:1px solid #161616;box-shadow:0 3px 3px rgba(0,0,0,.1)}body.syndicate header.titlebar .statusicon{position:absolute;top:4px;left:12px;transition:color .5s}body.syndicate header.titlebar .title{position:absolute;top:6px;left:46px;color:#e74242;font-size:16px;white-space:nowrap}body.syndicate header.titlebar .minimize{position:absolute;top:6px;right:46px}body.syndicate header.titlebar .close{position:absolute;top:4px;right:12px} \ No newline at end of file +@charset "utf-8";body,html{box-sizing:border-box;height:100%;margin:0}html{overflow:hidden;cursor:default}body{overflow:auto;font-family:Verdana,Geneva,sans-serif;font-size:12px;color:#fff;background-color:#2a2a2a;background-image:linear-gradient(180deg,#2a2a2a 0,#202020);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff2a2a2a',endColorstr='#ff202020',GradientType=0)}*,:after,:before{box-sizing:inherit}h1,h2,h3,h4{display:inline-block;margin:0;padding:6px 0}h1{font-size:18px}h2{font-size:16px}h3{font-size:14px}h4{font-size:12px}body.nanotrasen{background:url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2ZXJzaW9uPSIxLjAiIHZpZXdCb3g9IjAgMCA0MjUgMjAwIiBvcGFjaXR5PSIuMzMiPgogIDxwYXRoIGQ9Im0gMTc4LjAwMzk5LDAuMDM4NjkgLTcxLjIwMzkzLDAgYSA2Ljc2MTM0MjIsNi4wMjU1NDk1IDAgMCAwIC02Ljc2MTM0LDYuMDI1NTUgbCAwLDE4Ny44NzE0NyBhIDYuNzYxMzQyMiw2LjAyNTU0OTUgMCAwIDAgNi43NjEzNCw2LjAyNTU0IGwgNTMuMTA3MiwwIGEgNi43NjEzNDIyLDYuMDI1NTQ5NSAwIDAgMCA2Ljc2MTM1LC02LjAyNTU0IGwgMCwtMTAxLjU0NDAxOCA3Mi4yMTYyOCwxMDQuNjk5Mzk4IGEgNi43NjEzNDIyLDYuMDI1NTQ5NSAwIDAgMCA1Ljc2MDE1LDIuODcwMTYgbCA3My41NTQ4NywwIGEgNi43NjEzNDIyLDYuMDI1NTQ5NSAwIDAgMCA2Ljc2MTM1LC02LjAyNTU0IGwgMCwtMTg3Ljg3MTQ3IGEgNi43NjEzNDIyLDYuMDI1NTQ5NSAwIDAgMCAtNi43NjEzNSwtNi4wMjU1NSBsIC01NC43MTY0NCwwIGEgNi43NjEzNDIyLDYuMDI1NTQ5NSAwIDAgMCAtNi43NjEzMyw2LjAyNTU1IGwgMCwxMDIuNjE5MzUgTCAxODMuNzY0MTMsMi45MDg4NiBhIDYuNzYxMzQyMiw2LjAyNTU0OTUgMCAwIDAgLTUuNzYwMTQsLTIuODcwMTcgeiIgLz4KICA8cGF0aCBkPSJNIDQuODQ0NjMzMywyMi4xMDg3NSBBIDEzLjQxMjAzOSwxMi41MDE4NDIgMCAwIDEgMTMuNDc3NTg4LDAuMDM5MjQgbCA2Ni4xMTgzMTUsMCBhIDUuMzY0ODE1OCw1LjAwMDczNyAwIDAgMSA1LjM2NDgyMyw1LjAwMDczIGwgMCw3OS44NzkzMSB6IiAvPgogIDxwYXRoIGQ9Im0gNDIwLjE1NTM1LDE3Ny44OTExOSBhIDEzLjQxMjAzOCwxMi41MDE4NDIgMCAwIDEgLTguNjMyOTUsMjIuMDY5NTEgbCAtNjYuMTE4MzIsMCBhIDUuMzY0ODE1Miw1LjAwMDczNyAwIDAgMSAtNS4zNjQ4MiwtNS4wMDA3NCBsIDAsLTc5Ljg3OTMxIHoiIC8+Cjwvc3ZnPgo8IS0tIFRoaXMgd29yayBpcyBsaWNlbnNlZCB1bmRlciBhIENyZWF0aXZlIENvbW1vbnMgQXR0cmlidXRpb24tU2hhcmVBbGlrZSA0LjAgSW50ZXJuYXRpb25hbCBMaWNlbnNlLiAtLT4KPCEtLSBodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9saWNlbnNlcy9ieS1zYS80LjAvIC0tPgo=") no-repeat fixed center/70% 70%,linear-gradient(180deg,#2a2a2a 0,#202020);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff2a2a2a',endColorstr='#ff202020',GradientType=0)}body.nanotrasen .normal{color:#40628a}body.nanotrasen .good{color:#537d29}body.nanotrasen .average{color:#be6209}body.nanotrasen .bad{color:#b00e0e}body.nanotrasen .highlight{color:#8ba5c4}body.nanotrasen main{display:block;margin-top:32px;padding:2px 6px 0}body.nanotrasen hr{height:2px;background-color:#40628a;border:none}body.nanotrasen .hidden{display:none}body.nanotrasen .bar .barText,body.nanotrasen span.button{color:#fff;font-size:12px;font-weight:400;font-style:normal;text-decoration:none}body.nanotrasen .bold{font-weight:700}body.nanotrasen .italic{font-style:italic}body.nanotrasen [unselectable=on]{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}body.nanotrasen div[data-tooltip],body.nanotrasen span[data-tooltip]{position:relative}body.nanotrasen div[data-tooltip]:after,body.nanotrasen span[data-tooltip]:after{position:absolute;display:block;z-index:2;width:250px;padding:10px;-webkit-transform:translateX(-50%);-ms-transform:translateX(-50%);transform:translateX(-50%);visibility:hidden;opacity:0;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";white-space:normal;text-align:left;content:attr(data-tooltip);transition:all .5s;border:1px solid #272727;background-color:#363636}body.nanotrasen div[data-tooltip]:hover:after,body.nanotrasen span[data-tooltip]:hover:after{visibility:visible;opacity:1;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"}body.nanotrasen div[data-tooltip].tooltip-top:after,body.nanotrasen span[data-tooltip].tooltip-top:after{bottom:100%;left:50%;-webkit-transform:translateX(-50%) translateY(8px);-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.nanotrasen div[data-tooltip].tooltip-bottom:after,body.nanotrasen div[data-tooltip].tooltip-top:hover:after,body.nanotrasen span[data-tooltip].tooltip-bottom:after,body.nanotrasen span[data-tooltip].tooltip-top:hover:after{-webkit-transform:translateX(-50%) translateY(-8px);-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.nanotrasen div[data-tooltip].tooltip-bottom:after,body.nanotrasen span[data-tooltip].tooltip-bottom:after{top:100%;left:50%}body.nanotrasen div[data-tooltip].tooltip-bottom:hover:after,body.nanotrasen span[data-tooltip].tooltip-bottom:hover:after{-webkit-transform:translateX(-50%) translateY(8px);-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.nanotrasen div[data-tooltip].tooltip-left:after,body.nanotrasen span[data-tooltip].tooltip-left:after{top:50%;right:100%;-webkit-transform:translateX(8px) translateY(-50%);-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.nanotrasen div[data-tooltip].tooltip-left:hover:after,body.nanotrasen div[data-tooltip].tooltip-right:after,body.nanotrasen span[data-tooltip].tooltip-left:hover:after,body.nanotrasen span[data-tooltip].tooltip-right:after{-webkit-transform:translateX(-8px) translateY(-50%);-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.nanotrasen div[data-tooltip].tooltip-right:after,body.nanotrasen span[data-tooltip].tooltip-right:after{top:50%;left:100%}body.nanotrasen div[data-tooltip].tooltip-right:hover:after,body.nanotrasen span[data-tooltip].tooltip-right:hover:after{-webkit-transform:translateX(8px) translateY(-50%);-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.nanotrasen .bar{display:inline-block;position:relative;vertical-align:middle;width:100%;height:20px;line-height:17px;padding:1px;border:1px solid #40628a;background:#272727}body.nanotrasen .bar .barText{position:absolute;top:0;right:3px}body.nanotrasen .bar .barFill{display:block;height:100%;transition:background-color 1s;background-color:#40628a}body.nanotrasen .bar .barFill.good{background-color:#537d29}body.nanotrasen .bar .barFill.average{background-color:#be6209}body.nanotrasen .bar .barFill.bad{background-color:#b00e0e}body.nanotrasen span.button{display:inline-block;vertical-align:middle;height:20px;line-height:17px;padding:0 5px;white-space:nowrap;border:1px solid #272727}body.nanotrasen span.button .fa{padding-right:2px}body.nanotrasen span.button.normal{transition:background-color .5s;background-color:#40628a}body.nanotrasen span.button.normal.active:focus,body.nanotrasen span.button.normal.active:hover{transition:background-color .25s;background-color:#4f78aa;outline:0}body.nanotrasen span.button.disabled{transition:background-color .5s;background-color:#999}body.nanotrasen span.button.disabled.active:focus,body.nanotrasen span.button.disabled.active:hover{transition:background-color .25s;background-color:#a8a8a8;outline:0}body.nanotrasen span.button.selected{transition:background-color .5s;background-color:#2f943c}body.nanotrasen span.button.selected.active:focus,body.nanotrasen span.button.selected.active:hover{transition:background-color .25s;background-color:#3ab84b;outline:0}body.nanotrasen span.button.caution{transition:background-color .5s;background-color:#9a9d00}body.nanotrasen span.button.caution.active:focus,body.nanotrasen span.button.caution.active:hover{transition:background-color .25s;background-color:#ced200;outline:0}body.nanotrasen span.button.danger{transition:background-color .5s;background-color:#9d0808}body.nanotrasen span.button.danger.active:focus,body.nanotrasen span.button.danger.active:hover{transition:background-color .25s;background-color:#ce0b0b;outline:0}body.nanotrasen span.button.gridable{width:125px;margin:2px 0}body.nanotrasen span.button+span:not(.button),body.nanotrasen span:not(.button)+span.button{margin-left:5px}body.nanotrasen div.display{width:100%;padding:4px;margin:6px 0;background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#54000000,endColorStr=#54000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#54000000,endColorStr=#54000000);background-color:rgba(0,0,0,.33);box-shadow:inset 0 0 5px rgba(0,0,0,.5)}body.nanotrasen div.display header,body.nanotrasen div.subdisplay header{display:block;position:relative;width:100%;padding:0 4px;margin-bottom:6px;color:#fff;border-bottom:2px solid #40628a}body.nanotrasen div.display header .buttonRight,body.nanotrasen div.subdisplay header .buttonRight{position:absolute;bottom:6px;right:4px}body.nanotrasen div.display article,body.nanotrasen div.subdisplay article{display:table;width:100%;border-collapse:collapse}body.nanotrasen input{display:inline-block;vertical-align:middle;height:20px;line-height:17px;padding:0 5px;white-space:nowrap;color:#000;background-color:#fff;border:1px solid #272727}body.nanotrasen input::-webkit-input-placeholder{color:#999}body.nanotrasen input::-moz-placeholder{color:#999}body.nanotrasen input:-ms-input-placeholder{color:#999}body.nanotrasen input::placeholder{color:#999}body.nanotrasen input::-ms-clear{display:none}body.nanotrasen svg.linegraph{overflow:hidden}body.nanotrasen div.notice{margin:8px 0;padding:4px;box-shadow:none;color:#000;font-weight:700;font-style:italic;background-color:#bb9b68;background-image:repeating-linear-gradient(-45deg,#bb9b68,#bb9b68 10px,#b1905d 0,#b1905d 20px)}body.nanotrasen div.notice .label{color:#000}body.nanotrasen div.notice .content:only-of-type{padding:0}body.nanotrasen div.notice hr{background-color:#272727}body.nanotrasen div.resize{position:fixed;bottom:0;right:0;width:0;height:0;border-style:solid;border-width:0 0 45px 45px;border-color:transparent transparent #363636;-webkit-transform:rotate(1turn);-ms-transform:rotate(1turn);transform:rotate(1turn)}body.nanotrasen section .content,body.nanotrasen section .label,body.nanotrasen section .line,body.syndicate section .content,body.syndicate section .label,body.syndicate section .line{display:table-cell;margin:0;text-align:left;vertical-align:middle;padding:3px 2px}body.nanotrasen section{display:table-row;width:100%}body.nanotrasen section:not(:first-child){padding-top:4px}body.nanotrasen section.candystripe:nth-child(even){background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000);background-color:rgba(0,0,0,.2)}body.nanotrasen section .label{width:1%;padding-right:32px;white-space:nowrap;color:#8ba5c4}body.nanotrasen section .content:not(:last-child){padding-right:16px}body.nanotrasen section .line{width:100%}body.nanotrasen div.subdisplay{width:100%;margin:0}body.nanotrasen header.titlebar .close,body.nanotrasen header.titlebar .minimize{display:inline-block;position:relative;padding:7px;margin:-7px;color:#8ba5c4}body.nanotrasen header.titlebar .close:hover,body.nanotrasen header.titlebar .minimize:hover{color:#9cb2cd}body.nanotrasen header.titlebar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px;background-color:#363636;border-bottom:1px solid #161616;box-shadow:0 3px 3px rgba(0,0,0,.1)}body.nanotrasen header.titlebar .statusicon{position:absolute;top:4px;left:12px;transition:color .5s}body.nanotrasen header.titlebar .title{position:absolute;top:6px;left:46px;color:#8ba5c4;font-size:16px;white-space:nowrap}body.nanotrasen header.titlebar .minimize{position:absolute;top:6px;right:46px}body.nanotrasen header.titlebar .close{position:absolute;top:4px;right:12px}body.syndicate{background:url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2ZXJzaW9uPSIxLjAiIHZpZXdCb3g9IjAgMCAyMDAgMjg5Ljc0MiIgb3BhY2l0eT0iLjMzIj4KICA8cGF0aCBkPSJtIDkzLjUzNzY3NywwIGMgLTE4LjExMzEyNSwwIC0zNC4yMjAxMzMsMy4xMTE2NCAtNDguMzIzNDg0LDkuMzM0MzcgLTEzLjk2NTA5Miw2LjIyMTY3IC0yNC42MTI0NDIsMTUuMDcxMTQgLTMxLjk0MDY1MSwyNi41NDcxIC03LjE4OTkzOTgsMTEuMzM3ODkgLTEwLjMwMTIyNjYsMjQuNzQ5MTEgLTEwLjMwMTIyNjYsNDAuMjM0NzggMCwxMC42NDY2MiAyLjcyNTAwMjYsMjAuNDY0NjUgOC4xNzUxMTE2LDI5LjQ1MjU4IDUuNjE1Mjc3LDguOTg2ODYgMTQuMDM4Mjc3LDE3LjM1MjA0IDI1LjI2ODgyMSwyNS4wOTQzNiAxMS4yMzA1NDQsNy42MDUzMSAyNi41MDc0MjEsMTUuNDE4MzUgNDUuODMwNTE0LDIzLjQzNzgyIDE5Ljk4Mzc0OCw4LjI5NTU3IDM0Ljg0ODg0OCwxNS41NTQ3MSA0NC41OTI5OTgsMjEuNzc2MzggOS43NDQxNCw2LjIyMjczIDE2Ljc2MTcsMTIuODU4NSAyMS4wNTU3MiwxOS45MDk1MSA0LjI5NDA0LDcuMDUyMDggNi40NDE5MywxNS43NjQwOCA2LjQ0MTkzLDI2LjEzNDU5IDAsMTYuMTc3MDIgLTUuMjAxOTYsMjguNDgyMjIgLTE1LjYwNjczLDM2LjkxNjgyIC0xMC4yMzk2LDguNDM0NyAtMjUuMDIyMDMsMTIuNjUyMyAtNDQuMzQ1MTY5LDEyLjY1MjMgLTE0LjAzODE3MSwwIC0yNS41MTUyNDcsLTEuNjU5NCAtMzQuNDMzNjE4LC00Ljk3NzcgLTguOTE4MzcsLTMuNDU2NiAtMTYuMTg1NTcyLC04LjcxMTMgLTIxLjgwMDgzOSwtMTUuNzYzMyAtNS42MTUyNzcsLTcuMDUyMSAtMTAuMDc0Nzk1LC0xNi42NjA4OCAtMTMuMzc3ODk5LC0yOC44MjgxMiBsIC0yNC43NzMxNjI2MjkzOTQ1LDAgMCw1Ni44MjYzMiBDIDMzLjg1Njc2OSwyODYuMDc2MDEgNjMuNzQ5MDQsMjg5Ljc0MjAxIDg5LjY3ODM4MywyODkuNzQyMDEgYyAxNi4wMjAwMjcsMCAzMC43MTk3ODcsLTEuMzgyNyA0NC4wOTczMzcsLTQuMTQ3OSAxMy41NDI3MiwtMi45MDQzIDI1LjEwNDEsLTcuNDY3NiAzNC42ODMwOSwtMTMuNjg5MyA5Ljc0NDEzLC02LjM1OTcgMTcuMzQwNDIsLTE0LjUxOTUgMjIuNzkwNTIsLTI0LjQ3NDggNS40NTAxLC0xMC4wOTMzMiA4LjE3NTExLC0yMi4zOTk1OSA4LjE3NTExLC0zNi45MTY4MiAwLC0xMi45OTc2NCAtMy4zMDIxLC0yNC4zMzUzOSAtOS45MDgyOSwtMzQuMDE0NiAtNi40NDEwNSwtOS44MTcyNSAtMTUuNTI1NDUsLTE4LjUyNzA3IC0yNy4yNTE0NiwtMjYuMTMxMzMgLTExLjU2MDg1LC03LjYwNDI3IC0yNy45MTA4MywtMTUuODMxNDIgLTQ5LjA1MDY2LC0yNC42ODAyMiAtMTcuNTA2NDQsLTcuMTkwMTIgLTMwLjcxOTY2OCwtMTMuNjg5NDggLTM5LjYzODAzOCwtMTkuNDk3MDEgLTguOTE4MzcxLC01LjgwNzUyIC0xOC42MDc0NzQsLTEyLjQzNDA5IC0yNC4wOTY1MjQsLTE4Ljg3NDE3IC01LjQyNjA0MywtNi4zNjYxNiAtOS42NTg4MjYsLTE1LjA3MDAzIC05LjY1ODgyNiwtMjQuODg3MjkgMCwtOS4yNjQwMSAyLjA3NTQxNCwtMTcuMjEzNDUgNi4yMjM0NTQsLTIzLjg1MDMzIDExLjA5ODI5OCwtMTQuMzk3NDggNDEuMjg2NjM4LC0xLjc5NTA3IDQ1LjA3NTYwOSwyNC4zNDc2MiA0LjgzOTM5Miw2Ljc3NDkxIDguODQ5MzUsMTYuMjQ3MjkgMTIuMDI5NTE1LDI4LjQxNTYgbCAyMC41MzIzNCwwIDAsLTU1Ljk5OTY3IGMgLTQuNDc4MjUsLTUuOTI0NDggLTkuOTU0ODgsLTEwLjYzMjIyIC0xNS45MDgzNywtMTQuMzc0MTEgMS42NDA1NSwwLjQ3OTA1IDMuMTkwMzksMS4wMjM3NiA0LjYzODY1LDEuNjQwMjQgNi40OTg2MSwyLjYyNjA3IDEyLjE2NzkzLDcuMzI3NDcgMTcuMDA3MywxNC4xMDM0NSA0LjgzOTM5LDYuNzc0OTEgOC44NDkzNSwxNi4yNDU2NyAxMi4wMjk1MiwyOC40MTM5NyAwLDAgOC40ODEyOCwtMC4xMjg5NCA4LjQ4OTc4LC0wLjAwMiAwLjQxNzc2LDYuNDE0OTQgLTEuNzUzMzksOS40NTI4NiAtNC4xMjM0MiwxMi41NjEwNCAtMi40MTc0LDMuMTY5NzggLTUuMTQ0ODYsNi43ODk3MyAtNC4wMDI3OCwxMy4wMDI5IDEuNTA3ODYsOC4yMDMxOCAxMC4xODM1NCwxMC41OTY0MiAxNC42MjE5NCw5LjMxMTU0IC0zLjMxODQyLC0wLjQ5OTExIC01LjMxODU1LC0xLjc0OTQ4IC01LjMxODU1LC0xLjc0OTQ4IDAsMCAxLjg3NjQ2LDAuOTk4NjggNS42NTExNywtMS4zNTk4MSAtMy4yNzY5NSwwLjk1NTcxIC0xMC43MDUyOSwtMC43OTczOCAtMTEuODAxMjUsLTYuNzYzMTMgLTAuOTU3NTIsLTUuMjA4NjEgMC45NDY1NCwtNy4yOTUxNCAzLjQwMTEzLC0xMC41MTQ4MiAyLjQ1NDYyLC0zLjIxOTY4IDUuMjg0MjYsLTYuOTU4MzEgNC42ODQzLC0xNC40ODgyNCBsIDAuMDAzLDAuMDAyIDguOTI2NzYsMCAwLC01NS45OTk2NyBjIC0xNS4wNzEyNSwtMy44NzE2OCAtMjcuNjUzMTQsLTYuMzYwNDIgLTM3Ljc0NjcxLC03LjQ2NTg2IC05Ljk1NTMxLC0xLjEwNzU1IC0yMC4xODgyMywtMS42NTk4MSAtMzAuNjk2NjEzLC0xLjY1OTgxIHogbSA3MC4zMjE2MDMsMTcuMzA4OTMgMC4yMzgwNSw0MC4zMDQ5IGMgMS4zMTgwOCwxLjIyNjY2IDIuNDM5NjUsMi4yNzgxNSAzLjM0MDgxLDMuMTA2MDIgNC44MzkzOSw2Ljc3NDkxIDguODQ5MzQsMTYuMjQ1NjYgMTIuMDI5NTEsMjguNDEzOTcgbCAyMC41MzIzNCwwIDAsLTU1Ljk5OTY3IGMgLTYuNjc3MzEsLTQuNTkzODEgLTE5LjgzNjQzLC0xMC40NzMwOSAtMzYuMTQwNzEsLTE1LjgyNTIyIHogbSAtMjguMTIwNDksNS42MDU1MSA4LjU2NDc5LDE3LjcxNjU1IGMgLTExLjk3MDM3LC02LjQ2Njk3IC0xMy44NDY3OCwtOS43MTcyNiAtOC41NjQ3OSwtMTcuNzE2NTUgeiBtIDIyLjc5NzA1LDAgYyAyLjc3MTUsNy45OTkyOSAxLjc4NzQxLDExLjI0OTU4IC00LjQ5MzU0LDE3LjcxNjU1IGwgNC40OTM1NCwtMTcuNzE2NTUgeiBtIDE1LjIyMTk1LDI0LjAwODQ4IDguNTY0NzksMTcuNzE2NTUgYyAtMTEuOTcwMzgsLTYuNDY2OTcgLTEzLjg0Njc5LC05LjcxNzI2IC04LjU2NDc5LC0xNy43MTY1NSB6IG0gMjIuNzk3MDQsMCBjIDIuNzcxNSw3Ljk5OTI5IDEuNzg3NDEsMTEuMjQ5NTggLTQuNDkzNTQsMTcuNzE2NTUgbCA0LjQ5MzU0LC0xNy43MTY1NSB6IG0gLTk5LjExMzg0LDIuMjA3NjQgOC41NjQ3OSwxNy43MTY1NSBjIC0xMS45NzAzODIsLTYuNDY2OTcgLTEzLjg0Njc4MiwtOS43MTcyNiAtOC41NjQ3OSwtMTcuNzE2NTUgeiBtIDIyLjc5NTQyLDAgYyAyLjc3MTUsNy45OTkyOSAxLjc4NzQxLDExLjI0OTU4IC00LjQ5MzU0LDE3LjcxNjU1IGwgNC40OTM1NCwtMTcuNzE2NTUgeiIgLz4KPC9zdmc+CjwhLS0gVGhpcyB3b3JrIGlzIGxpY2Vuc2VkIHVuZGVyIGEgQ3JlYXRpdmUgQ29tbW9ucyBBdHRyaWJ1dGlvbi1TaGFyZUFsaWtlIDQuMCBJbnRlcm5hdGlvbmFsIExpY2Vuc2UuIC0tPgo8IS0tIGh0dHA6Ly9jcmVhdGl2ZWNvbW1vbnMub3JnL2xpY2Vuc2VzL2J5LXNhLzQuMC8gLS0+Cg==") no-repeat fixed center/70% 70%,linear-gradient(180deg,#750000 0,#340404);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff750000',endColorstr='#ff340404',GradientType=0)}body.syndicate .normal{color:#40628a}body.syndicate .good{color:#73e573}body.syndicate .average{color:#be6209}body.syndicate .bad{color:#b00e0e}body.syndicate .highlight{color:#000}body.syndicate main{display:block;margin-top:32px;padding:2px 6px 0}body.syndicate hr{height:2px;background-color:#272727;border:none}body.syndicate .hidden{display:none}body.syndicate .bar .barText,body.syndicate span.button{color:#fff;font-size:12px;font-weight:400;font-style:normal;text-decoration:none}body.syndicate .bold{font-weight:700}body.syndicate .italic{font-style:italic}body.syndicate [unselectable=on]{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}body.syndicate div[data-tooltip],body.syndicate span[data-tooltip]{position:relative}body.syndicate div[data-tooltip]:after,body.syndicate span[data-tooltip]:after{position:absolute;display:block;z-index:2;width:250px;padding:10px;-webkit-transform:translateX(-50%);-ms-transform:translateX(-50%);transform:translateX(-50%);visibility:hidden;opacity:0;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";white-space:normal;text-align:left;content:attr(data-tooltip);transition:all .5s;border:1px solid #272727;background-color:#363636}body.syndicate div[data-tooltip]:hover:after,body.syndicate span[data-tooltip]:hover:after{visibility:visible;opacity:1;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"}body.syndicate div[data-tooltip].tooltip-top:after,body.syndicate span[data-tooltip].tooltip-top:after{bottom:100%;left:50%;-webkit-transform:translateX(-50%) translateY(8px);-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.syndicate div[data-tooltip].tooltip-bottom:after,body.syndicate div[data-tooltip].tooltip-top:hover:after,body.syndicate span[data-tooltip].tooltip-bottom:after,body.syndicate span[data-tooltip].tooltip-top:hover:after{-webkit-transform:translateX(-50%) translateY(-8px);-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.syndicate div[data-tooltip].tooltip-bottom:after,body.syndicate span[data-tooltip].tooltip-bottom:after{top:100%;left:50%}body.syndicate div[data-tooltip].tooltip-bottom:hover:after,body.syndicate span[data-tooltip].tooltip-bottom:hover:after{-webkit-transform:translateX(-50%) translateY(8px);-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.syndicate div[data-tooltip].tooltip-left:after,body.syndicate span[data-tooltip].tooltip-left:after{top:50%;right:100%;-webkit-transform:translateX(8px) translateY(-50%);-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.syndicate div[data-tooltip].tooltip-left:hover:after,body.syndicate div[data-tooltip].tooltip-right:after,body.syndicate span[data-tooltip].tooltip-left:hover:after,body.syndicate span[data-tooltip].tooltip-right:after{-webkit-transform:translateX(-8px) translateY(-50%);-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.syndicate div[data-tooltip].tooltip-right:after,body.syndicate span[data-tooltip].tooltip-right:after{top:50%;left:100%}body.syndicate div[data-tooltip].tooltip-right:hover:after,body.syndicate span[data-tooltip].tooltip-right:hover:after{-webkit-transform:translateX(8px) translateY(-50%);-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.syndicate .bar{display:inline-block;position:relative;vertical-align:middle;width:100%;height:20px;line-height:17px;padding:1px;border:1px solid #000;background:#272727}body.syndicate .bar .barText{position:absolute;top:0;right:3px}body.syndicate .bar .barFill{display:block;height:100%;transition:background-color 1s;background-color:#000}body.syndicate .bar .barFill.good{background-color:#73e573}body.syndicate .bar .barFill.average{background-color:#be6209}body.syndicate .bar .barFill.bad{background-color:#b00e0e}body.syndicate span.button{display:inline-block;vertical-align:middle;height:20px;line-height:17px;padding:0 5px;white-space:nowrap;border:1px solid #272727}body.syndicate span.button .fa{padding-right:2px}body.syndicate span.button.normal{transition:background-color .5s;background-color:#397439}body.syndicate span.button.normal.active:focus,body.syndicate span.button.normal.active:hover{transition:background-color .25s;background-color:#4a964a;outline:0}body.syndicate span.button.disabled{transition:background-color .5s;background-color:#363636}body.syndicate span.button.disabled.active:focus,body.syndicate span.button.disabled.active:hover{transition:background-color .25s;background-color:#545454;outline:0}body.syndicate span.button.selected{transition:background-color .5s;background-color:#9d0808}body.syndicate span.button.selected.active:focus,body.syndicate span.button.selected.active:hover{transition:background-color .25s;background-color:#ce0b0b;outline:0}body.syndicate span.button.caution{transition:background-color .5s;background-color:#be6209}body.syndicate span.button.caution.active:focus,body.syndicate span.button.caution.active:hover{transition:background-color .25s;background-color:#eb790b;outline:0}body.syndicate span.button.danger{transition:background-color .5s;background-color:#9a9d00}body.syndicate span.button.danger.active:focus,body.syndicate span.button.danger.active:hover{transition:background-color .25s;background-color:#ced200;outline:0}body.syndicate span.button.gridable{width:125px;margin:2px 0}body.syndicate span.button+span:not(.button),body.syndicate span:not(.button)+span.button{margin-left:5px}body.syndicate div.display{width:100%;padding:4px;margin:6px 0;background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#80000000,endColorStr=#80000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#80000000,endColorStr=#80000000);background-color:rgba(0,0,0,.5);box-shadow:inset 0 0 5px rgba(0,0,0,.75)}body.syndicate div.display header,body.syndicate div.subdisplay header{display:block;position:relative;width:100%;padding:0 4px;margin-bottom:6px;color:#fff;border-bottom:2px solid #272727}body.syndicate div.display header .buttonRight,body.syndicate div.subdisplay header .buttonRight{position:absolute;bottom:6px;right:4px}body.syndicate div.display article,body.syndicate div.subdisplay article{display:table;width:100%;border-collapse:collapse}body.syndicate input{display:inline-block;vertical-align:middle;height:20px;line-height:17px;padding:0 5px;white-space:nowrap;color:#fff;background-color:#9d0808;border:1px solid #272727}body.syndicate input::-webkit-input-placeholder{color:#999}body.syndicate input::-moz-placeholder{color:#999}body.syndicate input:-ms-input-placeholder{color:#999}body.syndicate input::placeholder{color:#999}body.syndicate input::-ms-clear{display:none}body.syndicate svg.linegraph{overflow:hidden}body.syndicate div.notice{margin:8px 0;padding:4px;box-shadow:none;color:#000;font-weight:700;font-style:italic;background-color:#750000;background-image:repeating-linear-gradient(-45deg,#750000,#750000 10px,#910101 0,#910101 20px)}body.syndicate div.notice .label{color:#000}body.syndicate div.notice .content:only-of-type{padding:0}body.syndicate div.notice hr{background-color:#272727}body.syndicate div.resize{position:fixed;bottom:0;right:0;width:0;height:0;border-style:solid;border-width:0 0 45px 45px;border-color:transparent transparent #363636;-webkit-transform:rotate(1turn);-ms-transform:rotate(1turn);transform:rotate(1turn)}body.syndicate section .content,body.syndicate section .label,body.syndicate section .line{display:table-cell;margin:0;text-align:left;vertical-align:middle;padding:3px 2px}body.syndicate section{display:table-row;width:100%}body.syndicate section:not(:first-child){padding-top:4px}body.syndicate section.candystripe:nth-child(even){background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000);background-color:rgba(0,0,0,.2)}body.syndicate section .label{width:1%;padding-right:32px;white-space:nowrap;color:#fff}body.syndicate section .content:not(:last-child){padding-right:16px}body.syndicate section .line{width:100%}body.syndicate div.subdisplay{width:100%;margin:0}body.syndicate header.titlebar .close,body.syndicate header.titlebar .minimize{display:inline-block;position:relative;padding:7px;margin:-7px;color:#e74242}body.syndicate header.titlebar .close:hover,body.syndicate header.titlebar .minimize:hover{color:#eb5e5e}body.syndicate header.titlebar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px;background-color:#363636;border-bottom:1px solid #161616;box-shadow:0 3px 3px rgba(0,0,0,.1)}body.syndicate header.titlebar .statusicon{position:absolute;top:4px;left:12px;transition:color .5s}body.syndicate header.titlebar .title{position:absolute;top:6px;left:46px;color:#e74242;font-size:16px;white-space:nowrap}body.syndicate header.titlebar .minimize{position:absolute;top:6px;right:46px}body.syndicate header.titlebar .close{position:absolute;top:4px;right:12px}.no-icons header.titlebar .statusicon{font-size:20px}.no-icons header.titlebar .statusicon:after{content:"O"}.no-icons header.titlebar .minimize{top:-2px;font-size:20px}.no-icons header.titlebar .minimize:after{content:"—"}.no-icons header.titlebar .close{font-size:20px}.no-icons header.titlebar .close:after{content:"X"} \ No newline at end of file diff --git a/tgui/assets/tgui.js b/tgui/assets/tgui.js index 8df27dd35fd..82d72a7d5b7 100644 --- a/tgui/assets/tgui.js +++ b/tgui/assets/tgui.js @@ -1,12 +1,12 @@ -require=function t(e,n,r){function i(o,s){if(!n[o]){if(!e[o]){var u="function"==typeof require&&require;if(!s&&u)return u(o,!0);if(a)return a(o,!0);var c=Error("Cannot find module '"+o+"'");throw c.code="MODULE_NOT_FOUND",c}var l=n[o]={exports:{}};e[o][0].call(l.exports,function(t){var n=e[o][1][t];return i(n?n:t)},l,l.exports,t,e,n,r)}return n[o].exports}for(var a="function"==typeof require&&require,o=0;o=0;--r){var i=this.tryEntries[r],a=i.completion;if("root"===i.tryLoc)return e("end");if(i.tryLoc<=this.prev){var o=y.call(i,"catchLoc"),s=y.call(i,"finallyLoc");if(o&&s){if(this.prev=0;--n){var r=this.tryEntries[n];if(r.tryLoc<=this.prev&&y.call(r,"finallyLoc")&&this.prev=0;--e){var n=this.tryEntries[e];if(n.finallyLoc===t)return this.complete(n.completion,n.afterLoc),d(n),O}},"catch":function(t){for(var e=this.tryEntries.length-1;e>=0;--e){var n=this.tryEntries[e];if(n.tryLoc===t){var r=n.completion;if("throw"===r.type){var i=r.arg;d(n)}return i}}throw Error("illegal catch attempt")},delegateYield:function(t,e,n){return this.delegate={iterator:m(t),resultName:e,nextLoc:n},O}}}("object"==typeof n?n:"object"==typeof window?window:"object"==typeof self?self:this)}).call(this,t(200),void 0!==n?n:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{200:200}],3:[function(t,e,n){e.exports=function(t){if("function"!=typeof t)throw TypeError(t+" is not a function!");return t}},{}],4:[function(t,e,n){var r=t(84)("unscopables"),i=Array.prototype;void 0==i[r]&&t(32)(i,r,{}),e.exports=function(t){i[r][t]=!0}},{32:32,84:84}],5:[function(t,e,n){var r=t(39);e.exports=function(t){if(!r(t))throw TypeError(t+" is not an object!");return t}},{39:39}],6:[function(t,e,n){"use strict";var r=t(81),i=t(77),a=t(80);e.exports=[].copyWithin||function(t,e){var n=r(this),o=a(n.length),s=i(t,o),u=i(e,o),c=arguments,l=c.length>2?c[2]:void 0,p=Math.min((void 0===l?o:i(l,o))-u,o-s),f=1;for(s>u&&u+p>s&&(f=-1,u+=p-1,s+=p-1);p-- >0;)u in n?n[s]=n[u]:delete n[s],s+=f,u+=f;return n}},{77:77,80:80,81:81}],7:[function(t,e,n){"use strict";var r=t(81),i=t(77),a=t(80);e.exports=[].fill||function(t){for(var e=r(this),n=a(e.length),o=arguments,s=o.length,u=i(s>1?o[1]:void 0,n),c=s>2?o[2]:void 0,l=void 0===c?n:i(c,n);l>u;)e[u++]=t;return e}},{77:77,80:80,81:81}],8:[function(t,e,n){var r=t(79),i=t(80),a=t(77);e.exports=function(t){return function(e,n,o){var s,u=r(e),c=i(u.length),l=a(o,c);if(t&&n!=n){for(;c>l;)if(s=u[l++],s!=s)return!0}else for(;c>l;l++)if((t||l in u)&&u[l]===n)return t||l;return!t&&-1}}},{77:77,79:79,80:80}],9:[function(t,e,n){var r=t(18),i=t(35),a=t(81),o=t(80),s=t(10);e.exports=function(t){var e=1==t,n=2==t,u=3==t,c=4==t,l=6==t,p=5==t||l;return function(f,d,h){for(var m,v,g=a(f),y=i(g),b=r(d,h,3),x=o(y.length),w=0,_=e?s(f,x):n?s(f,0):void 0;x>w;w++)if((p||w in y)&&(m=y[w],v=b(m,w,g),t))if(e)_[w]=v;else if(v)switch(t){case 3:return!0;case 5:return m;case 6:return w;case 2:_.push(m)}else if(c)return!1;return l?-1:u||c?c:_}}},{10:10,18:18,35:35,80:80,81:81}],10:[function(t,e,n){var r=t(39),i=t(37),a=t(84)("species");e.exports=function(t,e){var n;return i(t)&&(n=t.constructor,"function"!=typeof n||n!==Array&&!i(n.prototype)||(n=void 0),r(n)&&(n=n[a],null===n&&(n=void 0))),new(void 0===n?Array:n)(e)}},{37:37,39:39,84:84}],11:[function(t,e,n){var r=t(12),i=t(84)("toStringTag"),a="Arguments"==r(function(){return arguments}());e.exports=function(t){var e,n,o;return void 0===t?"Undefined":null===t?"Null":"string"==typeof(n=(e=Object(t))[i])?n:a?r(e):"Object"==(o=r(e))&&"function"==typeof e.callee?"Arguments":o}},{12:12,84:84}],12:[function(t,e,n){var r={}.toString;e.exports=function(t){return r.call(t).slice(8,-1)}},{}],13:[function(t,e,n){"use strict";var r=t(47),i=t(32),a=t(61),o=t(18),s=t(70),u=t(19),c=t(28),l=t(43),p=t(45),f=t(83)("id"),d=t(31),h=t(39),m=t(66),v=t(20),g=Object.isExtensible||h,y=v?"_s":"size",b=0,x=function(t,e){if(!h(t))return"symbol"==typeof t?t:("string"==typeof t?"S":"P")+t;if(!d(t,f)){if(!g(t))return"F";if(!e)return"E";i(t,f,++b)}return"O"+t[f]},w=function(t,e){var n,r=x(e);if("F"!==r)return t._i[r];for(n=t._f;n;n=n.n)if(n.k==e)return n};e.exports={getConstructor:function(t,e,n,i){var l=t(function(t,a){s(t,l,e),t._i=r.create(null),t._f=void 0,t._l=void 0,t[y]=0,void 0!=a&&c(a,n,t[i],t)});return a(l.prototype,{clear:function(){for(var t=this,e=t._i,n=t._f;n;n=n.n)n.r=!0,n.p&&(n.p=n.p.n=void 0),delete e[n.i];t._f=t._l=void 0,t[y]=0},"delete":function(t){var e=this,n=w(e,t);if(n){var r=n.n,i=n.p;delete e._i[n.i],n.r=!0,i&&(i.n=r),r&&(r.p=i),e._f==n&&(e._f=r),e._l==n&&(e._l=i),e[y]--}return!!n},forEach:function(t){for(var e,n=o(t,arguments.length>1?arguments[1]:void 0,3);e=e?e.n:this._f;)for(n(e.v,e.k,this);e&&e.r;)e=e.p},has:function(t){return!!w(this,t)}}),v&&r.setDesc(l.prototype,"size",{get:function(){return u(this[y])}}),l},def:function(t,e,n){var r,i,a=w(t,e);return a?a.v=n:(t._l=a={i:i=x(e,!0),k:e,v:n,p:r=t._l,n:void 0,r:!1},t._f||(t._f=a),r&&(r.n=a),t[y]++,"F"!==i&&(t._i[i]=a)),t},getEntry:w,setStrong:function(t,e,n){l(t,e,function(t,e){this._t=t,this._k=e,this._l=void 0},function(){for(var t=this,e=t._k,n=t._l;n&&n.r;)n=n.p;return t._t&&(t._l=n=n?n.n:t._t._f)?"keys"==e?p(0,n.k):"values"==e?p(0,n.v):p(0,[n.k,n.v]):(t._t=void 0,p(1))},n?"entries":"values",!n,!0),m(e)}}},{18:18,19:19,20:20,28:28,31:31,32:32,39:39,43:43,45:45,47:47,61:61,66:66,70:70,83:83}],14:[function(t,e,n){var r=t(28),i=t(11);e.exports=function(t){return function(){if(i(this)!=t)throw TypeError(t+"#toJSON isn't generic");var e=[];return r(this,!1,e.push,e),e}}},{11:11,28:28}],15:[function(t,e,n){"use strict";var r=t(32),i=t(61),a=t(5),o=t(39),s=t(70),u=t(28),c=t(9),l=t(31),p=t(83)("weak"),f=Object.isExtensible||o,d=c(5),h=c(6),m=0,v=function(t){return t._l||(t._l=new g)},g=function(){this.a=[]},y=function(t,e){return d(t.a,function(t){return t[0]===e})};g.prototype={get:function(t){var e=y(this,t);return e?e[1]:void 0},has:function(t){return!!y(this,t)},set:function(t,e){var n=y(this,t);n?n[1]=e:this.a.push([t,e])},"delete":function(t){var e=h(this.a,function(e){return e[0]===t});return~e&&this.a.splice(e,1),!!~e}},e.exports={getConstructor:function(t,e,n,r){var a=t(function(t,i){s(t,a,e),t._i=m++,t._l=void 0,void 0!=i&&u(i,n,t[r],t)});return i(a.prototype,{"delete":function(t){return o(t)?f(t)?l(t,p)&&l(t[p],this._i)&&delete t[p][this._i]:v(this)["delete"](t):!1},has:function(t){return o(t)?f(t)?l(t,p)&&l(t[p],this._i):v(this).has(t):!1}}),a},def:function(t,e,n){return f(a(e))?(l(e,p)||r(e,p,{}),e[p][t._i]=n):v(t).set(e,n),t},frozenStore:v,WEAK:p}},{28:28,31:31,32:32,39:39,5:5,61:61,70:70,83:83,9:9}],16:[function(t,e,n){"use strict";var r=t(30),i=t(23),a=t(62),o=t(61),s=t(28),u=t(70),c=t(39),l=t(25),p=t(44),f=t(67);e.exports=function(t,e,n,d,h,m){var v=r[t],g=v,y=h?"set":"add",b=g&&g.prototype,x={},w=function(t){var e=b[t];a(b,t,"delete"==t?function(t){return m&&!c(t)?!1:e.call(this,0===t?0:t)}:"has"==t?function(t){return m&&!c(t)?!1:e.call(this,0===t?0:t)}:"get"==t?function(t){return m&&!c(t)?void 0:e.call(this,0===t?0:t)}:"add"==t?function(t){return e.call(this,0===t?0:t),this}:function(t,n){return e.call(this,0===t?0:t,n),this})};if("function"==typeof g&&(m||b.forEach&&!l(function(){(new g).entries().next()}))){var _,k=new g,E=k[y](m?{}:-0,1)!=k,S=l(function(){k.has(1)}),O=p(function(t){new g(t)});O||(g=e(function(e,n){u(e,g,t);var r=new v;return void 0!=n&&s(n,h,r[y],r),r}),g.prototype=b,b.constructor=g),m||k.forEach(function(t,e){_=1/e===-(1/0)}),(S||_)&&(w("delete"),w("has"),h&&w("get")),(_||E)&&w(y),m&&b.clear&&delete b.clear}else g=d.getConstructor(e,t,h,y),o(g.prototype,n);return f(g,t),x[t]=g,i(i.G+i.W+i.F*(g!=v),x),m||d.setStrong(g,t,h),g}},{23:23,25:25,28:28,30:30,39:39,44:44,61:61,62:62,67:67,70:70}],17:[function(t,e,n){var r=e.exports={version:"1.2.6"};"number"==typeof __e&&(__e=r)},{}],18:[function(t,e,n){var r=t(3);e.exports=function(t,e,n){if(r(t),void 0===e)return t;switch(n){case 1:return function(n){return t.call(e,n)};case 2:return function(n,r){return t.call(e,n,r)};case 3:return function(n,r,i){return t.call(e,n,r,i)}}return function(){return t.apply(e,arguments)}}},{3:3}],19:[function(t,e,n){e.exports=function(t){if(void 0==t)throw TypeError("Can't call method on "+t);return t}},{}],20:[function(t,e,n){e.exports=!t(25)(function(){return 7!=Object.defineProperty({},"a",{get:function(){return 7}}).a})},{25:25}],21:[function(t,e,n){var r=t(39),i=t(30).document,a=r(i)&&r(i.createElement);e.exports=function(t){return a?i.createElement(t):{}}},{30:30,39:39}],22:[function(t,e,n){var r=t(47);e.exports=function(t){var e=r.getKeys(t),n=r.getSymbols;if(n)for(var i,a=n(t),o=r.isEnum,s=0;a.length>s;)o.call(t,i=a[s++])&&e.push(i);return e}},{47:47}],23:[function(t,e,n){var r=t(30),i=t(17),a=t(32),o=t(62),s=t(18),u="prototype",c=function(t,e,n){var l,p,f,d,h=t&c.F,m=t&c.G,v=t&c.S,g=t&c.P,y=t&c.B,b=m?r:v?r[e]||(r[e]={}):(r[e]||{})[u],x=m?i:i[e]||(i[e]={}),w=x[u]||(x[u]={});m&&(n=e);for(l in n)p=!h&&b&&l in b,f=(p?b:n)[l],d=y&&p?s(f,r):g&&"function"==typeof f?s(Function.call,f):f,b&&!p&&o(b,l,f),x[l]!=f&&a(x,l,d),g&&w[l]!=f&&(w[l]=f)};r.core=i,c.F=1,c.G=2,c.S=4,c.P=8,c.B=16,c.W=32,e.exports=c},{17:17,18:18,30:30,32:32,62:62}],24:[function(t,e,n){var r=t(84)("match");e.exports=function(t){var e=/./;try{"/./"[t](e)}catch(n){try{return e[r]=!1,!"/./"[t](e)}catch(i){}}return!0}},{84:84}],25:[function(t,e,n){e.exports=function(t){try{return!!t()}catch(e){return!0}}},{}],26:[function(t,e,n){"use strict";var r=t(32),i=t(62),a=t(25),o=t(19),s=t(84);e.exports=function(t,e,n){var u=s(t),c=""[t];a(function(){var e={};return e[u]=function(){return 7},7!=""[t](e)})&&(i(String.prototype,t,n(o,u,c)),r(RegExp.prototype,u,2==e?function(t,e){return c.call(t,this,e)}:function(t){return c.call(t,this)}))}},{19:19,25:25,32:32,62:62,84:84}],27:[function(t,e,n){"use strict";var r=t(5);e.exports=function(){var t=r(this),e="";return t.global&&(e+="g"),t.ignoreCase&&(e+="i"),t.multiline&&(e+="m"),t.unicode&&(e+="u"),t.sticky&&(e+="y"),e}},{5:5}],28:[function(t,e,n){var r=t(18),i=t(41),a=t(36),o=t(5),s=t(80),u=t(85);e.exports=function(t,e,n,c){var l,p,f,d=u(t),h=r(n,c,e?2:1),m=0;if("function"!=typeof d)throw TypeError(t+" is not iterable!");if(a(d))for(l=s(t.length);l>m;m++)e?h(o(p=t[m])[0],p[1]):h(t[m]);else for(f=d.call(t);!(p=f.next()).done;)i(f,h,p.value,e)}},{18:18,36:36,41:41,5:5,80:80,85:85}],29:[function(t,e,n){var r=t(79),i=t(47).getNames,a={}.toString,o="object"==typeof window&&Object.getOwnPropertyNames?Object.getOwnPropertyNames(window):[],s=function(t){try{return i(t)}catch(e){return o.slice()}};e.exports.get=function(t){return o&&"[object Window]"==a.call(t)?s(t):i(r(t))}},{47:47,79:79}],30:[function(t,e,n){var r=e.exports="undefined"!=typeof window&&window.Math==Math?window:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")();"number"==typeof __g&&(__g=r)},{}],31:[function(t,e,n){var r={}.hasOwnProperty;e.exports=function(t,e){return r.call(t,e)}},{}],32:[function(t,e,n){var r=t(47),i=t(60);e.exports=t(20)?function(t,e,n){return r.setDesc(t,e,i(1,n))}:function(t,e,n){return t[e]=n,t}},{20:20,47:47,60:60}],33:[function(t,e,n){e.exports=t(30).document&&document.documentElement},{30:30}],34:[function(t,e,n){e.exports=function(t,e,n){var r=void 0===n;switch(e.length){case 0:return r?t():t.call(n);case 1:return r?t(e[0]):t.call(n,e[0]);case 2:return r?t(e[0],e[1]):t.call(n,e[0],e[1]);case 3:return r?t(e[0],e[1],e[2]):t.call(n,e[0],e[1],e[2]);case 4:return r?t(e[0],e[1],e[2],e[3]):t.call(n,e[0],e[1],e[2],e[3])}return t.apply(n,e)}},{}],35:[function(t,e,n){var r=t(12);e.exports=Object("z").propertyIsEnumerable(0)?Object:function(t){return"String"==r(t)?t.split(""):Object(t)}},{12:12}],36:[function(t,e,n){var r=t(46),i=t(84)("iterator"),a=Array.prototype;e.exports=function(t){return void 0!==t&&(r.Array===t||a[i]===t)}},{46:46,84:84}],37:[function(t,e,n){var r=t(12);e.exports=Array.isArray||function(t){return"Array"==r(t)}},{12:12}],38:[function(t,e,n){var r=t(39),i=Math.floor;e.exports=function(t){return!r(t)&&isFinite(t)&&i(t)===t}},{39:39}],39:[function(t,e,n){e.exports=function(t){return"object"==typeof t?null!==t:"function"==typeof t}},{}],40:[function(t,e,n){var r=t(39),i=t(12),a=t(84)("match");e.exports=function(t){var e;return r(t)&&(void 0!==(e=t[a])?!!e:"RegExp"==i(t))}},{12:12,39:39,84:84}],41:[function(t,e,n){var r=t(5);e.exports=function(t,e,n,i){try{return i?e(r(n)[0],n[1]):e(n)}catch(a){var o=t["return"];throw void 0!==o&&r(o.call(t)),a}}},{5:5}],42:[function(t,e,n){"use strict";var r=t(47),i=t(60),a=t(67),o={};t(32)(o,t(84)("iterator"),function(){return this}),e.exports=function(t,e,n){t.prototype=r.create(o,{next:i(1,n)}),a(t,e+" Iterator")}},{32:32,47:47,60:60,67:67,84:84}],43:[function(t,e,n){"use strict";var r=t(49),i=t(23),a=t(62),o=t(32),s=t(31),u=t(46),c=t(42),l=t(67),p=t(47).getProto,f=t(84)("iterator"),d=!([].keys&&"next"in[].keys()),h="@@iterator",m="keys",v="values",g=function(){return this};e.exports=function(t,e,n,y,b,x,w){c(n,e,y);var _,k,E=function(t){if(!d&&t in P)return P[t];switch(t){case m:return function(){return new n(this,t)};case v:return function(){return new n(this,t)}}return function(){return new n(this,t)}},S=e+" Iterator",O=b==v,A=!1,P=t.prototype,C=P[f]||P[h]||b&&P[b],j=C||E(b);if(C){var T=p(j.call(new t));l(T,S,!0),!r&&s(P,h)&&o(T,f,g),O&&C.name!==v&&(A=!0,j=function(){return C.call(this)})}if(r&&!w||!d&&!A&&P[f]||o(P,f,j),u[e]=j,u[S]=g,b)if(_={values:O?j:E(v),keys:x?j:E(m),entries:O?E("entries"):j},w)for(k in _)k in P||a(P,k,_[k]);else i(i.P+i.F*(d||A),e,_);return _}},{23:23,31:31,32:32,42:42,46:46,47:47,49:49,62:62,67:67,84:84}],44:[function(t,e,n){var r=t(84)("iterator"),i=!1;try{var a=[7][r]();a["return"]=function(){i=!0},Array.from(a,function(){throw 2})}catch(o){}e.exports=function(t,e){if(!e&&!i)return!1;var n=!1;try{var a=[7],o=a[r]();o.next=function(){n=!0},a[r]=function(){return o},t(a)}catch(s){}return n}},{84:84}],45:[function(t,e,n){e.exports=function(t,e){return{value:e,done:!!t}}},{}],46:[function(t,e,n){e.exports={}},{}],47:[function(t,e,n){var r=Object;e.exports={create:r.create,getProto:r.getPrototypeOf,isEnum:{}.propertyIsEnumerable,getDesc:r.getOwnPropertyDescriptor,setDesc:r.defineProperty,setDescs:r.defineProperties,getKeys:r.keys,getNames:r.getOwnPropertyNames,getSymbols:r.getOwnPropertySymbols,each:[].forEach}},{}],48:[function(t,e,n){var r=t(47),i=t(79);e.exports=function(t,e){for(var n,a=i(t),o=r.getKeys(a),s=o.length,u=0;s>u;)if(a[n=o[u++]]===e)return n}},{47:47,79:79}],49:[function(t,e,n){e.exports=!1},{}],50:[function(t,e,n){e.exports=Math.expm1||function(t){return 0==(t=+t)?t:t>-1e-6&&1e-6>t?t+t*t/2:Math.exp(t)-1}},{}],51:[function(t,e,n){e.exports=Math.log1p||function(t){return(t=+t)>-1e-8&&1e-8>t?t-t*t/2:Math.log(1+t)}},{}],52:[function(t,e,n){e.exports=Math.sign||function(t){return 0==(t=+t)||t!=t?t:0>t?-1:1}},{}],53:[function(t,e,n){var r,i,a,o=t(30),s=t(76).set,u=o.MutationObserver||o.WebKitMutationObserver,c=o.process,l=o.Promise,p="process"==t(12)(c),f=function(){var t,e,n;for(p&&(t=c.domain)&&(c.domain=null,t.exit());r;)e=r.domain,n=r.fn,e&&e.enter(),n(),e&&e.exit(),r=r.next;i=void 0,t&&t.enter()};if(p)a=function(){c.nextTick(f)};else if(u){var d=1,h=document.createTextNode("");new u(f).observe(h,{characterData:!0}),a=function(){h.data=d=-d}}else a=l&&l.resolve?function(){l.resolve().then(f)}:function(){s.call(o,f)};e.exports=function(t){var e={fn:t,next:void 0,domain:p&&c.domain};i&&(i.next=e),r||(r=e,a()),i=e}},{12:12,30:30,76:76}],54:[function(t,e,n){var r=t(47),i=t(81),a=t(35);e.exports=t(25)(function(){var t=Object.assign,e={},n={},r=Symbol(),i="abcdefghijklmnopqrst";return e[r]=7,i.split("").forEach(function(t){n[t]=t}),7!=t({},e)[r]||Object.keys(t({},n)).join("")!=i})?function(t,e){for(var n=i(t),o=arguments,s=o.length,u=1,c=r.getKeys,l=r.getSymbols,p=r.isEnum;s>u;)for(var f,d=a(o[u++]),h=l?c(d).concat(l(d)):c(d),m=h.length,v=0;m>v;)p.call(d,f=h[v++])&&(n[f]=d[f]);return n}:Object.assign},{25:25,35:35,47:47,81:81}],55:[function(t,e,n){var r=t(23),i=t(17),a=t(25);e.exports=function(t,e){var n=(i.Object||{})[t]||Object[t],o={};o[t]=e(n),r(r.S+r.F*a(function(){n(1)}),"Object",o)}},{17:17,23:23,25:25}],56:[function(t,e,n){var r=t(47),i=t(79),a=r.isEnum;e.exports=function(t){return function(e){for(var n,o=i(e),s=r.getKeys(o),u=s.length,c=0,l=[];u>c;)a.call(o,n=s[c++])&&l.push(t?[n,o[n]]:o[n]);return l}}},{47:47,79:79}],57:[function(t,e,n){var r=t(47),i=t(5),a=t(30).Reflect;e.exports=a&&a.ownKeys||function(t){var e=r.getNames(i(t)),n=r.getSymbols;return n?e.concat(n(t)):e}},{30:30,47:47,5:5}],58:[function(t,e,n){"use strict";var r=t(59),i=t(34),a=t(3);e.exports=function(){for(var t=a(this),e=arguments.length,n=Array(e),o=0,s=r._,u=!1;e>o;)(n[o]=arguments[o++])===s&&(u=!0);return function(){var r,a=this,o=arguments,c=o.length,l=0,p=0;if(!u&&!c)return i(t,n,a);if(r=n.slice(),u)for(;e>l;l++)r[l]===s&&(r[l]=o[p++]);for(;c>p;)r.push(o[p++]);return i(t,r,a)}}},{3:3,34:34,59:59}],59:[function(t,e,n){e.exports=t(30)},{30:30}],60:[function(t,e,n){e.exports=function(t,e){return{enumerable:!(1&t),configurable:!(2&t),writable:!(4&t),value:e}}},{}],61:[function(t,e,n){var r=t(62);e.exports=function(t,e){for(var n in e)r(t,n,e[n]);return t}},{62:62}],62:[function(t,e,n){var r=t(30),i=t(32),a=t(83)("src"),o="toString",s=Function[o],u=(""+s).split(o);t(17).inspectSource=function(t){return s.call(t)},(e.exports=function(t,e,n,o){"function"==typeof n&&(n.hasOwnProperty(a)||i(n,a,t[e]?""+t[e]:u.join(e+"")),n.hasOwnProperty("name")||i(n,"name",e)),t===r?t[e]=n:(o||delete t[e],i(t,e,n))})(Function.prototype,o,function(){return"function"==typeof this&&this[a]||s.call(this)})},{17:17,30:30,32:32,83:83}],63:[function(t,e,n){e.exports=function(t,e){var n=e===Object(e)?function(t){return e[t]}:e;return function(e){return(e+"").replace(t,n)}}},{}],64:[function(t,e,n){e.exports=Object.is||function(t,e){return t===e?0!==t||1/t===1/e:t!=t&&e!=e}},{}],65:[function(t,e,n){var r=t(47).getDesc,i=t(39),a=t(5),o=function(t,e){if(a(t),!i(e)&&null!==e)throw TypeError(e+": can't set as prototype!")};e.exports={set:Object.setPrototypeOf||("__proto__"in{}?function(e,n,i){try{i=t(18)(Function.call,r(Object.prototype,"__proto__").set,2),i(e,[]),n=!(e instanceof Array)}catch(a){n=!0}return function(t,e){return o(t,e),n?t.__proto__=e:i(t,e),t}}({},!1):void 0),check:o}},{18:18,39:39,47:47,5:5}],66:[function(t,e,n){"use strict";var r=t(30),i=t(47),a=t(20),o=t(84)("species");e.exports=function(t){var e=r[t];a&&e&&!e[o]&&i.setDesc(e,o,{configurable:!0,get:function(){return this}})}},{20:20,30:30,47:47,84:84}],67:[function(t,e,n){var r=t(47).setDesc,i=t(31),a=t(84)("toStringTag");e.exports=function(t,e,n){t&&!i(t=n?t:t.prototype,a)&&r(t,a,{configurable:!0,value:e})}},{31:31,47:47,84:84}],68:[function(t,e,n){var r=t(30),i="__core-js_shared__",a=r[i]||(r[i]={});e.exports=function(t){return a[t]||(a[t]={})}},{30:30}],69:[function(t,e,n){var r=t(5),i=t(3),a=t(84)("species");e.exports=function(t,e){var n,o=r(t).constructor;return void 0===o||void 0==(n=r(o)[a])?e:i(n)}},{3:3,5:5,84:84}],70:[function(t,e,n){e.exports=function(t,e,n){if(!(t instanceof e))throw TypeError(n+": use the 'new' operator!");return t}},{}],71:[function(t,e,n){var r=t(78),i=t(19);e.exports=function(t){return function(e,n){var a,o,s=i(e)+"",u=r(n),c=s.length;return 0>u||u>=c?t?"":void 0:(a=s.charCodeAt(u),55296>a||a>56319||u+1===c||(o=s.charCodeAt(u+1))<56320||o>57343?t?s.charAt(u):a:t?s.slice(u,u+2):(a-55296<<10)+(o-56320)+65536)}}},{19:19,78:78}],72:[function(t,e,n){var r=t(40),i=t(19);e.exports=function(t,e,n){if(r(e))throw TypeError("String#"+n+" doesn't accept regex!");return i(t)+""}},{19:19,40:40}],73:[function(t,e,n){var r=t(80),i=t(74),a=t(19);e.exports=function(t,e,n,o){var s=a(t)+"",u=s.length,c=void 0===n?" ":n+"",l=r(e);if(u>=l)return s;""==c&&(c=" ");var p=l-u,f=i.call(c,Math.ceil(p/c.length));return f.length>p&&(f=f.slice(0,p)),o?f+s:s+f}},{19:19,74:74,80:80}],74:[function(t,e,n){"use strict";var r=t(78),i=t(19);e.exports=function(t){var e=i(this)+"",n="",a=r(t);if(0>a||a==1/0)throw RangeError("Count can't be negative");for(;a>0;(a>>>=1)&&(e+=e))1&a&&(n+=e);return n}},{19:19,78:78}],75:[function(t,e,n){var r=t(23),i=t(19),a=t(25),o=" \n\x0B\f\r   ᠎              \u2028\u2029\ufeff",s="["+o+"]",u="​…",c=RegExp("^"+s+s+"*"),l=RegExp(s+s+"*$"),p=function(t,e){var n={};n[t]=e(f),r(r.P+r.F*a(function(){return!!o[t]()||u[t]()!=u}),"String",n)},f=p.trim=function(t,e){return t=i(t)+"",1&e&&(t=t.replace(c,"")),2&e&&(t=t.replace(l,"")),t};e.exports=p},{19:19,23:23,25:25}],76:[function(t,e,n){var r,i,a,o=t(18),s=t(34),u=t(33),c=t(21),l=t(30),p=l.process,f=l.setImmediate,d=l.clearImmediate,h=l.MessageChannel,m=0,v={},g="onreadystatechange",y=function(){var t=+this;if(v.hasOwnProperty(t)){var e=v[t];delete v[t],e()}},b=function(t){y.call(t.data)};f&&d||(f=function(t){for(var e=[],n=1;arguments.length>n;)e.push(arguments[n++]);return v[++m]=function(){s("function"==typeof t?t:Function(t),e)},r(m),m},d=function(t){delete v[t]},"process"==t(12)(p)?r=function(t){p.nextTick(o(y,t,1))}:h?(i=new h,a=i.port2,i.port1.onmessage=b,r=o(a.postMessage,a,1)):l.addEventListener&&"function"==typeof postMessage&&!l.importScripts?(r=function(t){l.postMessage(t+"","*")},l.addEventListener("message",b,!1)):r=g in c("script")?function(t){u.appendChild(c("script"))[g]=function(){u.removeChild(this),y.call(t)}}:function(t){setTimeout(o(y,t,1),0)}),e.exports={set:f,clear:d}},{12:12,18:18,21:21,30:30,33:33,34:34}],77:[function(t,e,n){var r=t(78),i=Math.max,a=Math.min;e.exports=function(t,e){return t=r(t),0>t?i(t+e,0):a(t,e)}},{78:78}],78:[function(t,e,n){var r=Math.ceil,i=Math.floor;e.exports=function(t){return isNaN(t=+t)?0:(t>0?i:r)(t)}},{}],79:[function(t,e,n){var r=t(35),i=t(19);e.exports=function(t){return r(i(t))}},{19:19,35:35}],80:[function(t,e,n){var r=t(78),i=Math.min;e.exports=function(t){return t>0?i(r(t),9007199254740991):0}},{78:78}],81:[function(t,e,n){var r=t(19);e.exports=function(t){return Object(r(t))}},{19:19}],82:[function(t,e,n){var r=t(39);e.exports=function(t,e){if(!r(t))return t;var n,i;if(e&&"function"==typeof(n=t.toString)&&!r(i=n.call(t)))return i;if("function"==typeof(n=t.valueOf)&&!r(i=n.call(t)))return i;if(!e&&"function"==typeof(n=t.toString)&&!r(i=n.call(t)))return i;throw TypeError("Can't convert object to primitive value")}},{39:39}],83:[function(t,e,n){var r=0,i=Math.random();e.exports=function(t){return"Symbol(".concat(void 0===t?"":t,")_",(++r+i).toString(36))}},{}],84:[function(t,e,n){var r=t(68)("wks"),i=t(83),a=t(30).Symbol;e.exports=function(t){return r[t]||(r[t]=a&&a[t]||(a||i)("Symbol."+t))}},{30:30,68:68,83:83}],85:[function(t,e,n){var r=t(11),i=t(84)("iterator"),a=t(46);e.exports=t(17).getIteratorMethod=function(t){return void 0!=t?t[i]||t["@@iterator"]||a[r(t)]:void 0}},{11:11,17:17,46:46,84:84}],86:[function(t,e,n){"use strict";var r,i=t(47),a=t(23),o=t(20),s=t(60),u=t(33),c=t(21),l=t(31),p=t(12),f=t(34),d=t(25),h=t(5),m=t(3),v=t(39),g=t(81),y=t(79),b=t(78),x=t(77),w=t(80),_=t(35),k=t(83)("__proto__"),E=t(9),S=t(8)(!1),O=Object.prototype,A=Array.prototype,P=A.slice,C=A.join,j=i.setDesc,T=i.getDesc,M=i.setDescs,F={};o||(r=!d(function(){return 7!=j(c("div"),"a",{get:function(){return 7}}).a}),i.setDesc=function(t,e,n){if(r)try{return j(t,e,n)}catch(i){}if("get"in n||"set"in n)throw TypeError("Accessors not supported!");return"value"in n&&(h(t)[e]=n.value),t},i.getDesc=function(t,e){if(r)try{return T(t,e)}catch(n){}return l(t,e)?s(!O.propertyIsEnumerable.call(t,e),t[e]):void 0},i.setDescs=M=function(t,e){h(t);for(var n,r=i.getKeys(e),a=r.length,o=0;a>o;)i.setDesc(t,n=r[o++],e[n]);return t}),a(a.S+a.F*!o,"Object",{getOwnPropertyDescriptor:i.getDesc,defineProperty:i.setDesc,defineProperties:M});var L="constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf".split(","),N=L.concat("length","prototype"),R=L.length,I=function(){var t,e=c("iframe"),n=R,r=">";for(e.style.display="none",u.appendChild(e),e.src="javascript:",t=e.contentWindow.document,t.open(),t.write(" + +
    + {{#each tabs}} + {{.}} + {{/each}} +
    + + {{>content}} + diff --git a/tgui/src/components/tabs/tab.ract b/tgui/src/components/tabs/tab.ract new file mode 100644 index 00000000000..b1cdb5e4baf --- /dev/null +++ b/tgui/src/components/tabs/tab.ract @@ -0,0 +1,3 @@ +{{#if shown}} + {{yield}} +{{/if}} diff --git a/tgui/src/components/titlebar.styl b/tgui/src/components/titlebar.styl index d4661fd8913..628fe75745e 100644 --- a/tgui/src/components/titlebar.styl +++ b/tgui/src/components/titlebar.styl @@ -48,3 +48,18 @@ header.titlebar position: absolute top: 4px right: 12px + +/.no-icons header.titlebar + .statusicon + font-size: 20px + &::after + content: "O" + .minimize + top: -2px + font-size: 20px + &::after + content: "—" + .close + font-size: 20px + &::after + content: "X" diff --git a/tgui/src/components/warnings.ract b/tgui/src/components/warnings.ract index 2e5695e535f..74e4819f4a4 100644 --- a/tgui/src/components/warnings.ract +++ b/tgui/src/components/warnings.ract @@ -1,25 +1,25 @@ diff --git a/tgui/src/interfaces/cargo.ract b/tgui/src/interfaces/cargo.ract index 1db3bbddef0..a56e0ad0ebb 100644 --- a/tgui/src/interfaces/cargo.ract +++ b/tgui/src/interfaces/cargo.ract @@ -1,24 +1,14 @@ - - {{#partial button}} - {{#if config.fancy}} - - {{/if}} - {{/partial}} + {{#if data.docked && !data.requestonly}} {{data.location}} @@ -72,8 +62,8 @@
    #{{id}}
    {{object}}
    {{cost}} Points
    -
    By {{orderedby}}
    -
    Comment: {{comment}}
    +
    By {{orderer}}
    +
    Comment: {{reason}}
    {{#if !data.requestonly}}
    @@ -85,12 +75,14 @@ No Requests {{/each}} -{{#each data.supplies}} - - {{#each packs}} - - {{cost}} Points - - {{/each}} - -{{/each}} + + {{#each data.supplies}} + + {{#each packs}} + + {{cost}} Points + + {{/each}} + + {{/each}} + diff --git a/tgui/src/interfaces/tanks.ract b/tgui/src/interfaces/tanks.ract index 334ebf9a206..e4d08c8441b 100644 --- a/tgui/src/interfaces/tanks.ract +++ b/tgui/src/interfaces/tanks.ract @@ -12,7 +12,7 @@ - The regulator {{data.maskConnected ? "is" : "is not"}} connected to a mask. + The regulator {{data.connected? "is" : "is not"}} connected to a mask. @@ -32,8 +32,4 @@ Max - - {{data.valveOpen ? "Open" : "Closed"}} - diff --git a/tgui/src/tgui.js b/tgui/src/tgui.js index 9b4123cbc5b..60162102b1e 100644 --- a/tgui/src/tgui.js +++ b/tgui/src/tgui.js @@ -7,11 +7,14 @@ import 'babel-polyfill' import 'dom4' import 'html5shiv' +// Extend the Math builtin with our own utilities. Object.assign(Math, require('util/math')) +// Set up the initialize function. This is either called below if JSON is provided +// inline, or called by the server if it was not. import TGUI from 'tgui.ract' window.initialize = (dataString) => { - if (window.tgui) return + if (window.tgui) return // Don't run twice. window.tgui = new TGUI({ el: '#container', data () { @@ -25,25 +28,26 @@ window.initialize = (dataString) => { } } }) - window.initialize = function () {} } +// Try to find data in the page. If the JSON was inlined, load it. const holder = document.getElementById('data') const data = holder.textContent const ref = holder.getAttribute('data-ref') -if (data !== '{}') { // If the JSON was inlined, load it. +if (data !== '{}') { window.initialize(data) holder.remove() } - +// Let the server know we're set up. This also sends data if it was not inlined. import { act } from 'util/byond' act(ref, 'tgui:initialize') -import WebFont from 'webfontloader' -WebFont.load({ - custom: { - families: [ 'FontAwesome' ], - urls: [ 'https://netdna.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css' ], - testStrings: { FontAwesome: '\uf240' } - } -}) +// Load fonts. +import { loadCSS } from 'fg-loadcss' +loadCSS('https://netdna.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css') +// Handle font loads. +import FontFaceObserver from 'fontfaceobserver' +const fontawesome = new FontFaceObserver('FontAwesome') +fontawesome.check('\uf240') + .then(() => document.body.classList.add('icons')) + .catch(() => document.body.classList.add('no-icons')) diff --git a/tgui/src/tgui.ract b/tgui/src/tgui.ract index 8d277168e28..bde840c609b 100644 --- a/tgui/src/tgui.ract +++ b/tgui/src/tgui.ract @@ -16,6 +16,7 @@ component.exports = { 'ui-notice': require('components/notice'), 'ui-section': require('components/section'), 'ui-subdisplay': require('components/subdisplay'), + 'ui-tabs': require('components/tabs'), }, events: { enter: require('ractive-events-keys').enter, diff --git a/tgui/src/tgui.styl b/tgui/src/tgui.styl index 822d4d21c18..3fc64c9045f 100644 --- a/tgui/src/tgui.styl +++ b/tgui/src/tgui.styl @@ -131,11 +131,4 @@ h4 @extend $h font-size: 12px -.wf-inactive - .titlebar - .minimize::after - content: "-" - .close::after - content: "X" - @require "styles/*"